| name | social-publishing |
| description | Publish content to Twitter/X, LinkedIn, and Instagram via the content-calendar API. Use when asked to post to social media, schedule a tweet, publish a LinkedIn update, or post to Instagram through the content-calendar system. Triggers include "post to Twitter", "publish on LinkedIn", "Instagram post", "social media post", or any request to push content to a social platform. |
social-publishing
Publish social media posts via the content-calendar API. Handles platform-specific formatting constraints and scheduling.
When to use
- Publishing a post to one or more social platforms immediately
- Scheduling a post for a future date and time
- Checking platform character limits before posting
- Generating a platform-appropriate version of content
Platform Constraints
Apply these rules before constructing a post body:
Twitter / X
- Maximum 280 characters
- URLs count as 23 characters regardless of actual length
- Up to 4 images or 1 video
- No clickable links in body; link cards auto-generated
LinkedIn
- Maximum 3000 characters for company pages
- Up to 9 images or 1 video
- Links generate automatic preview cards
Instagram
- Maximum 2200 characters for captions
- No clickable links in captions (use "link in bio")
- Images must be at least 1080x1080 pixels
- Aspect ratios: 1:1, 4:5, or 1.91:1
Workflow: Publish a Post
1. Authenticate
curl -c cookies.txt -X POST http://localhost:3000/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"admin@example.com","password":"yourpassword"}'
2. Create a post
curl -b cookies.txt -X POST http://localhost:3000/api/posts \
-H 'Content-Type: application/json' \
-d '{
"title": "Spring announcement",
"body": "Big news from Acme Corp today...",
"platforms": ["twitter", "linkedin"],
"status": "draft"
}'
3. Schedule it
curl -b cookies.txt -X PUT http://localhost:3000/api/posts/{id} \
-H 'Content-Type: application/json' \
-d '{
"status": "scheduled",
"scheduled_at": "2026-03-24T09:00:00Z"
}'
4. Or publish immediately
curl -b cookies.txt -X POST http://localhost:3000/api/posts/{id}/publish
Workflow: Post with Media
Upload the media first, then reference the ID in the post.
curl -b cookies.txt -X POST http://localhost:3000/api/media \
-F 'file=@/path/to/image.png'
curl -b cookies.txt -X POST http://localhost:3000/api/posts \
-H 'Content-Type: application/json' \
-d '{
"title": "Product launch",
"body": "Our new product is here...",
"platforms": ["twitter", "instagram"],
"media_ids": ["abc123"],
"status": "scheduled",
"scheduled_at": "2026-03-25T10:00:00Z"
}'
Platform-Specific Body Overrides
When a single body does not work across all platforms (e.g. Twitter needs a shorter version), use platform overrides:
curl -b cookies.txt -X POST http://localhost:3000/api/posts \
-H 'Content-Type: application/json' \
-d '{
"title": "Announcement",
"body": "Long LinkedIn version of the post content...",
"platforms": ["twitter", "linkedin"],
"platform_overrides": {
"twitter": "Short version under 280 chars. Link in bio."
},
"status": "scheduled",
"scheduled_at": "2026-03-24T09:00:00Z"
}'
Checking Character Count
Before submitting, count characters for the target platform:
const body = "Your post content here...";
const twitterCount = body.length;
const withinLimit = twitterCount <= 280;
Post Status Values
| Status | Meaning |
|---|
| draft | Not scheduled, not published |
| scheduled | Has a future scheduled_at, waiting to publish |
| published | Successfully published |
| failed | Publish attempt failed (check platform connection) |
Troubleshooting
400 Bad Request on post create
Check that platforms is a non-empty array and body is within the character limit for all selected platforms.
401 Unauthorized
Session expired. Re-authenticate with POST /api/auth/login.
Post stays in "scheduled" state
The scheduler runs every minute. If a post has not published after 2 minutes past its scheduled time, check SCHEDULER_ENABLED=1 and review server logs for publish errors.
Platform publish error
The platform API rejected the post. Common reasons: expired access token (reconnect in Settings), body too long, or invalid media format.