IMMA AI Docs
API reference

Posts

Create, validate, list, update, cancel and retry posts across TikTok, Instagram, Facebook Pages and Threads.

Preview

Preview: the API and MCP server are in private beta; details may change.

A post (post_...) is a caption plus media sent to one or more targets. Each target tracks its own status independently, so one platform failing does not affect the others.

Required scope: posts:write to create, validate, update, cancel or retry; posts:read to list or get.

Endpoints

MethodPathDescription
POST/postsCreate a post
POST/posts/validateDry-run validation; returns issues[] without saving
GET/postsList posts, filterable by status, date range, profile and platform
GET/posts/{id}Get a post's detail, including each target and its permalink or error
PATCH/posts/{id}Change caption or schedule while the post has not started publishing
POST/posts/{id}/cancelCancel a post
POST/posts/{id}/retryRetry targets that failed with a retryable error

For creating many posts in one call, see Posts batch.

Create a post

Request parameters

NameTypeRequiredDescription
profile_idstringYesThe profile this post belongs to
captionstringYesPost caption
mediaarray of stringsYesOne or more media_id values, ready before the post can publish
targetsarray of objectsYesOne entry per account: { account_id, instagram?, tiktok? }
scheduled_atstring (ISO 8601 with offset)NoWhen to publish. Omit to publish as soon as approved
approvalobjectNo{ mode: "link" | "none", notify? }. Defaults to "link"
ai_generatedbooleanNoWhether this content was generated by an AI. Passed through to TikTok's is_aigc label

Each targets[].tiktok entry needs mode: "direct" or mode: "inbox". A direct target without an explicit consent object is automatically routed to approval or inbox mode; see Platform notes below.

curl -X POST https://api.getimma.com/v1/posts \
  -H "Authorization: Bearer imma_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f9b6c2e-3b9a-4b8a-9b2e-3f9b6c2e3b9a" \
  -d '{
    "profile_id": "prof_01J...",
    "caption": "Rendang 1 kg, pre-order until Friday #rendang",
    "media": ["med_01J..."],
    "targets": [
      { "account_id": "acc_ig_...", "instagram": { "type": "reel" } },
      { "account_id": "acc_tt_...", "tiktok": { "mode": "direct" } }
    ],
    "scheduled_at": "2026-09-28T18:30:00+07:00",
    "approval": { "mode": "link", "notify": { "email": "[email protected]" } },
    "ai_generated": true
  }'

Response (201):

{
  "id": "post_01J...",
  "status": "awaiting_approval",
  "approval": {
    "id": "apr_...",
    "url": "https://getimma.com/approve/k8Fq2...",
    "expires_at": "2026-10-01T18:30:00+07:00"
  },
  "targets": [
    { "id": "tgt_1", "account_id": "acc_ig_...", "status": "awaiting_approval" },
    { "id": "tgt_2", "account_id": "acc_tt_...", "status": "awaiting_approval" }
  ],
  "warnings": []
}

Initial status rules

  • approval.mode: "link" (default): every target waits for approval, including non-TikTok targets.
  • approval.mode: "none":
    • Non-TikTok targets go straight to scheduled or queued.
    • A TikTok direct target must include a consent object (see Platform notes), or the request returns 422 consent_required with a hint to use approval.mode: "link" or tiktok.mode: "inbox" instead.

Validate without saving

curl -X POST https://api.getimma.com/v1/posts/validate \
  -H "Authorization: Bearer imma_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "profile_id": "prof_01J...", "caption": "...", "media": ["med_01J..."], "targets": [{ "account_id": "acc_tt_..." }] }'

Returns { "issues": [] } (or a populated issues array) without creating a post. Useful for an AI agent to check a draft before committing to it.

List posts

curl "https://api.getimma.com/v1/posts?status=scheduled&profile_id=prof_01J..." \
  -H "Authorization: Bearer imma_live_xxxxxxxxxxxxxxxxxxxx"

Supports status, a date range, profile_id, platform and cursor pagination; see Pagination.

Update, cancel, retry

curl -X PATCH https://api.getimma.com/v1/posts/post_01J... \
  -H "Authorization: Bearer imma_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "caption": "Rendang 1 kg, pre-order until Saturday #rendang" }'

curl -X POST https://api.getimma.com/v1/posts/post_01J.../cancel \
  -H "Authorization: Bearer imma_live_xxxxxxxxxxxxxxxxxxxx"

curl -X POST https://api.getimma.com/v1/posts/post_01J.../retry \
  -H "Authorization: Bearer imma_live_xxxxxxxxxxxxxxxxxxxx"

PATCH only works while the post has not started publishing. retry re-attempts targets that failed with a retryable: true error (see Errors); it does not retry targets that already succeeded.

Errors

CodeHTTPWhen
unauthorized401Missing or invalid API key
insufficient_scope403Key lacks posts:write or posts:read
consent_required422A TikTok direct target had no consent object and approval.mode was "none"
quota_exceeded422The target account's daily posting limit is already reached
idempotency_conflict409Same Idempotency-Key reused with a different body
not_found404Post does not exist, or belongs to another workspace

See Errors for the full list and shared error shape.

Platform notes

TikTok Direct Post always needs explicit human consent captured either through IMMA AI's hosted approval page or through a documented consent flag your own UI collects. There is no way to skip this by calling the API directly; it is enforced the same way regardless of caller. See Platform rules for the full consent contract, the inbox mode alternative, and posting limits per platform (Instagram 100/24h, Threads 250/24h, TikTok around 15/day).

On this page