Posts
Create drafts, schedule, publish now, edit, and read posts.
GET
/postsposts:readList posts. Query: status (filter), limit (default 50, max 200).
responsejson
{
"posts": [
{
"id": "…", "title": "…", "caption": "…",
"platforms": ["instagram", "twitter"],
"status": "scheduled",
"scheduled_at": "2026-07-20T14:30:00Z",
"published_at": null,
"media_urls": ["https://…"],
"media_type": "image",
"platform_results": {},
"created_at": "2026-07-13T09:00:00Z"
}
]
}POST
/postsposts:writeCreate a draft, schedule, or publish now — controlled by status.
request bodyjson
{
"title": "Optional title",
"caption": "The post text",
// Channel selection — prefer accountMappings; some platforms REQUIRE accountId.
"accountMappings": [
{ "platform": "instagram", "accountId": "a1b2…" },
{ "platform": "twitter", "accountId": "e5f6…" }
],
"mediaUrls": ["https://cdn.posteahora.com/…"], // from /media/upload-url
"mediaType": "image", // image | video
"postType": "post", // post | reel | story
"hashtags": ["#launch"],
"platformCaptions": { "twitter": "Shorter text for X" },
"platformOptions": { "tiktok": { "draft": true } },
"status": "published", // draft | scheduled | published
"scheduledAt": "2026-07-20T14:30:00Z" // required when status = scheduled
}responsejson
HTTP 201 — the created post(s). Multi-platform posts fan out into one row per platform at publish time.GET
/posts/:idposts:readRead one post (includes connected_account_id).
responsejson
{ "post": { "id": "…", … } }PATCH
/posts/:idposts:writeEdit a draft or scheduled post. Editable: caption, title, hashtags, mediaUrls, mediaType, postType, platforms, connectedAccountId, platformOptions, status (draft|scheduled), scheduledAt (future).
responsejson
{ "post": { "id": "…", … } }DELETE
/posts/:idposts:writeSoft-delete a post.
responsejson
{ "id": "…", "deleted": true }POST
/posts/:id/publishposts:writePublish an existing draft/scheduled post immediately. Poll GET /posts/:id for per-platform results.
responsejson
{ "postIds": ["…"], "status": "queued" }