Schedule and manage social media posts across multiple social platforms. Query analytics, manage your queue, and publish immediately — all via natural language. Call GET /api/v1/platforms for the list of platforms active on this instance.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Schedule and manage social media posts across multiple social platforms. Query analytics, manage your queue, and publish immediately — all via natural language. Call GET /api/v1/platforms for the list of platforms active on this instance.
homepage
https://postthatlater.com
PostThatLater Skill
Schedule and manage social media posts from Claude Code or any AI assistant.
Call GET /api/v1/accounts first — you need numeric account IDs to schedule posts. Never guess them.
Ask for timezone once per session — all scheduled_at values must be ISO 8601 UTC (e.g. 2026-03-10T09:00:00Z). Convert from the user's local time.
Confirm before publish_now — publishing is immediate and irreversible. Always confirm with the user before calling the publish-now endpoint.
Use Idempotency-Key on every POST/PATCH — generate a UUID per request to prevent duplicate posts on retry. Example: Idempotency-Key: $(uuidgen | tr '[:upper:]' '[:lower:]').
Check platform limits — always call GET /api/v1/platforms to get the live list of available platforms and their limits. Never hardcode a platform list or assume a platform is available.
Cross-posting — pass multiple IDs in account_ids to post the same content everywhere at once. The API creates one post record per account and links them via group_id.
All times are UTC in responses — convert to the user's timezone when displaying scheduled times.
Posting with an image — first POST /api/v1/images with the image URL to get a filename, then pass that filename in the images array of POST /api/v1/posts. Use GET /api/v1/images to list already-stored images that can be reused without re-uploading.
status — pending, posted, or failed (omit for all)
platform — e.g. bluesky, mastodon, linkedin
limit — max results (default: 20, max: 100)
offset — skip N results for pagination (default: 0)
Response:
{"data":[{"id":101,"text":"Hello from the API!","scheduled_at":"2026-03-15T09:00:00.000Z","status":"pending","platform":"bluesky","account_id":12,"images":[],"platform_post_id":null,"platform_post_url":null,"error_message":null,"retry_count":0,"likes":0,"comments":0,"shares":0,"group_id":null,"created_at":"2026-03-01T12:00:00.000Z","updated_at":null}],"meta":{"request_id":"...","total":5,"limit":10,"offset":0}}
Pass the filename in the images array of POST /api/v1/posts. Check GET /api/v1/platforms for the max_images limit per platform.
List stored images
Returns all images referenced by your posts with file metadata and which post IDs use each image. Use this to reuse an already-uploaded image without re-ingesting.
Returns character limits and capabilities for all currently available platforms.
New platforms may be added over time, so always fetch this list rather than
hardcoding platform names or limits.
curl https://postthatlater.com/api/v1/platforms
Response fields per platform:
name — slug used in API calls (e.g. bluesky)
display_name — human-readable name
char_limit — maximum post length in characters
max_images — maximum images per post
supports_video — whether video uploads are accepted
notes — platform-specific connection or usage notes
---
## Error Handling
All errors follow:
```json
{
"error": {
"code": "validation_error",
"message": "Validation failed.",
"details": [
{ "field": "text", "message": "Text exceeds Bluesky character limit (300 chars)." },
{ "field": "scheduled_at", "message": "scheduled_at must be a future datetime." }
]
}
}
Code
HTTP
Meaning
invalid_api_key
401
Missing, malformed, or revoked Bearer token
subscription_required
402
No active subscription
not_found
404
Resource doesn't exist or belongs to another user
conflict
409
Action not allowed in current state (e.g. editing a published post)
validation_error
400
Request body failed validation — check details array for field-level errors
rate_limited
429
60 req/min per key — check Retry-After header
internal_error
500
Unexpected server error
Example Session
User: Schedule a post about our summer sale on Bluesky and Mastodon for tomorrow at 10am EST
Agent workflow:
1. GET /api/v1/accounts → find Bluesky (id: 12) and Mastodon (id: 15)
2. GET /api/v1/platforms → confirm char limits (300 / 500)
3. Convert 10am EST → 15:00 UTC (March 5 → 2026-03-05T15:00:00Z)
4. Confirm with user: "Ready to schedule 'Summer sale...' to Bluesky + Mastodon for Mar 5 at 10am EST?"
5. POST /api/v1/posts with account_ids: [12, 15] and Idempotency-Key header
6. Report back: "Scheduled! Post #101 and #102 will go out March 5 at 10am EST."