Publish & Schedule
Publish posts now, schedule for later, cancel, and configure platform settings.
Publish a draft post immediately, schedule it for later, cancel a scheduled publish, or set platform-specific options (TikTok privacy, YouTube visibility, Threads who can reply).
Publish Post
POST /api/v1/posts/{id}/publish
Publish a draft post to connected social platforms. Each item is published to its target platform independently — if one fails, the others still go through.
Prerequisites
Before publishing, ensure:
- Platforms are connected — Connect your social accounts in Settings → Connections
- Post is publishable — A post can be published only when its status is
draft. After first publish starts, the post moves tosentand each item owns its own lifecycle. Retry failed items withPOST /api/v1/post-items/{id}/retry. - Enough credits — Publishing uses credits. The amount depends on the platform.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The post ID |
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
items | array | No | Per-item publish settings. Each entry needs item_id; settings is optional. Items omitted from the array publish with defaults — see Publish Settings Reference. |
If items is omitted entirely (or sent without settings), all items publish with the documented defaults.
Example
curl -X POST https://powerpost.ai/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000/publish \
-H "x-api-key: pp_live_sk_YOUR_KEY" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"item_id": "item-yt-002-cccc-dddd",
"settings": {
"privacy_status": "public",
"self_declared_made_for_kids": false,
"embeddable": true
}
}
]
}'Response
{
"post_id": "post-550e8400-e29b-41d4-a716-446655440000",
"status": "draft",
"skipped": ["x"],
"status_url": "/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000"
}| Field | Type | Description |
|---|---|---|
post_id | string | The post ID |
status | string | Stored post status at enqueue time |
skipped | array | Platform names (strings) with no active connection; they won't be posted. Empty when every platform is connected. |
status_url | string | Relative URL to poll for status |
Publishing is asynchronous. A 200 means the publish was accepted and enqueued; the post stays draft until the background job claims it and moves it to sent. Poll the Get Post endpoint or use webhooks to know when publishing completes.
If only some target platforms are connected, the connected ones publish and the rest come back in skipped. The whole request is rejected with a 422 only when none of the target platforms are connected.
Publishing Costs
Publishing uses credits. You are charged for each item that publishes successfully, after it goes out. The amount depends on the platform. The publish response does not include a cost, because nothing has been charged yet. Check your balance with Get Credits after publishing. See Credits.
Credits are only charged for items that publish successfully. If an item fails, no credits are charged for it.
Schedule Post
POST /api/v1/posts/{id}/schedule
Schedule a draft post to publish automatically at a future time. The post is held in scheduled status until then, when it publishes exactly as Publish Post would.
Prerequisites
Same as publishing — platforms connected and content ready. The post must be in draft status. Credits aren't checked when you schedule; they're charged per successful item when the post publishes, so make sure the balance is funded before the scheduled time.
A workspace can hold up to 100 scheduled posts at once; scheduling more returns a 400.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The post ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
scheduled_at | string | Yes | ISO 8601 datetime with a timezone offset, e.g. 2026-02-01T15:00:00Z. Must be at least a minute in the future and within 60 days. |
items | array | No | Optional per-item publish settings. Same shape as the Publish Post body — see Publish Settings Reference. |
Example
curl -X POST https://powerpost.ai/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000/schedule \
-H "x-api-key: pp_live_sk_YOUR_KEY" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"scheduled_at": "2026-02-01T15:00:00Z",
"items": [
{
"item_id": "item-yt-002-cccc-dddd",
"settings": {
"privacy_status": "public",
"self_declared_made_for_kids": false,
"embeddable": true
}
}
]
}'Response
{
"post_id": "post-550e8400-e29b-41d4-a716-446655440000",
"status": "scheduled",
"scheduled_at": "2026-02-01T15:00:00Z",
"skipped": ["x"],
"status_url": "/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000"
}| Field | Type | Description |
|---|---|---|
post_id | string | The post ID |
status | string | scheduled while waiting to publish |
scheduled_at | string | The confirmed publish time |
skipped | array | Platform names not connected right now. Reflects connection state at scheduling time; the job re-checks when it runs, so the item status on status_url is the source of truth. |
status_url | string | Relative URL to poll for status |
Scheduling needs an API key with the posts:publish scope. A key without it gets a 403.
Publish Settings Reference
Some post types accept extra publish-time settings via the optional items[].settings field on Publish Post and Schedule Post.
If items is omitted, or an item appears without settings, TikTok posts publish as SELF_ONLY
(private to the creator) and YouTube posts publish as private. Threads defaults to
reply_control: everyone (anyone can reply). Instagram leaves the AI label off unless
is_ai_generated is true. Set TikTok/YouTube settings explicitly to publish publicly.
TikTok Video (tiktok-video)
| Field | Type | Allowed values | Default |
|---|---|---|---|
privacy_level | string | PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY | SELF_ONLY |
disable_comment | boolean | false | |
disable_duet | boolean | false | |
disable_stitch | boolean | false | |
brand_content_toggle | boolean | false | |
brand_organic_toggle | boolean | false | |
is_brand_content | boolean | false |
TikTok Photos (tiktok-photos)
Same as TikTok Video minus disable_duet and disable_stitch.
YouTube Video & Short (youtube-video, youtube-short)
| Field | Type | Allowed values | Default |
|---|---|---|---|
privacy_status | string | public, unlisted, private | public |
self_declared_made_for_kids | boolean | false | |
embeddable | boolean | true |
YouTube may restrict uploads to private viewing for unverified API projects, regardless of the requested visibility. See YouTube's upload restrictions.
Threads (threads-post)
| Field | Type | Allowed values | Default |
|---|---|---|---|
reply_control | string | everyone, accounts_you_follow, mentioned_only, parent_post_author_only, followers_only | everyone |
Instagram (instagram-feed, instagram-reel, instagram-story)
| Field | Type | Default |
|---|---|---|
is_ai_generated | boolean | false |
Set this to true when you want Instagram's AI info label on the post. The label goes on the container that gets published. Carousel slides are not labeled on their own. PowerPost does not turn this on based on how the media was made.
Other Platforms
Facebook, X, and LinkedIn have no publish-time settings. Sending settings for one of those items returns 400.
Cancel Scheduled Post
POST /api/v1/posts/{id}/cancel-publish
Cancel a scheduled (or in-progress) publish and revert the post to a draft. Only works while nothing has gone out yet — once any item has started posting, the publish can no longer be cancelled.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The post ID |
Example
curl -X POST https://powerpost.ai/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000/cancel-publish \
-H "x-api-key: pp_live_sk_YOUR_KEY" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID"Response
{
"post_id": "post-550e8400-e29b-41d4-a716-446655440000",
"status": "draft",
"reverted": true
}| Field | Type | Description |
|---|---|---|
post_id | string | The post ID |
status | string | draft — the post is back to a draft |
reverted | boolean | Always true on a successful response. A post that has already started publishing returns a 400 instead |
Cancelling needs an API key with the posts:publish scope. A key without it gets a 403.
Errors
| Code | Description |
|---|---|
| 400 | Invalid request body, bad scheduled_at, or bad items[].settings |
| 401 | Invalid API key |
| 402 | Insufficient credits for publishing |
| 403 | API key is missing the posts:publish scope |
| 404 | Post not found |
| 409 | Post is not in a publishable state (already published, or already scheduled) |
| 422 | None of the target platforms are connected (if some are, they publish and the rest come back in skipped) |
| 429 | Rate limit exceeded |
| 502 | Scheduled publish could not be cancelled; try again shortly |
Related
- Posts — Create and get posts
- Post items — List and retry
- Post types — Media and caption limits
- Credits — How publishing is charged
- Webhooks —
post_item.published/post_item.failed