tebarDocs
GuideDevelopersAPI ReferenceChangelog

Posts

Creating, scheduling, changing, and canceling posts.

Create a post

POST /v1/posts
Authorization: Bearer tb_live_xxx
Idempotency-Key: 6f1c2b7e-0d8a-4f7e-9a51-2c1f7b0e9d34
Content-Type: application/json

{
  "content": "Weekend promo 🎉",
  "media_ids": ["0b9d..."],
  "targets": [{ "account_id": "a1.." }, { "account_id": "b2.." }],
  "scheduled_at": "2026-10-15T09:00:00+07:00"
}
FieldDescription
contentThe post text
media_idsMedia ids from an upload, in display order
media_urlsOptional. Public URLs of photos or videos; Tebar downloads them first (same rules as POST /v1/media/from-url) and adds them after media_ids. Up to 20 with media_ids. A failed download makes no post (400 media_download_failed)
targetsTarget accounts (account_id from GET /v1/accounts)
scheduled_atOptional. Without it, the post is published right away

201 response:

{
  "id": "p1..",
  "status": "scheduled",
  "scheduled_at": "2026-10-15T02:00:00Z",
  "targets": [
    {
      "id": "t1..",
      "account_id": "a1..",
      "platform": "instagram",
      "status": "pending",
      "permalink": null
    },
    {
      "id": "t2..",
      "account_id": "b2..",
      "platform": "threads",
      "status": "pending",
      "permalink": null
    }
  ]
}

Publishing runs in the background. Check GET /v1/posts/{id}: each target becomes published with a permalink, or failed with an error_code.

A single video on Instagram publishes as a Reel automatically. Two or more media items become a carousel (Instagram up to 10, Threads up to 20).

A version per account

Each target can have its own text and/or media (media_ids and/or media_urls). Fields not sent follow the shared version. content: "" means deliberately without text.

{
  "content": "What's your favorite coffee?",
  "targets": [
    { "account_id": "th..", "options": { "poll": { "options": ["Black", "Latte"] } } },
    { "account_id": "ig..", "content": "New on the menu this week ☕", "media_ids": ["m1.."] }
  ]
}

Threads threads

content is the first post. Each item of options.thread goes out as the next reply, in order (up to 10 follow-up parts). A part is text, or { "text", "media_ids" } / { "text", "media_url" } with 1 photo or video (media_url is downloaded by Tebar like media_urls). If publishing fails partway, a retry continues from the next part without reposting the ones already out. Needs the threads_manage_replies permission (see the table below).

{
  "content": "5 tips for iced latte at home 🧵",
  "targets": [
    {
      "account_id": "th..",
      "options": {
        "thread": [
          "1. Start with a strong espresso.",
          { "text": "2. Cold milk, not hot.", "media_ids": ["m1.."] },
          { "media_url": "https://example.com/latte.mp4" }
        ]
      }
    }
  ],
  "scheduled_at": "2026-10-31T19:30:00+07:00"
}

Options per platform

Sent in targets[].options. Unknown keys are refused (400 invalid_options).

