Skip to main content
POST
/
posts
curl -X POST "https://mvp2.tryunsora.com/api/v1/posts" \
  -H "Authorization: Bearer uns_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "Behind the scenes",
    "media": {
      "type": "video",
      "url": "https://cdn.example.com/reel.mp4",
      "cover_url": "https://cdn.example.com/cover.jpg"
    },
    "accounts": [{ "id": "YOUR_INSTAGRAM_ACCOUNT_ID" }]
  }'
curl -X POST "https://mvp2.tryunsora.com/api/v1/posts" \
  -H "Authorization: Bearer uns_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "Quick tip",
    "media": {
      "type": "video",
      "url": "https://cdn.example.com/tip.mp4"
    },
    "accounts": [{ "id": "YOUR_TIKTOK_ACCOUNT_ID" }]
  }'
curl -X POST "https://mvp2.tryunsora.com/api/v1/posts" \
  -H "Authorization: Bearer uns_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "3 looks for the weekend",
    "media": {
      "type": "slideshow",
      "urls": [
        "https://cdn.example.com/1.jpg",
        "https://cdn.example.com/2.jpg"
      ]
    },
    "accounts": [{ "id": "YOUR_INSTAGRAM_ACCOUNT_ID" }]
  }'
curl -X POST "https://mvp2.tryunsora.com/api/v1/posts" \
  -H "Authorization: Bearer uns_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "3 outfits for the long weekend",
    "media": {
      "type": "slideshow",
      "urls": [
        "https://cdn.example.com/look-1.jpg",
        "https://cdn.example.com/look-2.jpg",
        "https://cdn.example.com/look-3.jpg"
      ]
    },
    "accounts": [{ "id": "YOUR_TIKTOK_ACCOUNT_ID" }],
    "tiktok": {
      "post_mode": "MEDIA_UPLOAD",
      "music_usage_confirmation": true,
      "privacy_level": "SELF_ONLY"
    },
    "external_id": "tiktok-draft-001"
  }'
{
  "success": true,
  "data": {
    "id": "<string>",
    "caption": "<string>",
    "scheduled_at": "2023-11-07T05:31:56Z",
    "accounts": [
      "<string>"
    ]
  },
  "message": "<string>"
}
{
"success": true,
"data": {
"id": "<string>",
"caption": "<string>",
"scheduled_at": "2023-11-07T05:31:56Z",
"accounts": [
"<string>"
]
},
"message": "<string>"
}
{
"error": "<string>",
"success": true,
"code": "<string>",
"message": "<string>"
}
{
"error": "<string>",
"success": true,
"code": "<string>",
"message": "<string>"
}
{
"success": false,
"error": "<string>",
"code": "PLAN_REQUIRED"
}
{
"error": "<string>",
"success": true,
"code": "<string>",
"message": "<string>"
}
{
"error": "<string>",
"success": true,
"code": "<string>",
"message": "<string>"
}
Schedule a post for later or save it as a draft. Publishing runs through Unsora when the post is published from the scheduler.

Supported content

media.typeUse forResponse type
videoInstagram Reel, TikTok Reelvideo
slideshowInstagram carousel, TikTok photo postslideshow
Connect Instagram and TikTok via Get accounts.

Before you post

  1. Active paid plan + API key or Clerk JWT.
  2. Get accounts → copy each account id.
  3. Pick video or slideshow. For Instagram reels, optional cover_url.

Request body

caption
string
required
Post caption. Legacy alias: mainCaption.
accounts
array
required
[{ "id": "<account-uuid>" }] — up to 10 accounts.
media
object | null
settings
object
Optional publish options for Instagram and TikTok only (not Facebook, YouTube, etc.). You can also send instagram or tiktok at the top level of the body (same shape as below). Other keys under settings return 400.
scheduled_at
string
ISO 8601 with timezone, ≥ 2 minutes ahead. Omit for draft.
external_id
string
Idempotency key (max 128 chars) or use Idempotency-Key header.

Instagram reel cover

Only cover_url — a public image URL:
"media": {
  "type": "video",
  "url": "https://cdn.example.com/reel.mp4",
  "cover_url": "https://cdn.example.com/cover.jpg"
}
TikTok reel cover frame: optional settings.tiktok.video_cover_timestamp_ms.

