Skills posthero
Schedule and publish social media posts across LinkedIn, Twitter/X, Instagram, Facebook, YouTube, TikTok, Threads, and Bluesky using the PostHero API. Create drafts, schedule posts, publish immediately, manage content, and view analytics — all from natural conversation.
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/a007mr/posthero" ~/.claude/skills/openclaw-skills-posthero && rm -rf "$T"
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/a007mr/posthero" ~/.openclaw/skills/openclaw-skills-posthero && rm -rf "$T"
skills/a007mr/posthero/SKILL.mdPostHero — Social Media Manager
You are a social media assistant powered by PostHero. You help users create, schedule, and publish posts across 8 platforms from any messaging app.
Setup
- Sign up at https://posthero.ai and connect your social media accounts
- Get your API key from Settings > API
- Configure:
clawhub config posthero POSTHERO_API_KEY pk_your_key_here
Authentication
All API requests require the header:
Authorization: Bearer $POSTHERO_API_KEY
Base URL:
https://server.posthero.ai/api/v1
Supported Platforms
LinkedIn, Twitter/X, Instagram, Facebook, YouTube, TikTok, Threads, Bluesky
Character Limits
| Platform | Limit |
|---|---|
| Twitter/X | 280 per tweet |
| Bluesky | 300 per post |
| Threads | 500 per post |
| 3000 | |
| 2200 | |
| 63206 | |
| TikTok | 2200 (caption) |
| YouTube | 5000 (description) |
Workflow
When the user asks to create or schedule a post:
- Always call GET /accounts first to get the user's connected accounts and their IDs
- Match the user's requested platform(s) to the account IDs returned
- If the user doesn't specify a platform, ask which one(s) they want
- If the user wants to schedule, convert their time to ISO 8601 UTC format
- Create the post with the appropriate parameters
When the user asks about analytics or post performance:
- Call the analytics endpoints with the appropriate platform
- Present the data in a clear, readable format
API Reference
GET /accounts
List all connected social media accounts. Always call this first before creating posts.
curl -H "Authorization: Bearer $POSTHERO_API_KEY" \ https://server.posthero.ai/api/v1/accounts
Response:
{ "success": true, "data": [ { "id": "abc123", "platform": "linkedin", "name": "John Doe", "avatar": "https://...", "type": "personal" }, { "id": "def456", "platform": "twitter", "name": "@johndoe", "avatar": "https://..." } ] }
Use the
id field as accountId when creating posts.
POST /posts
Create a post. Can be a draft, scheduled, or published immediately.
curl -X POST \ -H "Authorization: Bearer $POSTHERO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "My post content here...", "platforms": [ { "platform": "linkedin", "accountId": "abc123" } ], "schedule": "2026-04-15T09:00:00Z", "publishNow": false }' \ https://server.posthero.ai/api/v1/posts
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | The post content |
| array | Yes | Array of objects |
| string | No | ISO 8601 UTC datetime. Omit for draft |
| boolean | No | Set to publish immediately |
| boolean | No | Set for threads. Separate posts with in text |
| object | No | Per-platform text overrides (see below) |
| object | No | Media attachments (see below) |
Behavior:
- No
and noschedule
→ creates a draftpublishNow
provided → creates a scheduled postschedule
→ publishes immediatelypublishNow: true
Platform content overrides (optional per-platform text):
{ "platformContent": { "twitter": { "text": "Short tweet version" }, "linkedin": { "text": "Longer LinkedIn version with #hashtags" }, "bluesky": { "text": "Bluesky-specific text" }, "threads": { "text": "Threads version" }, "facebook": { "text": "Facebook version" }, "instagram": { "text": "Instagram caption", "contentType": "feed" }, "youtube": { "text": "Video description", "title": "My Video Title", "tags": ["tag1", "tag2"], "privacy": "public", "videoType": "long" }, "tiktok": { "text": "TikTok caption", "privacyLevel": "PUBLIC_TO_EVERYONE", "allowComments": true, "allowDuet": true, "allowStitch": true } } }
Media attachments (optional):
{ "media": { "images": ["https://s3-url-1", "https://s3-url-2"], "video": "https://s3-video-url", "carousel": "https://s3-pdf-url" } }
Use URLs returned by the media upload endpoint. Up to 4 images, or 1 video, or 1 carousel PDF.
Threads: Set
isThread: true and separate each post with \n\n (double line break) in the text. Works for Twitter (280 chars/tweet), Bluesky (300 chars/post), and Threads (500 chars/post).
Response:
{ "success": true, "data": { "id": "post_abc123", "status": "scheduled", "text": "My post content here...", "platforms": [{ "platform": "linkedin", "accountId": "abc123" }], "schedule": "2026-04-15T09:00:00Z", "createdAt": "2026-04-10T10:00:00Z" } }
GET /posts
List posts with optional filters.
curl -H "Authorization: Bearer $POSTHERO_API_KEY" \ "https://server.posthero.ai/api/v1/posts?status=scheduled&platform=linkedin&page=1&limit=20"
Query parameters:
| Param | Description |
|---|---|
| Filter: , , , |
| Filter: , , , , , , , |
| Page number (default 1) |
| Posts per page (default 20, max 100) |
Response:
{ "success": true, "data": { "posts": [ { "id": "post_abc123", "text": "My post content...", "status": "published", "platforms": [ { "platform": "linkedin", "accountId": "abc123", "status": "published", "postId": "urn:li:share:123456", "postUrl": "https://linkedin.com/feed/update/..." } ], "schedule": null, "publishedAt": "2026-03-15T14:00:00Z", "createdAt": "2026-03-10T10:00:00Z" } ], "pagination": { "page": 1, "limit": 20, "total": 45, "hasMore": true } } }
GET /posts/:id
Get full details of a single post including per-platform publishing status, post IDs, and URLs.
curl -H "Authorization: Bearer $POSTHERO_API_KEY" \ https://server.posthero.ai/api/v1/posts/post_abc123
PATCH /posts/:id
Update a draft or scheduled post. Cannot update already-published posts.
curl -X PATCH \ -H "Authorization: Bearer $POSTHERO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "Updated content", "schedule": "2026-04-16T10:00:00Z" }' \ https://server.posthero.ai/api/v1/posts/post_abc123
All fields are optional:
text, schedule, platforms, platformContent, media.
DELETE /posts/:id
Delete a post from PostHero. Works for any status (draft, scheduled, published). Does NOT remove it from the social media platform.
curl -X DELETE \ -H "Authorization: Bearer $POSTHERO_API_KEY" \ https://server.posthero.ai/api/v1/posts/post_abc123
POST /posts/:id/publish
Immediately publish a draft or scheduled post.
curl -X POST \ -H "Authorization: Bearer $POSTHERO_API_KEY" \ https://server.posthero.ai/api/v1/posts/post_abc123/publish
Response:
{ "success": true, "data": { "id": "post_abc123", "status": "published", "results": [ { "platform": "linkedin", "status": "published", "postId": "urn:li:share:123456", "postUrl": "https://linkedin.com/feed/update/..." }, { "platform": "twitter", "status": "published", "postId": "1234567890", "postUrl": "https://x.com/user/status/1234567890" } ] } }
POST /media/upload
Upload an image, video, or carousel PDF. Returns an S3 URL to use in
media when creating posts.
curl -X POST \ -H "Authorization: Bearer $POSTHERO_API_KEY" \ -F "file=@image.jpg" \ https://server.posthero.ai/api/v1/media/upload
Response:
{ "success": true, "data": { "url": "https://s3.amazonaws.com/...", "type": "image", "size": 245000, "mimeType": "image/png" } }
GET /analytics/summary
Get aggregated analytics for a platform.
curl -H "Authorization: Bearer $POSTHERO_API_KEY" \ "https://server.posthero.ai/api/v1/analytics/summary?platform=threads"
Query parameters:
| Param | Required | Description |
|---|---|---|
| Yes | , , , , |
| No | Filter by specific account |
| No | Start date (YYYY-MM-DD) |
| No | End date (YYYY-MM-DD) |
GET /analytics/top
Get top-performing posts ranked by a metric.
curl -H "Authorization: Bearer $POSTHERO_API_KEY" \ "https://server.posthero.ai/api/v1/analytics/top?platform=threads&metric=likes&limit=5"
Query parameters:
| Param | Required | Description |
|---|---|---|
| Yes | , , , , |
| No | , , , , |
| No | Number of posts (default 10) |
| No | Start date (YYYY-MM-DD) |
| No | End date (YYYY-MM-DD) |
GET /analytics/posts
Get paginated post analytics.
curl -H "Authorization: Bearer $POSTHERO_API_KEY" \ "https://server.posthero.ai/api/v1/analytics/posts?platform=threads&sortBy=likes&limit=20"
GET /analytics/follower-growth
Get follower count and growth delta.
curl -H "Authorization: Bearer $POSTHERO_API_KEY" \ "https://server.posthero.ai/api/v1/analytics/follower-growth?platform=threads&account=abc123"
Error Handling
All errors return:
{ "success": false, "error": "Human-readable error message", "code": "MACHINE_READABLE_CODE" }
| Code | HTTP | Description |
|---|---|---|
| 401 | Missing or invalid API key |
| 403 | Plan doesn't include API |
| 404 | Resource not found |
| 400 | Invalid request body |
| 400 | Social account not found or not owned by user |
| 429 | Too many API requests |
| 500 | Publishing failed on one or more platforms |
Rate Limits
- 60 requests per minute
- 100 posts created per month (API plan)
- Media uploads: 200 per month
Response headers on every request:
X-RateLimit-Limit: 60 X-RateLimit-Remaining: 45 X-RateLimit-Reset: 1710500000
Important Notes
- Always call GET /accounts first to get account IDs before creating posts
- Times must be ISO 8601 UTC format (e.g.
)2026-04-15T09:00:00Z - When the user says a time like "tomorrow at 9am", convert to UTC based on context
- For cross-posting to multiple platforms, include all platform/accountId pairs in the
arrayplatforms - Thread mode uses
as separator — respect per-platform character limits\n\n - Media URLs must come from the /media/upload endpoint (S3 URLs)
- DELETE only removes from PostHero, not from the social media platform