PlatformOptionRules
Threadsthread: (string | { text?, media_ids? })[]Needs the threads_manage_replies permission (accounts connected before Oct 24, 2026: reconnect); without it 400 option_permission_missing. Thread: 1–10 follow-up parts. Each part is text (≤ 500 characters) or { "text": "…", "media_ids": ["…"] } with 1 photo or video. Errors in a specific part include details.thread_part (2 = the first part after the main post)
Threadspoll: { options: string[] }2–4 options, 1–25 characters. Only posts without media
Threadslink_attachment: urlLink card. Only posts without media
Threadstext_attachment: { text, link_url? }Long text ≤ 10,000 characters. Only posts without media
Threadstopic_tag: string1–50 characters, without . and &
Threadsreply_controleveryone, accounts_you_follow, mentioned_only, followers_only, parent_post_author_only. Anything but everyone (Threads' default, not sent) needs threads_manage_replies
Instagramformat: "feed" | "story"Story: exactly 1 media item, no caption, videos 3–60 seconds and ≤ 100 MB
Instagramshare_to_feed: booleanReels only (default true)
Instagramcover_media_id / thumb_offset_msReel cover: an image id, or a video frame in milliseconds
TikTokprivacy_levelBusiness accounts (video_public_only in GET /v1/accounts/{id}/tiktok/creator-info): optional; videos are always PUBLIC_TO_EVERYONE (anything else is 400 tiktok_privacy_unavailable), photos without a privacy go out public. Other accounts: required for direct posts, one of the privacy_level_options, chosen by the user (without it 400 tiktok_privacy_required)
TikTokpost_mode: "direct" | "draft"draft: sent to the TikTok app's inbox to be finished there
TikTokallow_comment, allow_duet, allow_stitchBusiness accounts: allowed by default, false turns off. Other accounts: default false. Duet and Stitch are video only. Anything the creator turned off in TikTok stays off
TikTokcommercial: { your_brand, branded_content }Commercial content disclosure (at least one true)
TikTokvideo_cover_timestamp_ms, is_aigcThe video's cover frame in milliseconds; mark AI-generated content. Business accounts also take cover_media_id: a JPG/PNG image id (360-1920 px, short side up to 1080 px, 20 MB) as the cover
TikTokphoto_title, auto_add_musicPhotos only. A TikTok post holds 1 video or 1–35 photos (400 invalid_media_mix)
YouTubetitle, made_for_kidsBoth required. title 1-100 characters without < or >; always ask the user for made_for_kids. The post text is the description (up to 5,000, no < or >)
YouTubeprivacy: "public" | "unlisted" | "private", tags, category_idDefault public. tags up to 500 characters in total
YouTubecontains_synthetic_media, notify_subscribersMark realistic AI or altered content; notify_subscribers: false skips notifying subscribers
YouTubecover_media_idId of a JPG or PNG from the media library as the thumbnail, set once the video is up. Not for Shorts. The channel must be phone-verified (youtube.com/verify); when YouTube refuses, the video stays up with its automatic thumbnail
LinkedInvisibility: "PUBLIC" | "CONNECTIONS"PUBLIC (default): everyone on LinkedIn. CONNECTIONS: connections only
Telegramsilent, protect_contentNo notification sound; the post cannot be forwarded or saved. Default false
Telegramno_link_previewLinks in the text without a preview card. Only posts without media
Pinterestboard_id, title, linkboard_id required, from GET /v1/accounts/{id}/pinterest/boards (no board: 400 pinterest_board_required). title up to 100 characters, link the destination URL. The post text is the description (up to 800). Exactly 1 photo
Discordsilent, no_link_previewNo push notification to members; links in the text without a preview card. Default false. Mentions such as @everyone are always sent without pinging anyone
LinkedInlink: urlArticle card. Only posts without media

Threads allows 5 unique links per post (400 too_many_links).

Managing posts

RequestWhat it does
PATCH /v1/posts/{id}Change content, media_ids, scheduled_at, or each account’s version and options (targets[]) of a post not published yet
DELETE /v1/posts/{id}Cancel a scheduled post
POST /v1/posts/{id}/retryRetry the failed accounts. Never reposts the ones already published
POST /v1/posts/{id}/removeRemove from Tebar's history. The post on Instagram/Threads/TikTok is not deleted

A post that has started publishing cannot be changed (409 post_not_editable). To publish a scheduled post now, send PATCH with scheduled_at set to the current time.

To change one account's version or options in a scheduled post, send targets with accounts already in the post. A field sent replaces that account's (options as a whole, so send again the other options you want to keep); content or media_ids set to null make the account follow the shared version again. Accounts cannot be added or removed (400 account_not_in_post).

{
  "targets": [
    { "account_id": "th..", "options": { "thread": ["The new part 2"], "topic_tag": "coffee" } },
    { "account_id": "ig..", "content": null, "media_ids": null }
  ]
}

On this page