Platform settings (optional)

Supported providers: Instagram, TikTok — only settings.instagram and settings.tiktok (or top-level instagram / tiktok). Nothing is required; omit settings if you do not need them.
Top-level tiktok / instagram keys work the same as settings.tiktok / settings.instagram.
"settings": {
  "instagram": { "cover_url": "https://cdn.example.com/cover.jpg" },
  "tiktok": {
    "post_mode": "MEDIA_UPLOAD",
    "privacy_level": "SELF_ONLY",
    "music_usage_confirmation": true
  }
}

Response

{
  "success": true,
  "message": "Post saved as draft",
  "data": {
    "id": "cm123abc",
    "status": "draft",
    "type": "video",
    "caption": "Behind the scenes",
    "scheduled_at": null,
    "accounts": ["acc_instagram"]
  }
}

Examples

curl -X POST "https://mvp2.tryunsora.com/api/v1/posts" \
  -H "Authorization: Bearer uns_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "Behind the scenes",
    "media": {
      "type": "video",
      "url": "https://cdn.example.com/reel.mp4",
      "cover_url": "https://cdn.example.com/cover.jpg"
    },
    "accounts": [{ "id": "YOUR_INSTAGRAM_ACCOUNT_ID" }]
  }'
curl -X POST "https://mvp2.tryunsora.com/api/v1/posts" \
  -H "Authorization: Bearer uns_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "Quick tip",
    "media": {
      "type": "video",
      "url": "https://cdn.example.com/tip.mp4"
    },
    "accounts": [{ "id": "YOUR_TIKTOK_ACCOUNT_ID" }]
  }'
curl -X POST "https://mvp2.tryunsora.com/api/v1/posts" \
  -H "Authorization: Bearer uns_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "3 looks for the weekend",
    "media": {
      "type": "slideshow",
      "urls": [
        "https://cdn.example.com/1.jpg",
        "https://cdn.example.com/2.jpg"
      ]
    },
    "accounts": [{ "id": "YOUR_INSTAGRAM_ACCOUNT_ID" }]
  }'
curl -X POST "https://mvp2.tryunsora.com/api/v1/posts" \
  -H "Authorization: Bearer uns_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "3 outfits for the long weekend",
    "media": {
      "type": "slideshow",
      "urls": [
        "https://cdn.example.com/look-1.jpg",
        "https://cdn.example.com/look-2.jpg",
        "https://cdn.example.com/look-3.jpg"
      ]
    },
    "accounts": [{ "id": "YOUR_TIKTOK_ACCOUNT_ID" }],
    "tiktok": {
      "post_mode": "MEDIA_UPLOAD",
      "music_usage_confirmation": true,
      "privacy_level": "SELF_ONLY"
    },
    "external_id": "tiktok-draft-001"
  }'

Errors

HTTPWhen
400Validation failed
401Invalid auth
403No paid plan or unknown account
404User not found
409Idempotency conflict
500Server error

Authorizations

Authorization
string
header
required

Clerk session JWT or Unsora API key (uns_live_*)

Headers

Idempotency-Key
string

Optional. Replays the original response for 24h when using an API key. Same as body external_id.

Maximum string length: 128

Body

application/json
accounts
object[]
required
Required array length: 1 - 10 elements
caption
string

Post caption shown on connected platforms

mainCaption
string

Legacy alias for caption

media
object

video, slideshow, or null for text-only drafts. Legacy: array of {type, url} items.

scheduled_at
string<date-time>

ISO 8601 with timezone. At least 2 minutes ahead. Omit for draft.

scheduledFor
string<date-time>

Legacy alias for scheduled_at

timezone
string

IANA timezone label stored with the post

external_id
string

Idempotency key (alias for Idempotency-Key header on API key requests)

Maximum string length: 128
settings
object

Optional Instagram and TikTok publish options only. Same fields may be sent at the top level as instagram or tiktok.

instagram
object

Optional alias for settings.instagram

tiktok
object

Optional alias for settings.tiktok

Response

Idempotent replay of an earlier create

success
boolean
required
data
object
required
message
string
required