Skip to main content
Postbreeze ships first-party publishers for the platforms below. Every platform shares the same scheduling API (POST /api/v1/posts) — what changes is the per-platform options blob you pass on each target.

Instagram

Feed, Reels, carousels. Business + Creator accounts only.

Facebook

Feed, Photo, Photo Carousel, Video, Reels. Page accounts only.

TikTok

Video uploads + photo carousels with branded-content disclosure.

X (Twitter)

Tweets, threads (up to 25), replies. Pay-Per-Use billing.

LinkedIn

Personal + Company pages. Photo gallery + PDF carousel.

YouTube

Long-form + Shorts. First-comment via Community surface.

Pinterest

Single + carousel pins. Board, title, link per pin.

Threads

Text, image, video, mixed-media carousels (up to 20 items).

Capability matrix

PlatformPost typesFirst commentCarouselAlt textAnalytics
InstagramFeed, Reel2–10 (mixed)❌ Not in API
FacebookFeed, Photo, Carousel, Video, Reel2–10 (photo only)❌ Not in API
TikTokVideo, Photo Carousel❌ Not in API1–35 (photo only)❌ Not in API
XTweet, Thread, Reply1–4 (photos only)
LinkedInPersonal, Company, PDF Carousel2–20 (photo or PDF)⚠️ MDP required
YouTubeVideo upload
PinterestPin, Carousel pin❌ Not in API2–5 (photo only)
ThreadsText, Image, Video, Carousel2–20 (mixed)

The single API surface

Every platform reaches the same endpoint with the same payload shape. Workspace is inferred from the API key — you don’t pass it.
POST /api/v1/posts
There are two accepted body shapes. Use the flat shape for the common case (same caption to N platforms with shared media); use the nested shape when you need fine-grained per-target overrides like custom platform options.
{
  "content": "Shared caption — applied to every platform",
  "scheduledFor": "2026-06-01T12:00:00Z",
  "mediaItems": [
    { "type": "IMAGE", "url": "https://cdn.example.com/hero.jpg", "altText": "Hero" }
  ],
  "platforms": [
    {
      "accountId": "soc_ig_…",
      "captionOverride": "Optional per-platform caption",
      "firstComment": "Optional follow-up reply"
    },
    { "accountId": "soc_x_…" }
  ]
}
Provide exactly one of platforms or targets — sending both returns 400 MUST_SPECIFY_EXACTLY_ONE.
Workspace inference. API keys are bound to a single workspace at creation. SDK and REST callers don’t pass workspaceId — the server reads it from the bearer credential. Create separate keys for separate brands.
See the API reference for the full schema, or pick a platform on the left for the per-platform options you’d pass.

A note on media

Three precedence rules apply for what media a target actually publishes:
  1. If the target has its own non-empty mediaIds → use those.
  2. Otherwise → use the post-level mediaIds (after URL ingest).
  3. If both are empty → text-only post (only some platforms accept this — Threads ✅, X ✅, Facebook ✅, LinkedIn ✅; the others reject).
This lets you publish the same post to 5 platforms with one shared media list, then override just the TikTok target with a portrait video while everyone else gets the landscape one.

Provider behavior + retry policy

Postbreeze wraps every publish in a Temporal workflow that retries up to 5 attempts with exponential backoff (initial 10s, max 15 min, coefficient 2). Non-retryable validation errors (e.g. caption too long) terminate immediately and surface as PostStatus.FAILED. Network blips, rate limits, and provider 5xx’s get retried automatically. The full retry timeline:
  • Attempt 1: immediate
  • Attempt 2: ~10s later
  • Attempt 3: ~30s later
  • Attempt 4: ~5 min later
  • Attempt 5: ~15 min later
Beyond that, the post target stays in FAILED and you can retry manually via POST /api/v1/posts/:id/retry.

See also