Skip to main content

Posts API

The /v1/posts endpoints let you create, list, inspect, update, reschedule, retry, and delete posts. Creating a post is the core operation — it's how you cross-post, schedule, and attach media programmatically.

All endpoints require authentication and an active or trialing subscription.


Create a post​

POST /api/v1/posts

Creates a post. Depending on the body, it becomes a draft (no scheduledAt) or a scheduled post. A single call can fan out to multiple accounts (cross-post) with per-channel overrides.

Request body​

FieldTypeRequiredDescription
accountIdsstring[]yesOne or more connected account IDs to post to. Min 1.
captionstringnoThe default caption text.
firstCommentstringnoA comment to post immediately after publish.
postTypestringnoPost type (e.g. post, reel, story, short, thread). Defaults to post.
mediaIdsstring[]noMedia IDs to attach (must be in your organization).
accountOverridesarraynoPer-channel caption/field overrides (see below).
threadPartsRecord of accountId → string[]noThread renditions (postType thread). Chain platforms carry N parts; LinkedIn/Facebook carry the full text as one element. null clears.
scheduledAtstring (ISO 8601)noOmit to save as a draft; include to schedule.

accountOverrides[]​

FieldTypeDescription
accountIdstringThe account this override applies to.
captionOverridestring | nullReplace the caption for this channel.
fieldsobjectPlatform-specific field overrides ({ key: value }).

Validation​

Before any rows are written, the request is validated against platform limits: caption length, post type, media constraints (count, size, aspect ratio, duration), and ownership of both accountIds and mediaIds.

note

This endpoint's 400/403 errors use the legacy flat shape ({ "error": "<message>" }), not the structured error.code shape.

Example: cross-post with overrides​

curl -X POST https://<your-api-origin>/api/v1/posts \
-H "Authorization: Bearer sx_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"caption": "Our new feature ships today 🚀",
"postType": "post",
"accountIds": ["acc_instagram", "acc_x", "acc_linkedin"],
"mediaIds": ["med_01"],
"accountOverrides": [
{ "accountId": "acc_x", "captionOverride": "New feature, shipping today." },
{ "accountId": "acc_linkedin", "captionOverride": "Today we are launching..." }
],
"scheduledAt": "2026-07-15T14:30:00Z"
}'

Example: draft (no schedule)​

curl -X POST https://<your-api-origin>/api/v1/posts \
-H "Authorization: Bearer sx_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"caption": "Draft caption",
"accountIds": ["acc_instagram"]
}'

Response — 201 Created​

{
"data": {
"id": "pst_abc123",
"status": "scheduled"
}
}

status is "scheduled" when scheduledAt is provided, otherwise "draft".

Errors​

StatusBody shapeMeaning
400{ "error": "<message>" }Invalid body, or platform-limit violation
403{ "error": "<message>" }accountIds or mediaIds not in your organization
401{ "error": "<message>" }Missing/invalid API key

List posts​

GET /api/v1/posts

Returns your posts, newest first. Uses standard pagination.

Query parameters​

ParameterTypeDefaultRangeDescription
limitinteger251–100Page size
offsetinteger0≥ 0Skip count
statusstring—enumdraft, scheduled, publishing, published, failed
qstring—1–200Case-insensitive caption search (ILIKE %q%)

Example​

curl "https://<your-api-origin>/api/v1/posts?status=scheduled&q=launch&limit=10" \
-H "Authorization: Bearer sx_live_YOUR_API_KEY"

Response — 200 OK​

{
"data": [
{
"id": "pst_abc123",
"caption": "Our new feature ships today 🚀",
"postType": "post",
"status": "scheduled",
"scheduledAt": "2026-07-15T14:30:00.000Z",
"createdAt": "2026-07-12T09:00:00.000Z",
"updatedAt": "2026-07-12T09:00:00.000Z"
}
],
"limit": 10,
"offset": 0
}

Only posts in your organization are returned.


Get a post​

GET /api/v1/posts/{id}

Returns full detail for one post.

Response — 200 OK​

{
"data": {
"id": "pst_abc123",
"caption": "Our new feature ships today 🚀",
"firstComment": null,
"postType": "post",
"status": "scheduled",
"scheduledAt": "2026-07-15T14:30:00.000Z",
"mediaIds": ["med_01"],
"accountOverrides": [],
"createdAt": "2026-07-12T09:00:00.000Z",
"updatedAt": "2026-07-12T09:00:00.000Z"
}
}

Errors​

StatusBody
404{ "error": { "code": "not_found", ... } }

Update a post​

PATCH /api/v1/posts/{id}

Updates a post. Omitted fields are left unchanged; nullable fields can be cleared by passing null.

Request body (all optional)​

FieldTypeDescription
captionstringNew caption
firstCommentstringNew first comment
postTypestringNew post type
statusstringdraft, scheduled, published, failed
scheduledAtstring (ISO 8601) | nullNew schedule time; null clears it
delayMinutesnumberDelay before publish (minutes)
accountIdsstring[]Replace destination accounts
accountOverridesarrayReplace per-channel overrides
mediaIdsstring[]Replace attached media (order preserved)
pollobject | null{ "question", "options", "durationDays" } (durationDays ≥ 1); null removes
threadPartsRecord | nullReplace thread renditions; null clears

Response — 200 OK​

The full updated post inside data (same shape as GET).


Reschedule a post​

POST /api/v1/posts/{id}/reschedule

Moves a scheduled post to a new time.

Request body​

FieldTypeRequiredDescription
scheduledAtstring (ISO 8601)yesNew time; a past timestamp is bumped to the next slot

Response — 200 OK​

The full updated post inside data.

Errors​

StatusBody
400{ "error": { "code": "validation_error", ... } }
404{ "error": { "code": "not_found", ... } }

Retry a failed post​

POST /api/v1/posts/{id}/retry

Queues a fresh publish job for a failed post.

Response — 200 OK​

{
"data": {
"jobId": "job_...",
"status": "queued"
}
}

Errors​

StatusBody
404{ "error": { "code": "not_found", ... } }

Post analytics​

GET /api/v1/posts/{id}/analytics

Returns the insight row recorded for a published post (impressions, likes, comments, etc., as available per platform). See Analytics.

Errors​

StatusBody
404{ "error": "Insight not found" }

Delete a post​

DELETE /api/v1/posts/{id}

Deletes a post. Only drafts and scheduled posts can be deleted — published posts cannot be deleted via the API (they return 400).

note

This endpoint's 400/404 errors use the legacy flat shape.

Example​

curl -X DELETE https://<your-api-origin>/api/v1/posts/pst_abc123 \
-H "Authorization: Bearer sx_live_YOUR_API_KEY"

Response — 200 OK​

{ "data": { "success": true } }

Errors​

StatusBody
400{ "error": "Cannot delete published post" }
404{ "error": "Post not found" }
note

This deletes the post in post.buzz. It does not delete the post from the social platform itself. Whether a published post can be removed from a platform depends on that platform's capabilities — see the capability matrix.