Posts
Schedule post
Queues a LinkedIn or X draft post for publishing through Postiv's dispatcher. Never publishes immediately; if the account has human approvers, the post waits for approval first.
/api/public/posts/:id/schedulecurl -X POST https://postiv.ai/api/public/posts/ID_ID/schedule \
-H "Authorization: Bearer pk_postiv_..." \
-H "Content-Type: application/json" \
-d '{
"scheduledTime": "2026-08-01T09:30:00.000Z",
"integrationId": 123,
"mediaType": "text"
}'{
"success": true,
"schedule": {
"queueEntry": {
"id": "q1...",
"postId": "post1...",
"integrationId": 1234,
"scheduledTime": "2026-07-20T09:00:00.000Z",
"status": "queued",
"mediaType": "text"
},
"requiresApproval": false,
"approverCount": 0,
"autoApproved": false,
"remainingApprovers": 0,
"message": "Post scheduled successfully"
}
}Authorization
Requires an organization API key with the posts:schedule scope, sent as Authorization: Bearer or x-api-key.
Path parameters
idstringrequiredResource id from the corresponding list or create endpoint.
Body parameters
scheduledTimestringrequiredISO-8601 timestamp, must be >= 2 minutes in the future.
integrationIdintrequiredAlias: integration_id. Target account: a LinkedIn profile/page or X account. An X draft needs an X account, a LinkedIn draft a LinkedIn account.
mediaTypestringAlias: media_type. image and carousel are LinkedIn only (X: 400 x_media_not_supported); text works on both. Omit to auto-detect (uses the carousel or image saved on a LinkedIn draft, if any).
textimagecarouselmediaUrlsstring|string[]Alias: media_urls. LinkedIn only (X: 400 x_media_not_supported). Max 20 URLs, each a valid URL.
carouselIduuidAlias: carousel_id. LinkedIn only (X: 400 x_media_not_supported). Required if mediaType='carousel' or to publish an infographic (auto-detected format). Carousels need a rendered PDF first; infographics render automatically at schedule time.
mediaDataobjectAlias: media_data. { title?, altText?, description?, commentPlug? }. On X only commentPlug is accepted; anything else returns 400 x_media_not_supported.
commentPlugobjectAlias: comment_plug. { mode: inherit|disable|override, text?, imageSource?, delayMinutes? (min 2), comments?: [{ text, imageSource?, delayMinutes (min 2) }] (1 to 5 comments) }. Merged into mediaData.commentPlug if not already set there. On X each override comment is max 280 characters (400 invalid_comment_plug) and is posted as a self-reply to the first tweet.
Response
The scheduling result.
schedule.queueEntryobject{ id, postId, integrationId, scheduledTime, status, mediaType }
schedule.requiresApprovalbooleanschedule.approverCountintschedule.autoApprovedbooleantrue if the scheduler is themself an approver and auto-approved their own post.
schedule.remainingApproversintschedule.messagestringHuman-readable status message.
Errors
| 400 | unsupported_media_type / missing_carousel_id / scheduled_time_in_past / invalid_integration_id / invalid_scheduled_time / empty_post_content / missing_post_text |
| 400 | linkedin_cmm_reconnect_required: a Comment Plug is in play but the profile's LinkedIn comment permission isn't connected (LinkedIn only) |
| 400 | x_media_not_supported: mediaType image/carousel, mediaUrls, mediaSource, carouselId or mediaData (other than commentPlug) sent for an X post; X images live inside the post |
| 400 | invalid_x_text / invalid_x_content: a tweet is empty or over 280 characters (a link counts 23), or the X content is invalid. invalid_comment_plug: an X override comment is over 280 characters |
| 400 | x_image_unavailable: an image in the X post was deleted; remove it or attach it again |
| 404 | post_not_found / linkedin_profile_not_found / integration_not_found (X account missing or needing reconnection) |
| 400 | post_already_published: post status is already published |
| 409 | post_already_scheduled: a live queue entry already exists (duplicate-call guard) |
| 409 | approval_link_not_supported_for_x: the X account is set to client approval links, which X does not support yet; switch it to team approvers in Settings |
| 409 | carousel_already_scheduled: the carousel is already scheduled on a post outside this post's stack (the versions of one stack can share a carousel) |
| 409 | carousel_pdf_not_ready: carousel media type requested but no rendered PDF; call render-carousel first |
| 502 | infographic_render_failed: automatic canvas render failed at schedule time |
Good to know
- If mediaType/mediaUrls are both omitted, an image already attached to the post via generate_post_image/edit_post_image is auto-attached. carouselId + no explicit mediaType auto-detects carousel vs. infographic format from the carousel's saved content and adjusts mediaType/mediaUrls accordingly (infographics publish as an image post of the rendered canvas PNG).
- X posts carry their images inside the post (tweet assets or the article), so none of the media params apply. Team approvals, the 2-minute lead time and Comment Plug overrides work as on LinkedIn; client approval links do not apply to X.