Skills postsyncer-social-media-assistant
Manages social media through PostSyncer using REST and/or MCP. Use when scheduling, posting, or managing content across Instagram, TikTok, YouTube, X (Twitter), LinkedIn, Facebook, Threads, Bluesky, Pinterest, Telegram, Mastodon. Covers posts, media library (list, import URLs, delete, multipart file upload), media folders (CRUD), comments with optional `media` attachments, labels, campaigns, and analytics. Accounts must be pre-connected in the PostSyncer app.
git clone https://github.com/openclaw/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/abdulmejidshemsuawel/postsyncer" ~/.claude/skills/openclaw-skills-postsyncer-social-media-assistant && rm -rf "$T"
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/abdulmejidshemsuawel/postsyncer" ~/.openclaw/skills/openclaw-skills-postsyncer-social-media-assistant && rm -rf "$T"
skills/abdulmejidshemsuawel/postsyncer/SKILL.mdPostSyncer Social Media Assistant
Autonomously manage social media through PostSyncer using the REST API.
Setup
- Create a PostSyncer account at app.postsyncer.com
- Connect social profiles (Instagram, TikTok, YouTube, X, LinkedIn, etc.)
- Go to Settings → API Integrations and create a personal access token with abilities:
,workspaces
,accounts
, and (if you use them)posts
,labelscampaigns - Add to
:.envPOSTSYNCER_API_TOKEN=your_token
PostSyncer MCP (optional)
PostSyncer MCP uses the same Bearer token as REST. Typical tools:
list-workspaces, list-accounts, post CRUD, list-media, get-media, upload-media-from-url, delete-media, list-folders, create-folder, get-folder, update-folder, delete-folder, comments, labels, campaigns, analytics.
Multipart file upload is only via REST:
POST /api/v1/media/upload/file (not exposed as an MCP tool). Use upload-media-from-url or REST URL import when the client cannot send multipart.
How to Make API Calls
All requests go to
https://postsyncer.com/api/v1 with the header:
Authorization: Bearer $POSTSYNCER_API_TOKEN Content-Type: application/json
Use
web_fetch, curl, or any HTTP tool available. Always read $POSTSYNCER_API_TOKEN from the environment.
API Reference
Discovery (Call First)
List Workspaces —
GET /api/v1/workspaces
curl "https://postsyncer.com/api/v1/workspaces" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Returns workspaces with
id, name, slug, timezone.
List Accounts —
GET /api/v1/accounts
curl "https://postsyncer.com/api/v1/accounts" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Returns accounts with
id, platform, username, workspace_id.
Media library
Requires the
posts ability. Responses include id, workspace_id, folder_id, and asset metadata.
List Media —
GET /api/v1/media
curl -G "https://postsyncer.com/api/v1/media" \ --data-urlencode "workspace_id=12" \ --data-urlencode "page=1" \ --data-urlencode "per_page=50" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Query params:
workspace_id, folder_id, root_only (true/false), page, per_page (max 100).
Get Media —
GET /api/v1/media/{media_id}
curl "https://postsyncer.com/api/v1/media/999" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Import from URLs —
POST /api/v1/media/upload/url
curl -X POST "https://postsyncer.com/api/v1/media/upload/url" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"workspace_id": 12, "urls": ["https://example.com/photo.jpg"], "folder_id": null}'
Upload file (multipart) —
POST /api/v1/media/upload/file
Use
multipart/form-data with fields such as workspace_id, file (and optional chunk/chunk metadata if your client uses chunked upload). Not JSON.
Delete Media —
DELETE /api/v1/media/{media_id} (confirm first)
curl -X DELETE "https://postsyncer.com/api/v1/media/999" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Media folders
Requires the
posts ability.
List Folders —
GET /api/v1/folders
curl -G "https://postsyncer.com/api/v1/folders" \ --data-urlencode "workspace_id=12" \ --data-urlencode "root=1" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Query params:
workspace_id, parent_id, root (top-level only).
Create Folder —
POST /api/v1/folders
curl -X POST "https://postsyncer.com/api/v1/folders" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"workspace_id": 12, "name": "Campaign assets", "color": "#3b82f6", "parent_id": null}'
Get Folder —
GET /api/v1/folders/{id}
Update Folder —
PUT /api/v1/folders/{id}
curl -X PUT "https://postsyncer.com/api/v1/folders/5" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Renamed folder"}'
Delete Folder —
DELETE /api/v1/folders/{id} (confirm first)
Posts
List Posts —
GET /api/v1/posts
curl "https://postsyncer.com/api/v1/posts?page=1&per_page=20&include_comments=false" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Query params:
page, per_page (max 100), include_comments (true/false).
Get Post —
GET /api/v1/posts/{id}
curl "https://postsyncer.com/api/v1/posts/123" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Create Post —
POST /api/v1/posts
curl -X POST "https://postsyncer.com/api/v1/posts" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "workspace_id": 12, "schedule_type": "schedule", "content": [{"text": "Caption #hashtags", "media": [42, "https://example.com/image.jpg"]}], "accounts": [{"id": 136}, {"id": 95, "settings": {"board_id": 123}}], "schedule_for": {"date": "2026-03-26", "time": "14:30", "timezone": "America/New_York"}, "labels": [5], "repeatable": false }'
:schedule_type
|publish_now
|scheduledraft
: Optional scheduling object used whenschedule_for
isschedule_type
. Provideschedule
to schedule for a specific date/time, or omit/leave empty to auto-schedule to the next available time slot{"date": "YYYY-MM-DD", "time": "HH:MM", "timezone": "..."}
: Array of thread items. Each needscontent
and/ortext
: an array of library media IDs (integers) and/or HTTPS URL strings (import or list media first when you want stable IDs)media
: Array ofaccounts
. Platform-specific options go in{id, settings?}settings
Update Post —
PUT /api/v1/posts/{id}
curl -X PUT "https://postsyncer.com/api/v1/posts/123" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"content": [{"text": "Updated caption"}], "schedule_for": {"date": "2026-03-27", "time": "10:00"}}'
Only posts that have not been published yet can be updated.
Delete Post —
DELETE /api/v1/posts/{id} (confirm with user first)
curl -X DELETE "https://postsyncer.com/api/v1/posts/123" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Comments
List Comments —
GET /api/v1/comments
curl -G "https://postsyncer.com/api/v1/comments" \ --data-urlencode "post_id=123" \ --data-urlencode "per_page=20" \ --data-urlencode "include_replies=true" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Query params:
post_id (required), per_page, page, include_replies, platform.
Get Comment —
GET /api/v1/comments/{id}
curl "https://postsyncer.com/api/v1/comments/456" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Create Comment / Reply —
POST /api/v1/comments
curl -X POST "https://postsyncer.com/api/v1/comments" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"post_id": 123, "content": "Reply text", "parent_comment_id": null, "media": [42]}'
Optional
media: array of integer library IDs and/or HTTPS URLs (same shape as post content[].media; do not use a deprecated media_urls field).
Update Comment —
PUT /api/v1/comments/{id}
curl -X PUT "https://postsyncer.com/api/v1/comments/456" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"content": "Updated reply text"}'
Hide Comment —
POST /api/v1/comments/{id}/hide
curl -X POST "https://postsyncer.com/api/v1/comments/456/hide" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Delete Comment —
DELETE /api/v1/comments/{id} (confirm first)
curl -X DELETE "https://postsyncer.com/api/v1/comments/456" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Sync Comments from Platforms —
POST /api/v1/comments/sync
curl -X POST "https://postsyncer.com/api/v1/comments/sync" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"post_id": 123}'
Labels
List Labels —
GET /api/v1/labels
curl "https://postsyncer.com/api/v1/labels" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Get Label —
GET /api/v1/labels/{id}
Create Label —
POST /api/v1/labels
curl -X POST "https://postsyncer.com/api/v1/labels" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Campaign 2026", "color": "#3b82f6", "workspace_id": 12}'
Update Label —
PUT /api/v1/labels/{id}
Delete Label —
DELETE /api/v1/labels/{id} (confirm first)
Analytics
All analytics endpoints require the
posts API ability.
All Workspaces —
GET /api/v1/analytics
curl "https://postsyncer.com/api/v1/analytics" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
By Workspace —
GET /api/v1/analytics/workspaces/{workspace_id}
curl "https://postsyncer.com/api/v1/analytics/workspaces/12" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
By Post —
GET /api/v1/analytics/posts/{post_id}
curl "https://postsyncer.com/api/v1/analytics/posts/123" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
By Account —
GET /api/v1/analytics/accounts/{account_id}
curl "https://postsyncer.com/api/v1/analytics/accounts/136" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Sync Post Analytics —
POST /api/v1/analytics/posts/{post_id}/sync
curl -X POST "https://postsyncer.com/api/v1/analytics/posts/123/sync" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Queues background jobs to refresh metrics. Does not return metrics directly — call GET after sync.
Account Management
Delete Account —
DELETE /api/v1/accounts/{id} (destructive, confirm first)
curl -X DELETE "https://postsyncer.com/api/v1/accounts/136" \ -H "Authorization: Bearer $POSTSYNCER_API_TOKEN"
Platform-Specific Settings
Pass per-platform options in
accounts[].settings when creating/updating posts:
Pinterest:
{"board_id": 123456}
X/Twitter:
{"reply_settings": "everyone", "for_super_followers_only": false, "quote_tweet_id": null, "reply": {"in_reply_to_tweet_id": null}, "community_id": null, "share_with_followers": true}
TikTok:
{"privacy_level": "PUBLIC_TO_EVERYONE", "disable_comment": false, "disable_duet": false, "disable_stitch": false, "post_mode": "DIRECT_POST"}
Instagram:
{"post_type": "POST"} — options: REELS, STORIES, POST
YouTube:
{"video_type": "video", "title": "My Video", "privacyStatus": "public", "notifySubscribers": true}
LinkedIn:
{"visibility": "PUBLIC"} — options: PUBLIC, CONNECTIONS, LOGGED_IN
Bluesky:
{"website_card": {"uri": "https://...", "title": "...", "description": "..."}}
Telegram:
{"disable_notification": false, "protect_content": false}
Common Workflows
Schedule a Post to Multiple Platforms
→ getGET /api/v1/workspacesworkspace_id
→ getGET /api/v1/accounts
s for target platformsid- Optionally
(or MCPPOST /api/v1/media/upload/url
) → use returnedupload-media-from-url
s inidcontent[].media
withPOST /api/v1/posts
andschedule_type: "schedule"schedule_for
Reply to Comments
→ find postGET /api/v1/postsid
withPOST /api/v1/comments/syncpost_idGET /api/v1/comments?post_id=123&include_replies=true
withPOST /api/v1/comments
and optionalpost_idparent_comment_id
Check Performance
for a specific postGET /api/v1/analytics/posts/{id}- If stale:
, then re-fetchPOST /api/v1/analytics/posts/{id}/sync
Best Practices
- Always start with
andGET /workspaces
to discover IDs; useGET /accounts
andGET /folders
when organizing or attaching library assetsGET /media - New automations: Use
or confirm beforeschedule_type: "draft"publish_now - Destructive actions: State what will happen, confirm before delete operations
- Multi-network: One post can target multiple accounts; check per-platform
in the responsestatus - Rate limits: 60 requests/minute — don't call sync endpoints repeatedly
- Hashtags: Keep relevant and limited (3–5 per post)
Error Handling
| Status | Meaning |
|---|---|
| Token missing or invalid |
| Token lacks required ability (e.g. ) |
| Resource not found or no access |
| Validation error — check required fields and formats |
| Rate limited — wait before retrying |