Post Reels via API to Instagram and TikTok
Reels are short-form vertical videos. OmniSocials supports reels on Instagram, Facebook, YouTube (as Shorts), and TikTok. Telegram and Discord have no reels: to share a video there, use type: "post". A reel that names telegram or discord is still accepted, and they get the video as a normal post with the reel text. A single POST /posts/create call with type: "reel" can fan out a reel to all four platforms at once.
Supported channels
| Channel ID | Platform | Format | Max duration |
|---|---|---|---|
instagram | Instagram Reels | Vertical 9:16 | 15 minutes |
facebook | Facebook Reels | Vertical 9:16 | 240 minutes |
youtube | YouTube Shorts | Vertical 9:16 | 3 minutes |
tiktok | TikTok | Vertical 9:16 or 16:9 | 10 minutes |
Calling with type: "reel" and a channel that does not support reels (LinkedIn, X, Pinterest, etc.) returns 400.
Minimal example
Terminal
Reels always require a single video file. Image-only or multi-video reel requests return 400.
Cross-posting a reel across all four platforms
Include every channel ID in accounts and use per-platform options for each platform's specific requirements.
JSON
Every platform-specific key only applies to its own channel. Instagram ignores the youtube and tiktok blocks. YouTube ignores the instagram and tiktok blocks. And so on.
Platform-specific options
Each reel-capable platform has its own set of options. Pass them under the matching channel ID key.
Instagram reel options
| Field | Type | Description |
|---|---|---|
instagram.share_to_feed | boolean | Also show the reel on the profile feed grid |
instagram.thumbnail_type | string | from-video or from-library |
instagram.thumb_offset | number | Timestamp in milliseconds, used when thumbnail_type is from-video |
instagram.cover_url | string | URL of a custom cover image, used when thumbnail_type is from-library |
instagram.audio_id | string | Licensed music track to attach, from GET /audio/search |
instagram.audio_volume | integer | Music volume 0–100 (default 100). Only used with audio_id. |
instagram.video_volume | integer | Volume of the video's own audio 0–100 (default 100). Set 0 for a music-only reel. |
instagram.is_trial_reel | boolean | Publish as a Trial Reel: shown to non-followers first to test performance. Not available on every account. |
instagram.trial_graduation_strategy | string | MANUAL (default) or SS_PERFORMANCE. How a Trial Reel graduates to all followers. Only used with is_trial_reel. |
Instagram Trial Reels
A Trial Reel is shown to non-followers first so you can test how content performs before (optionally) sharing it with your followers. Set instagram.is_trial_reel: true on a reel to publish it as a trial:
JSON
trial_graduation_strategy controls how the trial graduates to all your followers:
MANUAL(default): you decide when (or whether) to share it with followers, from the Instagram app.SS_PERFORMANCE: Instagram automatically shares it with your followers if it performs well.
GET /posts/{id} echoes both fields back under instagram, so you can verify a batch of scheduled Trial Reels programmatically.
Eligibility: Trial Reels are not available on every account. Instagram requires roughly 1,000+ followers and enables the feature per account; you can check eligibility by creating a reel in the Instagram app and looking for the "Trial" toggle. Ineligible accounts fail at publish time with a clear per-platform error on the post's errors map.
Instagram reel music
Search Meta's licensed catalog with GET /audio/search?q=... (omit q for currently trending audio; add type=original_sound to search original sounds instead of licensed music). Pass the chosen result's audio_id as instagram.audio_id and mix levels with audio_volume / video_volume:
JSON
Notes:
- Reels only. Meta's API does not support adding music to feed posts, carousels, or Stories; that remains app-only.
- Only tracks Meta has licensed for third-party publishing appear in search results, so the selection can differ from the native app.
- Requires a Facebook account connected to the workspace whose Facebook Page is linked to the same Instagram account (music publishing runs through Facebook's side of the Instagram API). If it isn't,
GET /audio/searchreturnsneedsFacebook: trueand publishing a reel withaudio_idfails with a clear error before anything goes live.
YouTube Shorts options
| Field | Type | Description |
|---|---|---|
youtube.title | string | Video title, max 100 characters. When omitted: the first line of the caption, else "YouTube Short". |
youtube.tags | array | Discovery tags. Max 500 characters total. |
youtube.privacy_status | string | public, private, or unlisted |
youtube.category_id | string | YouTube category. Defaults to "22" (People & Blogs). |
youtube.made_for_kids | boolean | COPPA disclosure. Disables comments and interactions when true. |
youtube.notify_subscribers | boolean | Send the subscriber notification when published |
youtube.contains_synthetic_media | boolean | Disclose AI-generated content |
TikTok options
| Field | Type | Description |
|---|---|---|
tiktok.privacy_level | string | PUBLIC_TO_EVERYONE (default), MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY |
tiktok.disable_comment | boolean | Disable comments on the reel |
tiktok.disable_duet | boolean | Disable duets |
tiktok.disable_stitch | boolean | Disable stitches |
tiktok.video_cover_timestamp_ms | integer | Timestamp (ms) of the frame to use as the cover |
tiktok.is_aigc | boolean | Disclose AI-generated content |
tiktok.brand_content_toggle | boolean | Mark as a paid partnership promoting a third-party brand |
tiktok.brand_organic_toggle | boolean | Mark as promoting your own business / brand |
privacy_level defaults to PUBLIC_TO_EVERYONE. When the creator's account does not allow the chosen level, the video is published as SELF_ONLY (private).
Facebook Reels
Facebook has no specific reel option fields. The default reel body works.
Different video per platform
Sometimes you want a slightly different cut for each platform (e.g. a shorter version for YouTube Shorts where the limit is 3 minutes, and a longer cut for TikTok where the limit is 10 minutes). Use the per-platform media_urls shape:
JSON
Media requirements
| Platform | Format | Aspect | Duration | File size |
|---|---|---|---|---|
| MP4 | 9:16 | Up to 15 minutes | Up to 300 MB | |
| MP4 | 9:16 | Up to 240 minutes | Up to 1 GB | |
| YouTube Shorts | MP4 | 9:16 | Up to 3 minutes | Up to 1 GB (the OmniSocials upload limit) |
| TikTok | MP4 or MOV | 9:16 or 16:9 | 3 seconds to 10 minutes (the creator's own TikTok limit: 3, 5 or 10 minutes) | Up to 1 GB (the OmniSocials upload limit) |
Videos outside these constraints are rejected at publish time. OmniSocials does not transcode, trim, or re-encode.
The safest format for cross-platform reels: MP4, H.264 codec, 1080 × 1920 vertical, under 3 minutes (YouTube Shorts is the tightest), under 300 MB (Instagram is the tightest). That passes every platform's requirements.
Thumbnails and cover images
The simplest way to set a cover is the top-level video_cover object, which works for every platform in one place (see Video covers):
JSON
Per platform:
- Instagram: default is the first frame.
video_coverapplies, or override withinstagram.thumb_offset(pick a video frame) orinstagram.cover_url(supply a custom image). - Facebook: default is the first frame.
video_coverapplies, or usefacebook.thumbnail_typewiththumb_offsetorcover_url. The thumbnail is set after the reel is live; if Facebook refuses it, the reel still publishes with the default frame. - YouTube Shorts:
video_coverapplies (a custom image or a video frame, sent withthumbnails.setat up to 1080 x 1920), but YouTube shows it on Shorts only on channels where it has enabled custom Shorts thumbnails (rolling out since July 2026, YouTube Partner Program channels first). On other channels YouTube stores the cover but displays a frame from the video on the Shorts tab and in the Shorts feed; there the thumbnail can only be changed by picking a frame in the YouTube app. Channels that are not verified cannot set custom thumbnails at all. - TikTok: frame only. TikTok's API takes a timestamp, not an image, so a
customcover is skipped and the frame fromvideo_cover(ortiktok.video_cover_timestamp_ms) is used. Setvideo_cover.overrides.tiktokto{ "type": "frame", "thumb_offset": 2000 }to pick a different frame for TikTok when the other platforms get an image.
Scheduling reels
Reels are schedulable the same way as feed posts. Add schedule_at (ISO 8601 UTC).
JSON
Limitations
- Reels must have exactly one video. Multi-video or image reels are rejected.
type: "reel"is rejected on platforms that do not support reels. Mixing reel-capable and non-reel-capable channels in the sameaccountsarray returns400.- TikTok branded-content reels (
brand_content_toggle: true) go through TikTok's review workflow and may take longer to publish.
Related reading
- Creating Posts for the full field reference
- Cross-Posting for the one-request-many-platforms model
- Creating Stories for the ephemeral story workflow
- Instagram, TikTok, YouTube for full per-platform specs