Every platform has its own knobs — Instagram’s REEL vs FEED, X’s
replySettings, TikTok’s privacy and consent flags, YouTube’s
madeForKids, LinkedIn’s PDF carousels. Postbreeze exposes these
through a single field on each platform target:
platformOptions is a discriminated union — the platform field
picks which shape applies. Pass only the fields you want to override;
everything else falls back to a sensible default.
These live next to platformOptions, not inside it. They apply to
any platform that supports them.
The full Zod schema lives in
packages/shared/src/index.ts.
This page is the human-readable copy.
Instagram
Constraints
- 📐 Feed posts require aspect ratio between 4:5 (0.8) and 1.91:1.
- 📱 Reels must be a single 9:16 video, 3–90 seconds.
- 🎠 Feed carousels support up to 10 media items.
- 🚫 Stories are not supported in v1 — they’re rejected at validation.
- 🚫 Mixing image + video in one Feed post is rejected by the API.
- 💬
firstComment is supported on Feed posts and Reels (not stories — and stories don’t ship in v1 anyway).
Facebook
Constraints
- 🚫 Cannot mix videos and images in the same post.
- ✅ Up to 10 images for Feed photo carousels.
- 🎬 Reels must be 9:16, between 3 and 90 seconds.
- 📊 Reels are capped at 30 publishes per Page per 24h by Meta.
- 🔗 Use
link (with kind: "FEED") for OG-card link previews.
- 💬
firstComment is supported on every surface except Reels.
Constraints
- 🖼️ Up to 4 images or 1 video per tweet — never a mix.
- 🧵
threadParts adds up to 25 tweets after the root. Each entry inherits no media; only the root tweet carries the post’s mediaItems.
- 💬
firstComment is published as a reply to the root tweet, not the last thread part.
- 🌍 Tweet text is always globally visible — X doesn’t expose geo-restriction on text.
LinkedIn (Personal)
Constraints
- 🖼️ Up to 20 images per post.
- 🚫 Multi-video posts are not supported.
- 📄 Single PDF document posts supported — upload the PDF and attach with
type: "document". See Media uploads → LinkedIn PDFs.
- 🔗 Link previews are auto-generated when no media is attached.
LinkedIn (Company)
Same shape as LinkedIn Personal, with the discriminator
platform: "LINKEDIN_COMPANY". Use for organization pages the
connected user administers.
Constraints
- 🏢 One
SocialAccount per administered organization. Use the
per-org accountId to fan out to multiple pages.
- 📊 Org-page analytics require LinkedIn Marketing Developer Platform
approval — until that lands, the analytics surface shows an
“approval pending” banner. Posting still works.
TikTok (Personal)
Required by TikTok. privacy has no default — you must pass
one of the four values below. Branded-content (brandContentToggle: true) is only allowed with privacy: "PUBLIC_TO_EVERYONE".
Constraints
- 🎬 Videos publish via
PULL_FROM_URL; the host of the media URL must be on TikTok’s verified-domain list (your R2 public bucket).
- 📸 Photo carousels support up to 35 images.
- 📝 Video captions: up to 2,200 characters. Photo titles capped at 90 characters — use
content for longer descriptions.
- 🔒 While the app is in TikTok Sandbox,
privacy is forced to "SELF_ONLY" regardless of what you pass — that’s a TikTok constraint until App Review lands.
- 🤝 Branded content cannot be
SELF_ONLY, MUTUAL_FOLLOW_FRIENDS, or FOLLOWER_OF_CREATOR. Validation rejects the combination pre-flight.
TikTok (Business)
Same shape as TikTok Personal, with the discriminator
platform: "TIKTOK_BUSINESS". Use for accounts authenticated through
TikTok for Business.
The reserved TIKTOK_BUSINESS slot exists for accounts that grant
the Business OAuth flow; the publish shape and validation rules are
identical to Personal.
YouTube
Constraints
- 🎬 YouTube targets accept a single video, no images.
- ⏱️ Videos ≤ 3 minutes in 9:16 are automatically published as YouTube Shorts; longer videos publish as regular videos. Postbreeze doesn’t override this — it’s YouTube’s classification.
- 🖼️ Custom thumbnails work for regular videos only (not Shorts).
- 💬
firstComment is supported and posted as a top-level comment after upload completes.
- 🚫 Tags, category overrides, AI-disclosure flag (
containsSyntheticMedia) are not exposed in v1 — defaults are applied server-side (categoryId: "22" “People & Blogs”).
Pinterest
Constraints
- 📌 Every pin requires a
board. There is no default board fallback in v1.
- 🖼️ Pinterest carousels accept up to 5 images.
- 🚫 Video pins are not supported in v1.
- 🔗
link becomes the pin’s destination — leave it unset for image-only inspiration pins.
Threads
Constraints
- 📝 Each post (root + every follow-up) is capped at 500 characters — Threads has no “See more” fold. The publisher rejects pre-flight if any part is over.
- 🧵
threadParts adds up to 25 follow-ups after the root. Each follow-up is text-only; only the root post carries the attached mediaItems.
- 🎠 Carousels accept 2–20 mixed items (images and videos) on the root post.
- 🎬 Videos up to 5 minutes / 1 GB.
- 📊 Posting limits: 250 published posts / 24h, 1,000 replies / 24h. Each follow-up counts toward the reply quota.
- 💬
firstComment is posted as a reply to the root post, not the last thread part.
One post fanned out to four platforms, each with its own
platformOptions, per-target caption override, and first-comment:
Defaults that kick in if you omit platformOptions
- Instagram →
kind: "FEED"
- Facebook →
kind: "FEED"
- X →
replySettings: "everyone"
- LinkedIn (Personal/Company) →
visibility: "PUBLIC"
- YouTube →
visibility: "PUBLIC", madeForKids: false
- Threads →
kind derived from media
The exceptions are TikTok (privacy has no default) and
Pinterest (board has no default) — those two targets require
platformOptions with at least the required field, or the post is
rejected at validation.