Posts
Create, schedule, update, publish, and delete social media posts across every connected channel — the core of the OmniSocials API.
List the user's recent posts fetched live from the connected platforms
Returns the most recent posts pulled directly from each connected platform's API (Instagram, TikTok, X, YouTube, Facebook, LinkedIn, and more), including content that was published outside OmniSocials. This is the fallback for brand-new workspaces that have not published anything through OmniSocials yet, so GET /posts (which only lists OmniSocials posts) comes back empty. Each post is enriched with normalized engagement / impressions / engagement_rate so you can rank across platforms without re-deriving per-platform rules. Metrics are only present where the platform exposes them for historical posts: X, TikTok, Bluesky, Mastodon, Instagram (likes/comments/reach/views/saves/shares, via one insights call per post), Facebook, and YouTube return counts, while Threads, Pinterest, and Google Business return captions only (metrics: {}). LinkedIn personal profiles cannot be listed live (LinkedIn grants no such permission to apps), so their results contain posts published through OmniSocials with their latest collected stats; TikTok results are backfilled the same way for photo posts the video list omits. Fetched live on every call, so it is not cached — expect a few seconds of latency across many platforms. Requires the analytics:read scope.
query Parameters
limitMax posts to fetch per connected platform (1-50, default 25).
platformsOptional comma-separated platform filter (e.g. "instagram,tiktok"). Defaults to every connected platform. Unsupported values return 400.
List the user's recent posts fetched live from the connected platforms › Responses
Recent posts across connected platforms, newest first
countconnected_platformserrorsPer-platform error messages for any platform that failed to fetch.
notecurrent_dateUpdate a post
path Parameters
idUpdate a post › Request Body
contentaccountstypeChange post type (draft only)
Media IDs from POST /media/upload. Flat array or per-platform object. Any entry may be an { id, alt } object to carry a per-media accessibility description (alt text, max 1500 chars).
Media IDs from POST /media/upload. Flat array or per-platform object. Any entry may be an { id, alt } object to carry a per-media accessibility description (alt text, max 1500 chars).
External image/video/PDF URLs to download and attach (max 10 total, each file ≤ 100 MB). Flat array or per-platform object. Any entry may be a { url, alt } object to carry a per-media accessibility description (alt text, max 1500 chars) — delivered to Mastodon, Bluesky, X and Pinterest. When using per-platform format, 'default' acts as fallback for selected platforms without their own key. A PDF URL is rasterized into one image slide per page (max 20, in order) — on LinkedIn it publishes as a swipeable document, elsewhere as an image carousel; slides inherit the entry's alt. For files over 100 MB (up to 1 GB), upload first via POST /v1/media/upload-from-url and attach the returned media id via the media field; oversized media_urls fail with code file_too_large.
schedule_atlocation_idInstagram only. Facebook Place/Page ID to tag the post's location with (e.g. a dealership or storefront). Applied to single-image and carousel feed posts via Instagram's content-publishing location_id. Find a Place's Page ID via Facebook's Pages Search API. Ignored by other platforms. Send an empty string on PATCH to clear it.
collaboratorsInstagram only. Up to 3 public Instagram usernames to invite as co-authors (the 'Collab' feature). Applied to image, carousel, and reel posts — NOT Stories. Invited users get an invitation in the Instagram app; once accepted, the post also appears on their profile and feed. Usernames are case-insensitive and a leading '@' is stripped. Private accounts and non-existent usernames are rejected by Instagram at publish time. Ignored by other platforms. Send an empty array on PATCH to clear collaborators.
Instagram only. Tag public Instagram accounts at specific positions on a photo. Photos only — NOT video, reels, or stories. For a single image omit image_index (or set 0); for a carousel, set image_index to the 0-based slide the tag belongs to (tags attach to that slide's image). Public accounts only; private/non-existent usernames are rejected by Instagram at publish time. Ignored by other platforms. Send an empty array on PATCH to clear tags.
Pinterest-specific options. Attach 2–5 images via media_urls.pinterest (or the flat media_urls) to publish a single carousel pin; the title, description, link, and alt_text apply to the whole pin. A single image or a single video still publishes as a normal image / video pin. Carousel constraint: Pinterest's v5 API requires every slide in a carousel pin to share the same aspect ratio (1% tolerance). If you attach mixed-ratio images and try to schedule or publish, the API responds 400 validation_error with mismatched_slides: [n, ...] listing the 1-indexed slide numbers that need to be re-cropped or removed. The check is run when publish_now: true, when schedule_at is set, and when PATCH flips a draft to a scheduled status — drafts are exempt so you can iterate on media.
YouTube Shorts options. Only applies when type is reel and youtube is among the selected accounts.
Instagram Reel options. MERGED into the stored options: keys you omit keep their current value (so updating share_to_feed cannot silently clear a Trial Reel flag or reel music set elsewhere); pass a key explicitly as null to clear it.
TikTok options
X (Twitter) options
Bluesky options
Mastodon options
Update a post › Responses
Post updated
Create a new post
Create a new post. You can attach media by uploading first (media/media_ids) or by passing external URLs (media_urls) which will be downloaded and processed automatically. Both can be combined.
Required media: Instagram and TikTok posts need at least one image/video. Pinterest posts need an image and a board_id. Posts without required media will be rejected with a 400 error.
Per-platform media caps (enforced at submit, not at publish time):
bluesky— max 4 images per postmastodon— max 4 media items per postx— max 4 images per postinstagram— max 10 items in a carouselthreads— max 10 items in a carouseltiktok— max 35 items per photo post; cannot mix photos and videos in one post
Exceeding any cap returns 400 { error: { code: "validation_error", message: "<Platform> allows up to N media items per post. You attached M, please remove M-N." } }. The Pinterest carousel aspect-ratio constraint (2–5 same-ratio images) is enforced the same way; see the Pinterest section for the mismatched_slides response shape.
Per-platform video file-size caps (validated via ffprobe; drafts exempt):
Mastodon 99 MB · Bluesky 100 MB · Instagram 300 MB · X 512 MB (free tier) · Threads / Reddit 1 GB · Pinterest 2 GB · Facebook / TikTok 4 GB · LinkedIn 5 GB · YouTube 256 GB.
Upload requests are capped at 100 MB on top of these — anything bigger is rejected before media processing with code: file_too_large.
Per-platform video duration caps (validated via ffprobe; drafts exempt): Facebook Post 240 min / Reel 90 s · Instagram 15 min (Post + Reel) · TikTok 10 min (Post + Reel) · YouTube Short 3 min · X 140 s · Bluesky 180 s · Threads 5 min · LinkedIn 10 min · Pinterest 15 min · Reddit 15 min · Mastodon (instance-dependent).
Cap violations return 400 { error: { code: "validation_error", message: "<Platform> only allows videos up to <cap> — yours is <duration>. Trim the video or deselect <Platform>." } } (duration) or "This video (<size>) is too large for <Platform>. ..." (size). When multiple platforms reject the same upload, each contributes one sentence to the message. See API_DEVELOPER_GUIDE.md → "Per-Platform Media Limits" and "Per-Platform Video Duration Caps" for the full table with source citations.
Create a new post › Request Body
contentPost content. Use 'default' for all platforms, or platform-specific keys: instagram, facebook, linkedin, linkedin_page, youtube, tiktok, pinterest, x, threads, bluesky, mastodon, google_business. Coming soon: reddit, snapchat.
accountsSocial accounts to post to. Each entry is either:
- A bare platform name (e.g.
"youtube","linkedin_page"), or - The composite ID returned by
GET /v1/accountsin the form"<workspace_id>_<platform>"(e.g."844008_youtube").
The composite form's workspace prefix must match the workspace your API key belongs to. Mismatched or unknown ids return 400 validation_error with an "Unknown account/platform" message — always source ids from GET /v1/accounts for the API key in use.
typePost type: 'post' (feed), 'story' (Instagram/Facebook), 'reel' (Instagram/Facebook/YouTube/TikTok). A 'reel' must have video media (MP4/MOV); an image is rejected with 400 validation_error at schedule/publish — use 'post' to share an image.
Media IDs from POST /media/upload. Flat array or per-platform object. Any entry may be an { id, alt } object to carry a per-media accessibility description (alt text, max 1500 chars).
External image/video/PDF URLs to download and attach (max 10 total, each file ≤ 100 MB). Flat array or per-platform object. Any entry may be a { url, alt } object to carry a per-media accessibility description (alt text, max 1500 chars) — delivered to Mastodon, Bluesky, X and Pinterest. When using per-platform format, 'default' acts as fallback for selected platforms without their own key. A PDF URL is rasterized into one image slide per page (max 20, in order) — on LinkedIn it publishes as a swipeable document, elsewhere as an image carousel; slides inherit the entry's alt. For files over 100 MB (up to 1 GB), upload first via POST /v1/media/upload-from-url and attach the returned media id via the media field; oversized media_urls fail with code file_too_large.
schedule_atISO 8601 datetime to schedule. Omit for draft.
publish_nowSet true to publish immediately
link_urlURL to share as a rich preview card on platforms that support link-share posts (currently LinkedIn and Facebook). When set on a text post, the URL renders as a preview tile with thumbnail / title / description instead of plain text. Ignored on platforms that don't support link shares (Instagram, TikTok, etc.) and on posts that already have media attached — media takes precedence.
link_titleOptional title for the link-share preview. LinkedIn uses this directly when set. Facebook ignores this — it fetches OG metadata server-side. Omit to let LinkedIn auto-fetch the page title.
link_descriptionOptional description for the link-share preview. LinkedIn uses this when set; Facebook auto-fetches the OG description. Omit to defer to OG metadata.
link_thumbnail_urlOptional thumbnail image URL for the preview card. Currently not yet applied to LinkedIn (would require uploading to LinkedIn's image API first); included for forward compatibility.
sourceSelf-reported origin of the integration creating this post. Defaults to 'api' if omitted. Use 'zapier', 'make', 'n8n', etc. to identify your integration.
location_idInstagram only. Facebook Place/Page ID to tag the post's location with (e.g. a dealership or storefront). Applied to single-image and carousel feed posts via Instagram's content-publishing location_id. Find a Place's Page ID via Facebook's Pages Search API. Ignored by other platforms. Send an empty string on PATCH to clear it.
collaboratorsInstagram only. Up to 3 public Instagram usernames to invite as co-authors (the 'Collab' feature). Applied to image, carousel, and reel posts — NOT Stories. Invited users get an invitation in the Instagram app; once accepted, the post also appears on their profile and feed. Usernames are case-insensitive and a leading '@' is stripped. Private accounts and non-existent usernames are rejected by Instagram at publish time. Ignored by other platforms. Send an empty array on PATCH to clear collaborators.
Instagram only. Tag public Instagram accounts at specific positions on a photo. Photos only — NOT video, reels, or stories. For a single image omit image_index (or set 0); for a carousel, set image_index to the 0-based slide the tag belongs to (tags attach to that slide's image). Public accounts only; private/non-existent usernames are rejected by Instagram at publish time. Ignored by other platforms. Send an empty array on PATCH to clear tags.
hashtag_setName of a saved hashtag set (see GET /hashtag-sets) to apply to this post, matched case-insensitively. The set's tags are merged in ONCE at create time — the post stores plain text, so later edits to the set never change this post. Tags already present in a caption are skipped (case-insensitive), and hard platform caps (Instagram 30) are enforced with a 400 hashtag_limit_exceeded before the platform can reject the post. Mutually interchangeable with hashtag_set_id.
hashtag_set_idId of a saved hashtag set to apply. Same behavior as hashtag_set; pass one or the other.
hashtag_placementWhere the set's tags land. caption_append (default) appends them to each target platform's caption after a blank line. first_comment puts them in the auto first comment on comment-capable platforms (Instagram, Facebook, LinkedIn Profile/Page, YouTube) — appended after any first_comment you passed explicitly — and falls back to caption_append on platforms without a comment API. Stories always use captions (first comments are never posted on Stories).
hashtag_platformsOptional subset of the post's selected platforms to apply the set to (e.g. only ["instagram", "tiktok"]). Defaults to all selected platforms.
Pinterest-specific options. Attach 2–5 images via media_urls.pinterest (or the flat media_urls) to publish a single carousel pin; the title, description, link, and alt_text apply to the whole pin. A single image or a single video still publishes as a normal image / video pin. Carousel constraint: Pinterest's v5 API requires every slide in a carousel pin to share the same aspect ratio (1% tolerance). If you attach mixed-ratio images and try to schedule or publish, the API responds 400 validation_error with mismatched_slides: [n, ...] listing the 1-indexed slide numbers that need to be re-cropped or removed. The check is run when publish_now: true, when schedule_at is set, and when PATCH flips a draft to a scheduled status — drafts are exempt so you can iterate on media.
YouTube Shorts options. Only applies when type is reel and youtube is among the selected accounts.
Instagram Reel options
Facebook options
LinkedIn Profile options
LinkedIn Company Page options
TikTok options
X (Twitter) options
Bluesky options
Mastodon options
Google Business Profile options. Use to publish EVENT or OFFER posts in addition to STANDARD, attach a call-to-action button, or both. STANDARD posts can also use this object purely to add a CTA. The shape mirrors Google's LocalPost JSONB exactly; see https://developers.google.com/my-business/reference/rest/v4/accounts.locations.localPosts#LocalPost.
Caption rules (enforced at scheduling — text that violates these returns validation_error 400 before the post is saved):
• No phone numbers in the caption (use a CALL button instead).
• No inline URLs / bare domains / email addresses (use a LEARN_MORE, BOOK, SHOP, SIGN_UP, or ORDER button instead).
• Caption max 1500 characters.
• Media optional (text-only posts allowed). If attached: exactly one JPEG/PNG/WebP image (no video, no carousels).
• The workspace must have a Google Business location selected (Settings → Organisation → Workspaces → Google Business) before scheduling.
Create a new post › Responses
Post created
Create and publish a post immediately
Creates a new post and publishes it right away — no scheduling needed. Equivalent to calling POST /posts/create with publish_now: true. The post will be queued for immediate publishing to all selected platforms.
Create and publish a post immediately › Request Body
contentPost content. Use 'default' for all platforms, or platform-specific keys: instagram, facebook, linkedin, linkedin_page, youtube, tiktok, pinterest, x, threads, bluesky, mastodon, google_business. Coming soon: reddit, snapchat.
accountsSocial accounts to post to. Each entry is either:
- A bare platform name (e.g.
"youtube","linkedin_page"), or - The composite ID returned by
GET /v1/accountsin the form"<workspace_id>_<platform>"(e.g."844008_youtube").
The composite form's workspace prefix must match the workspace your API key belongs to. Mismatched or unknown ids return 400 validation_error with an "Unknown account/platform" message — always source ids from GET /v1/accounts for the API key in use.
typePost type: 'post' (feed), 'story' (Instagram/Facebook), 'reel' (Instagram/Facebook/YouTube/TikTok). A 'reel' must have video media (MP4/MOV); an image is rejected with 400 validation_error at schedule/publish — use 'post' to share an image.
Media IDs from POST /media/upload. Flat array or per-platform object. Any entry may be an { id, alt } object to carry a per-media accessibility description (alt text, max 1500 chars).
External image/video/PDF URLs to download and attach (max 10 total, each file ≤ 100 MB). Flat array or per-platform object. Any entry may be a { url, alt } object to carry a per-media accessibility description (alt text, max 1500 chars) — delivered to Mastodon, Bluesky, X and Pinterest. When using per-platform format, 'default' acts as fallback for selected platforms without their own key. A PDF URL is rasterized into one image slide per page (max 20, in order) — on LinkedIn it publishes as a swipeable document, elsewhere as an image carousel; slides inherit the entry's alt. For files over 100 MB (up to 1 GB), upload first via POST /v1/media/upload-from-url and attach the returned media id via the media field; oversized media_urls fail with code file_too_large.
schedule_atISO 8601 datetime to schedule. Omit for draft.
publish_nowSet true to publish immediately
link_urlURL to share as a rich preview card on platforms that support link-share posts (currently LinkedIn and Facebook). When set on a text post, the URL renders as a preview tile with thumbnail / title / description instead of plain text. Ignored on platforms that don't support link shares (Instagram, TikTok, etc.) and on posts that already have media attached — media takes precedence.
link_titleOptional title for the link-share preview. LinkedIn uses this directly when set. Facebook ignores this — it fetches OG metadata server-side. Omit to let LinkedIn auto-fetch the page title.
link_descriptionOptional description for the link-share preview. LinkedIn uses this when set; Facebook auto-fetches the OG description. Omit to defer to OG metadata.
link_thumbnail_urlOptional thumbnail image URL for the preview card. Currently not yet applied to LinkedIn (would require uploading to LinkedIn's image API first); included for forward compatibility.
sourceSelf-reported origin of the integration creating this post. Defaults to 'api' if omitted. Use 'zapier', 'make', 'n8n', etc. to identify your integration.
location_idInstagram only. Facebook Place/Page ID to tag the post's location with (e.g. a dealership or storefront). Applied to single-image and carousel feed posts via Instagram's content-publishing location_id. Find a Place's Page ID via Facebook's Pages Search API. Ignored by other platforms. Send an empty string on PATCH to clear it.
collaboratorsInstagram only. Up to 3 public Instagram usernames to invite as co-authors (the 'Collab' feature). Applied to image, carousel, and reel posts — NOT Stories. Invited users get an invitation in the Instagram app; once accepted, the post also appears on their profile and feed. Usernames are case-insensitive and a leading '@' is stripped. Private accounts and non-existent usernames are rejected by Instagram at publish time. Ignored by other platforms. Send an empty array on PATCH to clear collaborators.
Instagram only. Tag public Instagram accounts at specific positions on a photo. Photos only — NOT video, reels, or stories. For a single image omit image_index (or set 0); for a carousel, set image_index to the 0-based slide the tag belongs to (tags attach to that slide's image). Public accounts only; private/non-existent usernames are rejected by Instagram at publish time. Ignored by other platforms. Send an empty array on PATCH to clear tags.
hashtag_setName of a saved hashtag set (see GET /hashtag-sets) to apply to this post, matched case-insensitively. The set's tags are merged in ONCE at create time — the post stores plain text, so later edits to the set never change this post. Tags already present in a caption are skipped (case-insensitive), and hard platform caps (Instagram 30) are enforced with a 400 hashtag_limit_exceeded before the platform can reject the post. Mutually interchangeable with hashtag_set_id.
hashtag_set_idId of a saved hashtag set to apply. Same behavior as hashtag_set; pass one or the other.
hashtag_placementWhere the set's tags land. caption_append (default) appends them to each target platform's caption after a blank line. first_comment puts them in the auto first comment on comment-capable platforms (Instagram, Facebook, LinkedIn Profile/Page, YouTube) — appended after any first_comment you passed explicitly — and falls back to caption_append on platforms without a comment API. Stories always use captions (first comments are never posted on Stories).
hashtag_platformsOptional subset of the post's selected platforms to apply the set to (e.g. only ["instagram", "tiktok"]). Defaults to all selected platforms.
Pinterest-specific options. Attach 2–5 images via media_urls.pinterest (or the flat media_urls) to publish a single carousel pin; the title, description, link, and alt_text apply to the whole pin. A single image or a single video still publishes as a normal image / video pin. Carousel constraint: Pinterest's v5 API requires every slide in a carousel pin to share the same aspect ratio (1% tolerance). If you attach mixed-ratio images and try to schedule or publish, the API responds 400 validation_error with mismatched_slides: [n, ...] listing the 1-indexed slide numbers that need to be re-cropped or removed. The check is run when publish_now: true, when schedule_at is set, and when PATCH flips a draft to a scheduled status — drafts are exempt so you can iterate on media.
YouTube Shorts options. Only applies when type is reel and youtube is among the selected accounts.
Instagram Reel options
Facebook options
LinkedIn Profile options
LinkedIn Company Page options
TikTok options
X (Twitter) options
Bluesky options
Mastodon options
Google Business Profile options. Use to publish EVENT or OFFER posts in addition to STANDARD, attach a call-to-action button, or both. STANDARD posts can also use this object purely to add a CTA. The shape mirrors Google's LocalPost JSONB exactly; see https://developers.google.com/my-business/reference/rest/v4/accounts.locations.localPosts#LocalPost.
Caption rules (enforced at scheduling — text that violates these returns validation_error 400 before the post is saved):
• No phone numbers in the caption (use a CALL button instead).
• No inline URLs / bare domains / email addresses (use a LEARN_MORE, BOOK, SHOP, SIGN_UP, or ORDER button instead).
• Caption max 1500 characters.
• Media optional (text-only posts allowed). If attached: exactly one JPEG/PNG/WebP image (no video, no carousels).
• The workspace must have a Google Business location selected (Settings → Organisation → Workspaces → Google Business) before scheduling.
Create and publish a post immediately › Responses
Post created and queued for immediate publishing