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.

POST/api/public/posts/:id/schedule
cURLPOST /api/public/posts/:id/schedule
curl -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"
  }'
200Response
{
  "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

idstringrequired

Resource id from the corresponding list or create endpoint.

Body parameters

scheduledTimestringrequired

ISO-8601 timestamp, must be >= 2 minutes in the future.

integrationIdintrequired

Alias: integration_id. Target account: a LinkedIn profile/page or X account. An X draft needs an X account, a LinkedIn draft a LinkedIn account.

mediaTypestring

Alias: 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).

One of:textimagecarousel
mediaUrlsstring|string[]

Alias: media_urls. LinkedIn only (X: 400 x_media_not_supported). Max 20 URLs, each a valid URL.

carouselIduuid

Alias: 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.

mediaDataobject

Alias: media_data. { title?, altText?, description?, commentPlug? }. On X only commentPlug is accepted; anything else returns 400 x_media_not_supported.

commentPlugobject

Alias: 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.requiresApprovalboolean
schedule.approverCountint
schedule.autoApprovedboolean

true if the scheduler is themself an approver and auto-approved their own post.

schedule.remainingApproversint
schedule.messagestring

Human-readable status message.

Errors

400unsupported_media_type / missing_carousel_id / scheduled_time_in_past / invalid_integration_id / invalid_scheduled_time / empty_post_content / missing_post_text
400linkedin_cmm_reconnect_required: a Comment Plug is in play but the profile's LinkedIn comment permission isn't connected (LinkedIn only)
400x_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
400invalid_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
400x_image_unavailable: an image in the X post was deleted; remove it or attach it again
404post_not_found / linkedin_profile_not_found / integration_not_found (X account missing or needing reconnection)
400post_already_published: post status is already published
409post_already_scheduled: a live queue entry already exists (duplicate-call guard)
409approval_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
409carousel_already_scheduled: the carousel is already scheduled on a post outside this post's stack (the versions of one stack can share a carousel)
409carousel_pdf_not_ready: carousel media type requested but no rendered PDF; call render-carousel first
502infographic_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.