Posteady
Posteady Docs
API

Instagram media publishing

Upload, publish, schedule, and track Instagram feed posts, Reels, and Stories through the REST API.

Use an Instagram professional account and confirmed media from the same workspace. Each request targets one account and uses an instagram object instead of posts or video.

Retrieve the account ID from GET /api/v1/accounts. Instagram accounts expose accountType as business, creator, or unknown, and support reads, publishing, and scheduling when the corresponding capability is true.

Choose or upload media

List JPEG images with mediaType=IMAGE or MP4/QuickTime videos with mediaType=VIDEO:

curl "https://www.posteady.com/api/v1/media?mediaType=IMAGE&limit=20&offset=0" \
  -H "Authorization: Bearer $POSTEADY_API_KEY"

mediaType defaults to VIDEO for compatibility. To upload a JPEG image, create a reservation:

curl -X POST https://www.posteady.com/api/v1/media/uploads \
  -H "Authorization: Bearer $POSTEADY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mediaType": "IMAGE",
    "fileName": "launch.jpg",
    "contentType": "image/jpeg",
    "fileSize": 1048576
  }'

PUT the bytes to the returned uploadUrl within 300 seconds using every returned requiredHeaders value. Then call POST /api/v1/media/uploads/confirm with the returned fileKey within 24 hours. Uploads stay in private staging until Posteady checks the reserved size, MIME type, and file signature and promotes the exact object to the media library.

JPEG images may be up to 8 MiB. The shared library accepts MP4 or QuickTime videos up to 2 GiB, while Instagram requests accept videos up to 1 GiB and 3 seconds–15 minutes long. Story videos allow up to 60 seconds. duration, width, and height are optional client hints when confirming a video; Posteady measures supported MP4/QuickTime files on the server and stores the measured values. Meta performs the final codec, frame-rate, bitrate, and aspect-ratio checks while processing the container. A reserved or uploaded file is unavailable for publishing until confirmation succeeds.

Supported posts

contentTypeMediaOptions
FEEDOne JPEG image, or 2–10 JPEG/video itemsOptional caption; altText on images
REELSOne videoOptional caption and shareToFeed
STORIESOne JPEG image or videoNo caption or shareToFeed

Captions allow up to 2,200 Unicode characters. Image altText allows up to 1,000 Unicode characters. A single FEED video is rejected; publish it as REELS or include it in a 2–10 item carousel.

Publish now

Generate one UUID for the operation and keep it when retrying the same request:

curl -X POST https://www.posteady.com/api/v1/posts \
  -H "Authorization: Bearer $POSTEADY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accountIds": ["<instagram-account-uuid>"],
    "instagram": {
      "requestId": "<request-uuid>",
      "contentType": "FEED",
      "caption": "A look at our latest release",
      "items": [
        { "mediaId": "<confirmed-image-uuid>", "altText": "The new product on a desk" },
        { "mediaId": "<confirmed-video-uuid>" }
      ]
    }
  }'

An accepted job returns HTTP 202. success: true means the job was accepted; it does not confirm publication. Store results[0].jobId and wait for published:

curl "https://www.posteady.com/api/v1/publish-jobs/<job-uuid>" \
  -H "Authorization: Bearer $POSTEADY_API_KEY"

The status is queued, scheduled, processing, published, failed, canceled, or unknown. Native postId and permalink remain null until available. unknown means the final submission outcome could not be established. Posteady will not automatically submit it again; check Instagram before creating a request with a new key.

The same requestId with unchanged input returns the existing job. Reusing it with a different account, content type, caption, items, options, or schedule returns 409 REQUEST_CONFLICT.

Schedule and cancel

Send the same fields to POST /api/v1/scheduled-posts and add a future scheduledAt with an offset and an optional IANA timezone:

{
  "accountIds": ["<instagram-account-uuid>"],
  "instagram": {
    "requestId": "<request-uuid>",
    "contentType": "STORIES",
    "items": [{ "mediaId": "<confirmed-image-uuid>" }]
  },
  "scheduledAt": "<future-time-with-offset>",
  "timezone": "Asia/Seoul"
}

List schedules with provider=instagram. Cancel a pending one with:

curl -X DELETE "https://www.posteady.com/api/v1/scheduled-posts/<scheduled-post-uuid>?platform=instagram" \
  -H "Authorization: Bearer $POSTEADY_API_KEY"

Cancellation is available until publishing starts. Later attempts return POST_NOT_CANCELLABLE.

After an API-created schedule is accepted, its content, media, and target account are fixed. You can change only its scheduled time in Posteady or cancel it before publishing starts. This keeps the accepted idempotency request and the media containers consistent.

Read posts and metrics

Call GET /api/v1/posts?provider=instagram. Results come from data already synchronized to Posteady; the request does not refresh Instagram. Each post may include mediaType, mediaProductType, and metricsUpdatedAt. Metrics map impressions to views, comments to replies, and saves to bookmarks; unavailable metrics are null rather than zero.

Use MCP

The equivalent tools are list_accounts, list_media, create_media_upload, confirm_media_upload, publish_post, schedule_post, get_publish_status, list_scheduled_posts, cancel_scheduled_post, and list_posts. Pass the same instagram object to publish_post or schedule_post. Media tools use workspaceId, or your default workspace when omitted. Publishing and scheduling derive the workspace from the account; publishing status derives it from the job. An optional workspaceId must match that resource. The file bytes still require a PUT to the issued upload URL. See What you can do.

On this page