OmniSocialsOmniSocials
DocumentationAPI reference
Help centerSupport
  • Documentation
  • API reference
Developers
  • Quickstart
  • API reference
  • SDKs
  • MCP server
  • CLI
For AI agents
  • Docs for AI agents
  • llms.txt
  • OpenAPI spec
  • Postman collection
Product
  • OmniSocials
  • Pricing
  • Changelog
  • Help center
Company
  • Support
  • Privacy policy
  • Terms of service

© 2026 OmniSocials

OmniSocials on GitHubOmniSocials on XOmniSocials on LinkedIn
Information
Posts
    List postsgetList live platform postsgetGet a postgetDelete a postdeleteUpdate a postpatchCreate a postpostCreate and publish postpostPublish a post nowpostRetry failed postpostApprove a postpostReject a postpostGet approval reviewget
Media
    List mediagetGet a media itemgetDelete a media itemdeleteRename or move mediapatchUpload a filepostUpload from base64postUpload from a URLpostCreate an upload URLpostSplit a PDF into pagespostCheck media limitspostUpload with a tokenpost
Folders
    List foldersgetCreate a folderpostDelete a folderdeleteRename or move a folderpatch
Hashtag Sets
    List hashtag setsgetCreate a hashtag setpostGet a hashtag setgetDelete a hashtag setdeleteUpdate a hashtag setpatch
Accounts
    List accountsgetGet an accountget
Analytics
    Get bulk post analyticsgetGet post analyticsgetGet analytics overviewgetGet account analyticsgetGet best posting timesget
Approvals
    List approval workflowsget
Webhooks
    List webhooksgetCreate a webhookpostGet a webhookgetDelete a webhookdeleteUpdate a webhookpatchRotate webhook secretpost
Locations
    Search locationsgetValidate a locationget
Audio
    Search Instagram audioget
Pinterest
    List product PinsgetCheck a product Pinget
Inbox
    List conversationsgetList messagesgetMark conversation readpostReply to a conversationpostHide or unhide a commentpostDelete a commentdeleteGet next conversationget
Automations
    List automationsgetCreate an automationpostGet an automationgetDelete an automationdeleteUpdate an automationpatchList automation eventsget
Schemas
OmniSocials API
OmniSocials API

Posts

Download schema

Create, schedule, update, publish, and delete social media posts across every connected channel. This is the core of the OmniSocials API.


List posts

GET
https://api.omnisocials.com/v1
/posts

List posts › query Parameters

status
​string · enum

Filter by status. published and the legacy alias posted are equivalent. in_approval matches posts waiting for a reviewer in an approval workflow. rejected matches posts an approver declined via POST /posts/{id}/reject. warning matches partially failed posts (some platforms published, some failed). These do NOT match failed, which only matches posts where every platform failed.

Enum values:
draft
in_approval
scheduled
posting
published
failed
warning
rejected
limit
​integer · max: 100

Number of posts to return

Default: 20
offset
​integer

Number of posts to skip

Default: 0

List posts › Responses

200

List of posts

​Post[]
​Pagination
GET/posts
curl "https://api.omnisocials.com/v1/posts?status=scheduled&limit=20" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY"
Example Responses
{ "data": [ { "id": "1024", "status": "draft", "type": "post", "story_slides": { "key": [ { "index": 0, "native_post_id": "17912345678901234", "url": "url", "media_url": "media_url", "media_type": "image", "published_at": "2026-10-21T09:00:07.000Z" } ] }, "content": { "default": "Our autumn menu is here.", "instagram": "Our autumn menu is here. #autumnmenu" }, "accounts": { "instagram": true, "linkedin_page": true, "facebook": false, "x": false }, "media": { "default": [ { "url": "https://cdn.omnisocials.com/file/library-omnisocials/312a658f-2b45-4289-b240-890807221a74/library/1792573200000-k3j9xq_0c9e6b1a-2f4d-4b8e-a7c3-9d1e5f6a2b70.jpg", "id": "482913", "alt": "A bowl of pumpkin soup on a wooden table" } ] }, "location_id": "1234567890", "collaborators": [ "partnerbrand" ], "user_tags": [ { "username": "partnerbrand", "x": 0.5, "y": 0.8, "image_index": 0 } ], "schedule_at": "2026-10-21T09:00:00.000Z", "app_url": "https://app.omnisocials.com/create-post/1024", "published_urls": { "facebook": "https://www.facebook.com/123456789/posts/987654321", "instagram": "https://www.instagram.com/p/Cxyz123ABC/", "linkedin": "https://www.linkedin.com/feed/update/urn:li:share:7191234567890", "x": "https://x.com/yourhandle/status/1791234567890123456" }, "retry_of": "1023", "retries": [ "1031" ], "created_at": "2026-10-20T14:32:10.000Z", "approval_status": "none", "errors": { "facebook": "Already Posted: These photos were already posted.", "instagram": "Instagram couldn't accept one of your images. Check that every image is JPEG/PNG, at least 320×320, has an aspect ratio between 4:5 and 1.91:1, and isn't visually flagged by Instagram. Re-upload or replace the offending image and try again." }, "source": "api", "updated_at": "2026-10-20T14:35:42.000Z", "x": { "reply_settings": "", "paid_partnership": false, "made_with_ai": false, "poll": { "options": [ "Yes" ], "duration_minutes": 1440 }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "bluesky": { "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "mastodon": { "poll": { "options": [ "Yes" ], "expires_in": 86400, "multiple": false, "hide_totals": false }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "threads": { "poll": { "options": [ "Yes" ] }, "location": { "id": "17841400000000000", "name": "Griffith Observatory", "address": "2800 E Observatory Rd", "city": "Los Angeles", "country": "United States" }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "telegram": { "silent": false, "link_preview": true, "pin": true, "protect_content": false, "spoiler": false, "caption_above_media": false, "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "open_period": 86400, "multiple": false }, "result": { "chat_id": "-1001234567890", "message_ids": [ "42" ], "text_message_id": "43", "pinned": true, "pin_error": "no_right", "link_public": "https://t.me/brand/42", "link_private": "https://t.me/c/1234567890/42", "sent_at": "2026-10-21T09:00:07.000Z" } }, "discord": { "silent": false, "link_preview": true, "allow_mentions": false, "spoiler": false, "thread_name": "October menu", "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "duration_hours": 24, "multiple": false }, "result": { "webhook_id": "1290000000000000000", "guild_id": "1180000000000000000", "channel_id": "1180000000000000001", "thread_id": null, "message_id": "1300000000000000000", "url": "https://discord.com/channels/1180000000000000000/1180000000000000001/1300000000000000000", "sent_at": "2026-10-22T09:00:03.000Z", "video_links": [ "https://www.example.com/path/to/resource" ], "link_message_id": "link_message_id", "warnings": [ "media_sent_as_links" ] } }, "instagram": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "video_cover": { "type": "frame", "thumb_offset": 3000, "overrides": { "linkedin_page": { "type": "custom", "cover_url": "https://example.com/cover.jpg" } } }, "facebook": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "linkedin": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" }, "carousel_as_images": false, "document_source": "slides" }, "linkedin_page": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" }, "carousel_as_images": false, "document_source": "slides" }, "youtube": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "tiktok": { "title": "Autumn menu", "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "comment_dm_automation": { "id": "318", "type": "comment_to_dm", "platform": "instagram", "status": "active", "name": "Guide DM", "post_id": "1024", "instagram_media_id": "17912345678901234", "facebook_post_id": "104857600123456_987654321098765", "post": {}, "trigger": { "kinds": [ "comment" ], "scope": "post", "keywords": [ "guide" ], "match": "word" }, "actions": { "dm": { "text": "Here is the guide: https://example.com/guide" }, "public_reply": { "enabled": true, "variations": [ "Sent you a DM!" ] } }, "limits": { "max_sends": 500, "stop_at": "2026-11-30T23:00:00.000Z" }, "stats": { "matched": 120, "sent": 112, "skipped": 6, "failed": 2, "last_event_at": "2026-10-21T15:00:12.000Z" }, "created_at": "2026-10-20T14:32:10.000Z", "updated_at": "2026-10-20T14:35:42.000Z", "platforms": [ "instagram", "facebook" ], "automations": [ { "id": "318", "platform": "instagram", "status": "active" } ] } } ], "pagination": { "total": 42, "limit": 20, "offset": 0, "has_more": true } }
json
application/json

List live platform posts

GET
https://api.omnisocials.com/v1
/posts/recent-platform

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 (views/likes/comments/shares, plus average_time_watched, full_video_watched_rate, total_time_watched, favorites, reach when the workspace enabled TikTok comments, the Business API authorization), 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 for most platforms, so expect a few seconds of latency across many platforms. X is the exception: because X's API bills every returned post, X results may be served from a snapshot up to 24 hours old. The snapshot refreshes immediately after you publish to X through OmniSocials, so your own new posts always appear. Requires the analytics:read scope.

List live platform posts › query Parameters

limit
​integer · max: 50

Max posts to fetch per connected platform (1-50, default 25). When omitted, X returns up to 10 (its API bills per returned post); pass an explicit limit to get more from X.

Default: 25
platforms
​string

Optional comma-separated platform filter (e.g. "instagram,tiktok"). Defaults to every connected platform. Unsupported values return 400.

Example: instagram,tiktok

List live platform posts › Responses

Recent posts across connected platforms, newest first

​object[]
count
​integer
connected_platforms
​string[]
errors
​object

Per-platform error messages for any platform that failed to fetch.

note
​string
current_date
​string · date
GET/posts/recent-platform
curl "https://api.omnisocials.com/v1/posts/recent-platform?limit=10&platforms=instagram,x" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY"
Example Responses
{ "data": [ { "platform": "instagram", "id": "17912345678901234", "permalink": "https://www.instagram.com/p/Cxyz123ABC/", "text": "Our autumn menu is here. #autumnmenu", "format": "carousel", "media_count": 3, "timestamp": "2026-10-21T09:00:07.000Z", "image_url": "image_url", "duration_seconds": 0, "metrics": {}, "engagement": 104, "impressions": 1520, "engagement_rate": 6.84 } ], "count": 25, "connected_platforms": [ "instagram" ], "errors": {}, "note": "note", "current_date": "2026-10-21" }
json
application/json

Get a post

GET
https://api.omnisocials.com/v1
/posts/{id}

Get a post › path Parameters

id
​string · required

Post ID

Example: 1024

Get a post › Responses

Post details

​Post
GET/posts/{id}
curl "https://api.omnisocials.com/v1/posts/12345" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY"
Example Responses
{ "data": { "id": "1024", "status": "draft", "type": "post", "story_slides": { "key": [ { "index": 0, "native_post_id": "17912345678901234", "url": "url", "media_url": "media_url", "media_type": "image", "published_at": "2026-10-21T09:00:07.000Z" } ] }, "content": { "default": "Our autumn menu is here.", "instagram": "Our autumn menu is here. #autumnmenu" }, "accounts": { "instagram": true, "linkedin_page": true, "facebook": false, "x": false }, "media": { "default": [ { "url": "https://cdn.omnisocials.com/file/library-omnisocials/312a658f-2b45-4289-b240-890807221a74/library/1792573200000-k3j9xq_0c9e6b1a-2f4d-4b8e-a7c3-9d1e5f6a2b70.jpg", "id": "482913", "alt": "A bowl of pumpkin soup on a wooden table" } ] }, "location_id": "1234567890", "collaborators": [ "partnerbrand" ], "user_tags": [ { "username": "partnerbrand", "x": 0.5, "y": 0.8, "image_index": 0 } ], "schedule_at": "2026-10-21T09:00:00.000Z", "app_url": "https://app.omnisocials.com/create-post/1024", "published_urls": { "facebook": "https://www.facebook.com/123456789/posts/987654321", "instagram": "https://www.instagram.com/p/Cxyz123ABC/", "linkedin": "https://www.linkedin.com/feed/update/urn:li:share:7191234567890", "x": "https://x.com/yourhandle/status/1791234567890123456" }, "retry_of": "1023", "retries": [ "1031" ], "created_at": "2026-10-20T14:32:10.000Z", "approval_status": "none", "errors": { "facebook": "Already Posted: These photos were already posted.", "instagram": "Instagram couldn't accept one of your images. Check that every image is JPEG/PNG, at least 320×320, has an aspect ratio between 4:5 and 1.91:1, and isn't visually flagged by Instagram. Re-upload or replace the offending image and try again." }, "source": "api", "updated_at": "2026-10-20T14:35:42.000Z", "x": { "reply_settings": "", "paid_partnership": false, "made_with_ai": false, "poll": { "options": [ "Yes" ], "duration_minutes": 1440 }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "bluesky": { "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "mastodon": { "poll": { "options": [ "Yes" ], "expires_in": 86400, "multiple": false, "hide_totals": false }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "threads": { "poll": { "options": [ "Yes" ] }, "location": { "id": "17841400000000000", "name": "Griffith Observatory", "address": "2800 E Observatory Rd", "city": "Los Angeles", "country": "United States" }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "telegram": { "silent": false, "link_preview": true, "pin": true, "protect_content": false, "spoiler": false, "caption_above_media": false, "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "open_period": 86400, "multiple": false }, "result": { "chat_id": "-1001234567890", "message_ids": [ "42" ], "text_message_id": "43", "pinned": true, "pin_error": "no_right", "link_public": "https://t.me/brand/42", "link_private": "https://t.me/c/1234567890/42", "sent_at": "2026-10-21T09:00:07.000Z" } }, "discord": { "silent": false, "link_preview": true, "allow_mentions": false, "spoiler": false, "thread_name": "October menu", "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "duration_hours": 24, "multiple": false }, "result": { "webhook_id": "1290000000000000000", "guild_id": "1180000000000000000", "channel_id": "1180000000000000001", "thread_id": null, "message_id": "1300000000000000000", "url": "https://discord.com/channels/1180000000000000000/1180000000000000001/1300000000000000000", "sent_at": "2026-10-22T09:00:03.000Z", "video_links": [ "https://www.example.com/path/to/resource" ], "link_message_id": "link_message_id", "warnings": [ "media_sent_as_links" ] } }, "instagram": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "video_cover": { "type": "frame", "thumb_offset": 3000, "overrides": { "linkedin_page": { "type": "custom", "cover_url": "https://example.com/cover.jpg" } } }, "facebook": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "linkedin": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" }, "carousel_as_images": false, "document_source": "slides" }, "linkedin_page": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" }, "carousel_as_images": false, "document_source": "slides" }, "youtube": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "tiktok": { "title": "Autumn menu", "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "comment_dm_automation": { "id": "318", "type": "comment_to_dm", "platform": "instagram", "status": "active", "name": "Guide DM", "post_id": "1024", "instagram_media_id": "17912345678901234", "facebook_post_id": "104857600123456_987654321098765", "post": {}, "trigger": { "kinds": [ "comment" ], "scope": "post", "keywords": [ "guide" ], "match": "word" }, "actions": { "dm": { "text": "Here is the guide: https://example.com/guide" }, "public_reply": { "enabled": true, "variations": [ "Sent you a DM!" ] } }, "limits": { "max_sends": 500, "stop_at": "2026-11-30T23:00:00.000Z" }, "stats": { "matched": 120, "sent": 112, "skipped": 6, "failed": 2, "last_event_at": "2026-10-21T15:00:12.000Z" }, "created_at": "2026-10-20T14:32:10.000Z", "updated_at": "2026-10-20T14:35:42.000Z", "platforms": [ "instagram", "facebook" ], "automations": [ { "id": "318", "platform": "instagram", "status": "active" } ] } } }
json
application/json

Delete a post

DELETE
https://api.omnisocials.com/v1
/posts/{id}

Removes the post from OmniSocials only: it leaves the calendar, the posts list and the analytics. It never deletes the live post on a platform, so a published post stays live everywhere it went. To take a live post down as well, use "Delete from [platform]" on the post in the OmniSocials dashboard (all platforms except Instagram and TikTok, whose APIs have no delete) or delete it in the platform's own app. Cannot be undone.

Delete a post › path Parameters

id
​string · required

Delete a post › Responses

Post deleted

No data returned
DELETE/posts/{id}
curl -X DELETE "https://api.omnisocials.com/v1/posts/12345" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY"
Example Responses
No example specified for this content type

Update a post

PATCH
https://api.omnisocials.com/v1
/posts/{id}

Update a post › path Parameters

id
​string · required

Update a post › Request Body

content
​object
accounts
​string[]
type
​string · enum

Change post type (draft only)

Enum values:
post
story
reel
​CreatePostRequest/properties/media

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). For type 'story', each item is one slide (max 10, published in order).

​CreatePostRequest/properties/media

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). For type 'story', each item is one slide (max 10, published in order).

​CreatePostRequest/properties/media_urls

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, Pinterest, Instagram (images) and LinkedIn (images). 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_at
​string · date-time

New publish time (ISO 8601, must be in the future). A draft becomes scheduled (or stays a planned draft when draft: true is sent with it). A post that is waiting for approval keeps its in_approval status and only its time moves. Send null to unschedule back to a draft without a date; a post that was waiting for approval then leaves its approval workflow (approval_status becomes none).

Example: 2026-10-21T09:00:00Z
draft
​boolean

Planned-draft switch. false without schedule_at schedules a draft at the schedule_at it already carries (400 validation_error when it has none or it is in the past). true without schedule_at unschedules a scheduled post: it keeps its time and stays on the calendar as a dashed draft, nothing publishes; a post waiting for approval leaves its workflow. true with schedule_at moves the time and keeps (or makes) the post a draft.

Example: false
​CreatePostRequest/properties/media_fit

Image fit per channel, for feed images (type post) whose ratio is outside what a channel shows uncropped. auto (the default when omitted) takes the channel's rule: Instagram crops a tall or wide image to 4:5 / 1.91:1 around the subject (Instagram cuts it to that window anyway, and Meta cannot boost a feed post outside it); Pinterest keeps a Pin taller than 2:3 and only reports it. crop crops for that channel, keep sends the original. Every decision is reported in the response warnings with code: "image_fit". The crop is a file of its own for that channel only; default and the other channels keep the original. On PATCH, media_fit alone (no media) re-decides the stored images: keep gives the original back, crop crops an image that was kept.

Example: {"instagram":"keep"}
location_id
​CreatePostRequest/properties/location_id

Instagram 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.

Example: 1234567890
collaborators
​string[] · maxItems: 3

Instagram 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.

Example: ["therock","kevinhart4real"]
​object[]

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.

Example: [{"username":"therock","x":0.5,"y":0.8}]
​object

Replaced wholesale; send the full desired cover. Pass null to remove the cover. Omit to leave it untouched. Facebook's facebook.thumbnail_type / thumb_offset / cover_url merge into overrides.facebook on their own (thumbnail_type: null clears just that override).

Example: {"type":"frame","thumb_offset":3000,"overrides":{"linkedin_page":{"type":"custom","cover_url":"https://example.com/cover.jpg"}}}
​CreatePostRequest/properties/pinterest

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 constraints: carousels hard-cap at 5 images: attaching more responds 400 validation_error at create/schedule time. Pinterest's v5 API also 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. Both checks 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.

​CreatePostRequest/properties/youtube

YouTube Shorts options. Only applies when type is reel and youtube is among the selected accounts.

​object

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.

​CreatePostRequest/properties/tiktok

TikTok options

​CreatePostRequest/properties/x

X (Twitter) options

​CreatePostRequest/properties/bluesky

Bluesky options

​CreatePostRequest/properties/mastodon

Mastodon options

​CreatePostRequest/properties/threads

Threads options: thread mode via thread_parts, location tag via location_id, poll via poll.

​object

Telegram options. MERGED into the stored options: keys you omit keep their value; a key set to null removes that option; telegram: null removes every option (the publish result stays).

​object

Discord options. MERGED into the stored options: keys you omit keep their value; a key set to null removes that option; discord: null removes every option (the publish result stays).

Example: {"silent":true,"link_preview":false,"buttons":[{"text":"Book a table","url":"https://example.com/book"}]}
​CreatePostRequest/properties/google_business

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.

​object

LinkedIn Profile options. MERGED into the stored options: keys you omit keep their current value. first_comment: a string sets it, null/empty clears it. carousel_as_images: true publishes 2+ images as a plain image gallery, false/null reverts to the default PDF document carousel. document_source: slides rebuilds the document from the slide images, original_pdf/null reverts to sending the kept original PDF (the default).

​object

LinkedIn Company Page options. Same merge semantics as linkedin.

linkedin_poll
​object | null

Replaced wholesale: send the full desired state for BOTH channels, not just the one you're changing. Pass null (or { "linkedin": null, "linkedin_page": null }) to clear every poll and revert to normal posts; set just one channel's key to null to clear only that channel's poll while keeping the other.

comment_dm_automation
​object | null

Replaces the post's comment-to-DM setup (keywords, DM, public reply, limits, platforms); each automation keeps listening on the same post. A channel no longer listed in platforms loses its automation. Pass null to remove them all. Omit to leave them untouched. Needs the automations:write scope.

Example: {"trigger":{"keywords":["guide"]},"actions":{"dm":{"text":"Here is the guide: https://example.com/guide"},"public_reply":{"enabled":true,"variations":["Sent you a DM!"]}},"limits":{"max_sends":500}}

Update a post › Responses

Post updated

​Post
PATCH/posts/{id}
curl -X PATCH "https://api.omnisocials.com/v1/posts/12345" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"schedule_at": "2026-11-02T09:00:00Z"}'
Example Request Body
{ "content": {}, "accounts": [ "instagram" ], "type": "post", "media": [ "482913" ], "media_ids": [ "482913" ], "media_urls": [ "https://example.com/photo.jpg" ], "schedule_at": "2026-10-21T09:00:00Z", "draft": false, "media_fit": { "instagram": "keep" }, "location_id": "1234567890", "collaborators": [ "therock", "kevinhart4real" ], "user_tags": [ { "username": "therock", "x": 0.5, "y": 0.8 } ], "video_cover": { "type": "frame", "thumb_offset": 3000, "overrides": { "linkedin_page": { "type": "custom", "cover_url": "https://example.com/cover.jpg" } } }, "pinterest": { "board_id": "1234567890123456789", "title": "Autumn menu", "link": "https://example.com/menu", "video_cover": "https://example.com/cover.jpg", "alt_text": "A bowl of pumpkin soup on a wooden table", "product_tags": [ "813744226420795884", "813744226420795885" ], "product_tags_result": { "requested": 2, "tagged": [ "813744226420795884" ], "skipped": [ { "pin_id": "813744226420795885", "reason": "PIN_IS_PRIVATE" } ], "error": "error" } }, "youtube": { "title": "How we plan a week of posts", "tags": [ "social media" ], "privacy_status": "public", "category_id": "22", "made_for_kids": false, "notify_subscribers": false, "contains_synthetic_media": false, "first_comment": "Full menu at the link in our bio." }, "instagram": { "share_to_feed": false, "thumbnail_type": "from-video", "thumb_offset": 3000, "cover_url": "https://example.com/cover.jpg", "audio_id": "587784541076604", "audio_volume": 100, "video_volume": 100, "first_comment": "Full menu at the link in our bio.", "is_trial_reel": false, "trial_graduation_strategy": "MANUAL", "is_ai_generated": false }, "tiktok": { "title": "Autumn menu", "privacy_level": "PUBLIC_TO_EVERYONE", "disable_comment": false, "disable_duet": false, "disable_stitch": false, "video_cover_timestamp_ms": 0, "is_aigc": false, "brand_content_toggle": false, "brand_organic_toggle": false, "auto_add_music": false, "first_comment": "Full menu at the link in our bio." }, "x": { "reply_settings": "", "paid_partnership": false, "made_with_ai": false, "poll": { "options": [ "Yes" ], "duration_minutes": 1440 }, "thread_parts": [ { "text": "1/3: our results are in", "media_ids": [ "12345" ] }, { "text": "2/3: grab your free pick at https://example.com/signup" }, { "text": "3/3: and here's the slip", "media_ids": [ "12346" ] } ] }, "bluesky": { "thread_parts": [ { "text": "1/3: our results are in" }, { "text": "2/3: read the full writeup at https://example.com/post" }, { "text": "3/3: thanks for reading! #buildinpublic" } ] }, "mastodon": { "poll": { "options": [ "Yes" ], "expires_in": 86400, "multiple": false, "hide_totals": false }, "thread_parts": [ { "text": "1/3: our picks are in" }, { "text": "2/3: read the full writeup at https://example.com/post" }, { "text": "3/3: thanks for reading! #fediverse" } ] }, "threads": { "poll": { "options": [ "Yes" ] }, "location_id": "17841400000000000", "location": { "id": "17841400000000000", "name": "Griffith Observatory", "address": "2800 E Observatory Rd", "city": "Los Angeles", "country": "United States" }, "thread_parts": [ { "text": "1/3: our results are in" }, { "text": "2/3: read the full writeup: https://example.com/post" }, { "text": "3/3: thanks for reading! #buildinpublic" } ] }, "telegram": { "silent": false, "link_preview": true, "pin": true, "protect_content": false, "spoiler": false, "caption_above_media": false, "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "open_period": 86400, "multiple": false }, "first_comment": "Full menu at the link in our bio." }, "discord": { "silent": true, "link_preview": false, "buttons": [ { "text": "Book a table", "url": "https://example.com/book" } ] }, "google_business": { "topic_type": "STANDARD", "cta": { "actionType": "LEARN_MORE", "url": "https://example.com/book" }, "event": { "title": "Autumn tasting night", "schedule": { "startDate": { "year": 2026, "month": 10, "day": 24 }, "startTime": { "hours": 18, "minutes": 0 }, "endDate": { "year": 2026, "month": 10, "day": 24 }, "endTime": { "hours": 22, "minutes": 0 } } }, "offer": { "couponCode": "AUTUMN20", "redeemOnlineUrl": "https://example.com/offer", "termsConditions": "Valid until 31 October 2026." } }, "linkedin": { "first_comment": "Full menu: https://example.com/menu", "carousel_as_images": false, "document_source": "original_pdf" }, "linkedin_page": { "first_comment": "Full menu: https://example.com/menu", "carousel_as_images": false, "document_source": "original_pdf" }, "linkedin_poll": { "linkedin": { "question": "Which feature should we build next?", "options": [ "Bulk upload" ], "duration": "ONE_DAY" }, "linkedin_page": { "question": "Which feature should we build next?", "options": [ "Bulk upload" ], "duration": "ONE_DAY" } }, "comment_dm_automation": { "trigger": { "keywords": [ "guide" ] }, "actions": { "dm": { "text": "Here is the guide: https://example.com/guide" }, "public_reply": { "enabled": true, "variations": [ "Sent you a DM!" ] } }, "limits": { "max_sends": 500 } } }
json
Example Responses
{ "data": { "id": "1024", "status": "draft", "type": "post", "story_slides": { "key": [ { "index": 0, "native_post_id": "17912345678901234", "url": "url", "media_url": "media_url", "media_type": "image", "published_at": "2026-10-21T09:00:07.000Z" } ] }, "content": { "default": "Our autumn menu is here.", "instagram": "Our autumn menu is here. #autumnmenu" }, "accounts": { "instagram": true, "linkedin_page": true, "facebook": false, "x": false }, "media": { "default": [ { "url": "https://cdn.omnisocials.com/file/library-omnisocials/312a658f-2b45-4289-b240-890807221a74/library/1792573200000-k3j9xq_0c9e6b1a-2f4d-4b8e-a7c3-9d1e5f6a2b70.jpg", "id": "482913", "alt": "A bowl of pumpkin soup on a wooden table" } ] }, "location_id": "1234567890", "collaborators": [ "partnerbrand" ], "user_tags": [ { "username": "partnerbrand", "x": 0.5, "y": 0.8, "image_index": 0 } ], "schedule_at": "2026-10-21T09:00:00.000Z", "app_url": "https://app.omnisocials.com/create-post/1024", "published_urls": { "facebook": "https://www.facebook.com/123456789/posts/987654321", "instagram": "https://www.instagram.com/p/Cxyz123ABC/", "linkedin": "https://www.linkedin.com/feed/update/urn:li:share:7191234567890", "x": "https://x.com/yourhandle/status/1791234567890123456" }, "retry_of": "1023", "retries": [ "1031" ], "created_at": "2026-10-20T14:32:10.000Z", "approval_status": "none", "errors": { "facebook": "Already Posted: These photos were already posted.", "instagram": "Instagram couldn't accept one of your images. Check that every image is JPEG/PNG, at least 320×320, has an aspect ratio between 4:5 and 1.91:1, and isn't visually flagged by Instagram. Re-upload or replace the offending image and try again." }, "source": "api", "updated_at": "2026-10-20T14:35:42.000Z", "x": { "reply_settings": "", "paid_partnership": false, "made_with_ai": false, "poll": { "options": [ "Yes" ], "duration_minutes": 1440 }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "bluesky": { "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "mastodon": { "poll": { "options": [ "Yes" ], "expires_in": 86400, "multiple": false, "hide_totals": false }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "threads": { "poll": { "options": [ "Yes" ] }, "location": { "id": "17841400000000000", "name": "Griffith Observatory", "address": "2800 E Observatory Rd", "city": "Los Angeles", "country": "United States" }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "telegram": { "silent": false, "link_preview": true, "pin": true, "protect_content": false, "spoiler": false, "caption_above_media": false, "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "open_period": 86400, "multiple": false }, "result": { "chat_id": "-1001234567890", "message_ids": [ "42" ], "text_message_id": "43", "pinned": true, "pin_error": "no_right", "link_public": "https://t.me/brand/42", "link_private": "https://t.me/c/1234567890/42", "sent_at": "2026-10-21T09:00:07.000Z" } }, "discord": { "silent": false, "link_preview": true, "allow_mentions": false, "spoiler": false, "thread_name": "October menu", "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "duration_hours": 24, "multiple": false }, "result": { "webhook_id": "1290000000000000000", "guild_id": "1180000000000000000", "channel_id": "1180000000000000001", "thread_id": null, "message_id": "1300000000000000000", "url": "https://discord.com/channels/1180000000000000000/1180000000000000001/1300000000000000000", "sent_at": "2026-10-22T09:00:03.000Z", "video_links": [ "https://www.example.com/path/to/resource" ], "link_message_id": "link_message_id", "warnings": [ "media_sent_as_links" ] } }, "instagram": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "video_cover": { "type": "frame", "thumb_offset": 3000, "overrides": { "linkedin_page": { "type": "custom", "cover_url": "https://example.com/cover.jpg" } } }, "facebook": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "linkedin": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" }, "carousel_as_images": false, "document_source": "slides" }, "linkedin_page": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" }, "carousel_as_images": false, "document_source": "slides" }, "youtube": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "tiktok": { "title": "Autumn menu", "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "comment_dm_automation": { "id": "318", "type": "comment_to_dm", "platform": "instagram", "status": "active", "name": "Guide DM", "post_id": "1024", "instagram_media_id": "17912345678901234", "facebook_post_id": "104857600123456_987654321098765", "post": {}, "trigger": { "kinds": [ "comment" ], "scope": "post", "keywords": [ "guide" ], "match": "word" }, "actions": { "dm": { "text": "Here is the guide: https://example.com/guide" }, "public_reply": { "enabled": true, "variations": [ "Sent you a DM!" ] } }, "limits": { "max_sends": 500, "stop_at": "2026-11-30T23:00:00.000Z" }, "stats": { "matched": 120, "sent": 112, "skipped": 6, "failed": 2, "last_event_at": "2026-10-21T15:00:12.000Z" }, "created_at": "2026-10-20T14:32:10.000Z", "updated_at": "2026-10-20T14:35:42.000Z", "platforms": [ "instagram", "facebook" ], "automations": [ { "id": "318", "platform": "instagram", "status": "active" } ] } } }
json
application/json

Create a post

POST
https://api.omnisocials.com/v1
/posts/create

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.

Stories (type: "story"): 1 to 10 media items. Each item is one slide and publishes as its own story on Instagram and Facebook, in the order given. Per-platform objects can give each platform its own slide list. Videos max 60 s per slide. After publishing, story_slides lists every slide's native id and URL; published_urls keeps the first slide.

Per-platform media caps (enforced at submit, not at publish time):

  • bluesky: max 4 images per post; cannot mix images and video
  • mastodon: max 4 media items per post; cannot mix images and video
  • x: max 4 images per post; cannot mix images and video
  • instagram: max 10 items in a carousel; images and videos can be mixed in one carousel
  • threads: max 10 items in a carousel; images and videos can be mixed in one carousel
  • tiktok: max 35 items per photo post; cannot mix photos and videos in one post
  • pinterest: max 5 images per carousel pin (videos are exempt: they publish as single video pins)
  • facebook, linkedin, linkedin_page: cannot mix images and video in one post (their APIs accept images only or a single video)

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." } } (Pinterest wording: "Pinterest carousel pins support a maximum of 5 images. Please remove some images and try again."). 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, 16 GB with Premium / Premium+ (in practice bounded by the 1 GB URL-ingest / 100 MB direct-upload limits) · 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 240 min (Post + Reel; the separate 90 s Reel cap was removed on 2026-09-30) · Instagram 15 min (Post + Reel) · TikTok 10 min (Post + Reel) · YouTube Short 3 min · X 140 s free tier, 125 min when the connected X account has Premium or Premium+ (tier detected automatically; reconnect X after upgrading) · 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.

X link-post credits: X's API bills posts whose text contains a URL at a premium ($0.20 vs $0.015), and OmniSocials passes that fee through as prepaid credits at X's rate card (20 credits per URL-containing tweet; threads are billed per part that contains a link). Only a link written with http:// or https:// counts; a bare domain (brand.com) or a www. link is free. Credits are purchased in euros: 1 credit = €0.01, top-ups of €5-500 in the dashboard. When a create/schedule targets X and the text contains a URL, the 201 response includes a warnings array entry (code: "x_url_post_credits") with credits_required, the company's current credits_balance, and the enforcement state. At publish time the credits are debited; if the balance can't cover it, the X target alone fails with an INSUFFICIENT_CREDITS message in its error_message (other platforms in the post publish normally) and the post can be retried after topping up in Settings → Organisation → Billing → Credits. Posts without links, analytics, and everything else on X stay free.

Schedule-time gate: every scheduled X link post reserves its cost until it publishes. Scheduling (or publishing) a new X link post that would push the total reserved past the balance is refused with 402 x_credits_insufficient (details carries credits_required, credits_balance, credits_reserved). Drafts are never gated; posts publishing before the enforcement date are never gated.

Create a post › Request Body

CreatePostRequest
content
​object · required

Post content. Use 'default' for all platforms, or platform-specific keys: instagram, facebook, linkedin, linkedin_page, youtube, tiktok, pinterest, x, threads, bluesky, mastodon, google_business, telegram, discord. Coming soon: reddit, snapchat.

Example: {"default":"Hello world!","instagram":"Hello from IG! #awesome"}
accounts
​string[] · required

Social 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/accounts in 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.

type
​string · enum

Post type: 'post' (feed), 'story' (Instagram/Facebook), 'reel' (Instagram/Facebook/YouTube/TikTok). Telegram and Discord have no reels: a reel that names them is still accepted, and they get the video as a normal post; send a video for them alone as a 'post'. 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. A 'story' takes 1 to 10 media items: each item is one slide, published as its own story in the order given (Instagram and Facebook have no multi-slide story container). More than 10 returns 400 validation_error.

Enum values:
post
story
reel
Default: post
​

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). For type 'story', each item is one slide (max 10, published in order).

​

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, Pinterest, Instagram (images) and LinkedIn (images). 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_at
​string · date-time

ISO 8601 datetime to schedule. Omit for a draft without a date. With draft: true the time is kept but the post stays a draft (a planned draft on the calendar, see draft).

Example: 2026-10-21T09:00:00Z
draft
​boolean

Planned draft. With schedule_at, the post is stored as draft and keeps that time: it shows on the dashboard calendar at that slot with a dashed outline, the scheduler never publishes it, and a person schedules it from the composer (or you do with PATCH /posts/{id} and draft: false). Use it when an agent proposes a slot that a human should confirm. Not allowed with publish_now or approval_workflow_id (400 validation_error). Without schedule_at it changes nothing: that post is a draft already.

Example: true
​object

Image fit per channel, for feed images (type post) whose ratio is outside what a channel shows uncropped. auto (the default when omitted) takes the channel's rule: Instagram crops a tall or wide image to 4:5 / 1.91:1 around the subject (Instagram cuts it to that window anyway, and Meta cannot boost a feed post outside it); Pinterest keeps a Pin taller than 2:3 and only reports it. crop crops for that channel, keep sends the original. Every decision is reported in the response warnings with code: "image_fit". The crop is a file of its own for that channel only; default and the other channels keep the original. On PATCH, media_fit alone (no media) re-decides the stored images: keep gives the original back, crop crops an image that was kept.

Example: {"instagram":"keep"}
publish_now
​boolean

Set true to publish immediately

Example: false
link_url
​string · uri

URL 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).

Example: https://goodlightai.com/blog/new-feature
link_title
​string

Optional 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.

Example: Our autumn menu
link_description
​string

Optional description for the link-share preview. LinkedIn uses this when set; Facebook auto-fetches the OG description. Omit to defer to OG metadata.

Example: Six new dishes, available from today.
link_thumbnail_url
​string · uri

Optional thumbnail image URL for the preview card. LinkedIn uploads this image as the card thumbnail; without it, LinkedIn uses the page's Open Graph image, and when the upload fails the card has no image. Facebook ignores it and uses the page's Open Graph image.

Example: https://example.com/preview.jpg
​VideoCover

Video thumbnail for a post whose media is one video. Applied on Instagram (feed videos and reels), Facebook (feed videos and reels), LinkedIn Profile and Page, TikTok, Pinterest and YouTube Shorts. On YouTube Shorts the cover shows only on channels where YouTube has enabled custom Shorts thumbnails (rolling out since July 2026, YouTube Partner Program channels first); on other channels YouTube stores it as the default thumbnail but shows a frame from the video on Shorts. TikTok only takes a frame, so a custom cover is skipped there (set a tiktok override with type frame to choose the frame). The per-platform reel fields (instagram.thumb_offset / cover_url, tiktok.video_cover_timestamp_ms, pinterest.video_cover) keep working and win over the base cover for their platform.

Example: {"type":"frame","thumb_offset":3000,"overrides":{"linkedin_page":{"type":"custom","cover_url":"https://example.com/cover.jpg"}}}
source
​string

Self-reported origin of the integration creating this post. Defaults to 'api' if omitted. Use 'zapier', 'make', 'n8n', etc. to identify your integration.

Example: zapier
location_id
​string

Instagram 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.

Example: 1234567890
collaborators
​string[] · maxItems: 3

Instagram 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.

Example: ["therock","kevinhart4real"]
​object[]

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.

Example: [{"username":"therock","x":0.5,"y":0.8}]
hashtag_set
​string

Name 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.

Example: Fitness Brand
hashtag_set_id
​string

Id of a saved hashtag set to apply. Same behavior as hashtag_set; pass one or the other.

Example: 57
hashtag_placement
​string · enum

Where 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, TikTok with comments enabled, Telegram), 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).

Enum values:
caption_append
first_comment
Default: caption_append
hashtag_platforms
​string[]

Optional subset of the post's selected platforms to apply the set to (e.g. only ["instagram", "tiktok"]). Defaults to all selected platforms.

approval_workflow_id
​string

Id of an approval workflow (see GET /approval-workflows) to route this post through. The post is created with status in_approval and approval_status: pending instead of scheduled: the workflow's first-step approvers are notified (dashboard badge, email, Slack), they review it in the dashboard's Approvals page, and it publishes at schedule_at only once the last step approves it (dashboard, or POST /posts/{id}/approve). A rejection leaves it rejected. Requires schedule_at; cannot be combined with publish_now. Errors: 404 workflow_not_found (not a workflow of this company/workspace), 400 validation_error (missing schedule_at, publish_now set, or the workflow has no approvers on its first step).

Example: 57823504
comment_dm_automation
​object | null

A comment-to-DM automation bound to this post (Instagram or Facebook must be in accounts). When somebody comments one of trigger.keywords on the post once it is live, the account DMs them actions.dm.text, once per person, and optionally posts one of actions.public_reply.variations under the comment. On a Facebook Page the DM lands in Messenger. The shape is the AutomationInput of POST /automations without post_id, scope or kinds (always this post, comment trigger), plus platforms. The created automations come back as comment_dm_automation on the post. Needs the opt-in automations:write scope on the API key (403 insufficient_scope without it).

Example: {"trigger":{"keywords":["guide"]},"actions":{"dm":{"text":"Here is the guide: https://example.com/guide"},"public_reply":{"enabled":true,"variations":["Sent you a DM!"]}},"limits":{"max_sends":500}}
​object

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 constraints: carousels hard-cap at 5 images: attaching more responds 400 validation_error at create/schedule time. Pinterest's v5 API also 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. Both checks 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.

​object

YouTube Shorts options. Only applies when type is reel and youtube is among the selected accounts.

​object

Instagram Reel options

​object

Facebook options

​object

LinkedIn Profile options

​object

LinkedIn Company Page options

linkedin_poll
​object | null

Non-sponsored LinkedIn poll(s), independent per channel, keyed by linkedin (personal profile) / linkedin_page (company page). A poll is mutually exclusive with media and a link share on that channel's post: a poll takes priority over both at publish time. Requires content.linkedin (or content.default) as that channel's caption/commentary; the poll itself only carries the question/options/duration.

​object

TikTok options

​object

X (Twitter) options

​object

Bluesky options

​object

Mastodon options

​object

Telegram options (2026-10-17). Telegram posts go to the connected channel or group through the OmniSocials bot. Text up to 4,096 characters; with media, text over 1,024 characters is sent as a reply under the media (Telegram's caption limit). Media: up to 10 photos and videos (an album), one GIF, one video up to 50 MB, or files. No Stories. Views are not available to bots: analytics report reactions and subscribers.

​object

Discord options (2026-10-22). Discord posts go to the channel the workspace connected, through that channel's webhook; the message shows the webhook's name and picture. Text up to 2,000 characters. Media: up to 10 images, GIFs and videos in one message (they may mix). A file over Discord's 20 MB attachment limit is sent differently: an image is re-encoded to fit, a video or GIF goes as a link in the text (listed in discord.result.video_links). No Stories; a reel is sent as one video message. Statistics: reactions and poll votes only (Discord gives webhooks no views). A sent message can be deleted at any time.

Example: {"silent":true,"link_preview":false,"buttons":[{"text":"Book a table","url":"https://example.com/book"}]}
​object

Threads options: thread mode via thread_parts, location tag via location_id, poll via poll.

​object

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 post › Responses

Post created

​Post
​object[]

Non-blocking notices about this post. x_url_post_credits (X link-post fee pass-through) and image_fit (a feed image outside what a channel shows uncropped: action is cropped, kept or crop_failed, with platform, media_url, ratio, target and crop_url; see media_fit).

POST/posts/create
curl -X POST "https://api.omnisocials.com/v1/posts/create" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": {"default": "New drop this Friday"}, "accounts": ["linkedin", "x"], "schedule_at": "2026-11-02T09:00:00Z" }'
Example Request Body
{ "content": { "default": "Hello world!", "instagram": "Hello from IG! #awesome" }, "accounts": [ "instagram" ], "type": "post", "media": [ "482913" ], "media_urls": [ "https://example.com/photo.jpg" ], "schedule_at": "2026-10-21T09:00:00Z", "draft": true, "media_fit": { "instagram": "keep" }, "publish_now": false, "link_url": "https://goodlightai.com/blog/new-feature", "link_title": "Our autumn menu", "link_description": "Six new dishes, available from today.", "link_thumbnail_url": "https://example.com/preview.jpg", "video_cover": { "type": "frame", "thumb_offset": 3000, "overrides": { "linkedin_page": { "type": "custom", "cover_url": "https://example.com/cover.jpg" } } }, "source": "zapier", "location_id": "1234567890", "collaborators": [ "therock", "kevinhart4real" ], "user_tags": [ { "username": "therock", "x": 0.5, "y": 0.8 } ], "hashtag_set": "Fitness Brand", "hashtag_set_id": "57", "hashtag_placement": "caption_append", "hashtag_platforms": [ "instagram" ], "approval_workflow_id": "57823504", "comment_dm_automation": { "trigger": { "keywords": [ "guide" ] }, "actions": { "dm": { "text": "Here is the guide: https://example.com/guide" }, "public_reply": { "enabled": true, "variations": [ "Sent you a DM!" ] } }, "limits": { "max_sends": 500 } }, "pinterest": { "board_id": "1234567890123456789", "title": "Autumn menu", "link": "https://example.com/menu", "video_cover": "https://example.com/cover.jpg", "alt_text": "A bowl of pumpkin soup on a wooden table", "product_tags": [ "813744226420795884", "813744226420795885" ], "product_tags_result": { "requested": 2, "tagged": [ "813744226420795884" ], "skipped": [ { "pin_id": "813744226420795885", "reason": "PIN_IS_PRIVATE" } ], "error": "error" } }, "youtube": { "title": "How we plan a week of posts", "tags": [ "social media" ], "privacy_status": "public", "category_id": "22", "made_for_kids": false, "notify_subscribers": false, "contains_synthetic_media": false, "first_comment": "Full menu at the link in our bio." }, "instagram": { "share_to_feed": false, "thumbnail_type": "from-video", "thumb_offset": 3000, "cover_url": "https://example.com/cover.jpg", "audio_id": "587784541076604", "audio_volume": 100, "video_volume": 100, "first_comment": "Full menu at the link in our bio.", "is_trial_reel": false, "trial_graduation_strategy": "MANUAL", "is_ai_generated": false }, "facebook": { "first_comment": "Full menu at the link in our bio.", "thumbnail_type": "from-video", "thumb_offset": 3000, "cover_url": "https://example.com/cover.jpg" }, "linkedin": { "first_comment": "Full menu: https://example.com/menu", "carousel_as_images": false, "document_source": "original_pdf" }, "linkedin_page": { "first_comment": "Full menu: https://example.com/menu", "carousel_as_images": false, "document_source": "original_pdf" }, "linkedin_poll": { "linkedin": { "question": "Which feature should we build next?", "options": [ "Bulk upload" ], "duration": "ONE_DAY" }, "linkedin_page": { "question": "Which feature should we build next?", "options": [ "Bulk upload" ], "duration": "ONE_DAY" } }, "tiktok": { "title": "Autumn menu", "privacy_level": "PUBLIC_TO_EVERYONE", "disable_comment": false, "disable_duet": false, "disable_stitch": false, "video_cover_timestamp_ms": 0, "is_aigc": false, "brand_content_toggle": false, "brand_organic_toggle": false, "auto_add_music": false, "first_comment": "Full menu at the link in our bio." }, "x": { "reply_settings": "", "paid_partnership": false, "made_with_ai": false, "poll": { "options": [ "Yes" ], "duration_minutes": 1440 }, "thread_parts": [ { "text": "1/3: our results are in", "media_ids": [ "12345" ] }, { "text": "2/3: grab your free pick at https://example.com/signup" }, { "text": "3/3: and here's the slip", "media_ids": [ "12346" ] } ] }, "bluesky": { "thread_parts": [ { "text": "1/3: our results are in" }, { "text": "2/3: read the full writeup at https://example.com/post" }, { "text": "3/3: thanks for reading! #buildinpublic" } ] }, "mastodon": { "poll": { "options": [ "Yes" ], "expires_in": 86400, "multiple": false, "hide_totals": false }, "thread_parts": [ { "text": "1/3: our picks are in" }, { "text": "2/3: read the full writeup at https://example.com/post" }, { "text": "3/3: thanks for reading! #fediverse" } ] }, "telegram": { "silent": false, "link_preview": true, "pin": true, "protect_content": false, "spoiler": false, "caption_above_media": false, "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "open_period": 86400, "multiple": false }, "first_comment": "Full menu at the link in our bio." }, "discord": { "silent": true, "link_preview": false, "buttons": [ { "text": "Book a table", "url": "https://example.com/book" } ] }, "threads": { "poll": { "options": [ "Yes" ] }, "location_id": "17841400000000000", "location": { "id": "17841400000000000", "name": "Griffith Observatory", "address": "2800 E Observatory Rd", "city": "Los Angeles", "country": "United States" }, "thread_parts": [ { "text": "1/3: our results are in" }, { "text": "2/3: read the full writeup: https://example.com/post" }, { "text": "3/3: thanks for reading! #buildinpublic" } ] }, "google_business": { "topic_type": "STANDARD", "cta": { "actionType": "LEARN_MORE", "url": "https://example.com/book" }, "event": { "title": "Autumn tasting night", "schedule": { "startDate": { "year": 2026, "month": 10, "day": 24 }, "startTime": { "hours": 18, "minutes": 0 }, "endDate": { "year": 2026, "month": 10, "day": 24 }, "endTime": { "hours": 22, "minutes": 0 } } }, "offer": { "couponCode": "AUTUMN20", "redeemOnlineUrl": "https://example.com/offer", "termsConditions": "Valid until 31 October 2026." } } }
json
Example Responses
{ "data": { "id": "1024", "status": "draft", "type": "post", "story_slides": { "key": [ { "index": 0, "native_post_id": "17912345678901234", "url": "url", "media_url": "media_url", "media_type": "image", "published_at": "2026-10-21T09:00:07.000Z" } ] }, "content": { "default": "Our autumn menu is here.", "instagram": "Our autumn menu is here. #autumnmenu" }, "accounts": { "instagram": true, "linkedin_page": true, "facebook": false, "x": false }, "media": { "default": [ { "url": "https://cdn.omnisocials.com/file/library-omnisocials/312a658f-2b45-4289-b240-890807221a74/library/1792573200000-k3j9xq_0c9e6b1a-2f4d-4b8e-a7c3-9d1e5f6a2b70.jpg", "id": "482913", "alt": "A bowl of pumpkin soup on a wooden table" } ] }, "location_id": "1234567890", "collaborators": [ "partnerbrand" ], "user_tags": [ { "username": "partnerbrand", "x": 0.5, "y": 0.8, "image_index": 0 } ], "schedule_at": "2026-10-21T09:00:00.000Z", "app_url": "https://app.omnisocials.com/create-post/1024", "published_urls": { "facebook": "https://www.facebook.com/123456789/posts/987654321", "instagram": "https://www.instagram.com/p/Cxyz123ABC/", "linkedin": "https://www.linkedin.com/feed/update/urn:li:share:7191234567890", "x": "https://x.com/yourhandle/status/1791234567890123456" }, "retry_of": "1023", "retries": [ "1031" ], "created_at": "2026-10-20T14:32:10.000Z", "approval_status": "none", "errors": { "facebook": "Already Posted: These photos were already posted.", "instagram": "Instagram couldn't accept one of your images. Check that every image is JPEG/PNG, at least 320×320, has an aspect ratio between 4:5 and 1.91:1, and isn't visually flagged by Instagram. Re-upload or replace the offending image and try again." }, "source": "api", "updated_at": "2026-10-20T14:35:42.000Z", "x": { "reply_settings": "", "paid_partnership": false, "made_with_ai": false, "poll": { "options": [ "Yes" ], "duration_minutes": 1440 }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "bluesky": { "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "mastodon": { "poll": { "options": [ "Yes" ], "expires_in": 86400, "multiple": false, "hide_totals": false }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "threads": { "poll": { "options": [ "Yes" ] }, "location": { "id": "17841400000000000", "name": "Griffith Observatory", "address": "2800 E Observatory Rd", "city": "Los Angeles", "country": "United States" }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "telegram": { "silent": false, "link_preview": true, "pin": true, "protect_content": false, "spoiler": false, "caption_above_media": false, "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "open_period": 86400, "multiple": false }, "result": { "chat_id": "-1001234567890", "message_ids": [ "42" ], "text_message_id": "43", "pinned": true, "pin_error": "no_right", "link_public": "https://t.me/brand/42", "link_private": "https://t.me/c/1234567890/42", "sent_at": "2026-10-21T09:00:07.000Z" } }, "discord": { "silent": false, "link_preview": true, "allow_mentions": false, "spoiler": false, "thread_name": "October menu", "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "duration_hours": 24, "multiple": false }, "result": { "webhook_id": "1290000000000000000", "guild_id": "1180000000000000000", "channel_id": "1180000000000000001", "thread_id": null, "message_id": "1300000000000000000", "url": "https://discord.com/channels/1180000000000000000/1180000000000000001/1300000000000000000", "sent_at": "2026-10-22T09:00:03.000Z", "video_links": [ "https://www.example.com/path/to/resource" ], "link_message_id": "link_message_id", "warnings": [ "media_sent_as_links" ] } }, "instagram": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "video_cover": { "type": "frame", "thumb_offset": 3000, "overrides": { "linkedin_page": { "type": "custom", "cover_url": "https://example.com/cover.jpg" } } }, "facebook": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "linkedin": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" }, "carousel_as_images": false, "document_source": "slides" }, "linkedin_page": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" }, "carousel_as_images": false, "document_source": "slides" }, "youtube": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "tiktok": { "title": "Autumn menu", "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "comment_dm_automation": { "id": "318", "type": "comment_to_dm", "platform": "instagram", "status": "active", "name": "Guide DM", "post_id": "1024", "instagram_media_id": "17912345678901234", "facebook_post_id": "104857600123456_987654321098765", "post": {}, "trigger": { "kinds": [ "comment" ], "scope": "post", "keywords": [ "guide" ], "match": "word" }, "actions": { "dm": { "text": "Here is the guide: https://example.com/guide" }, "public_reply": { "enabled": true, "variations": [ "Sent you a DM!" ] } }, "limits": { "max_sends": 500, "stop_at": "2026-11-30T23:00:00.000Z" }, "stats": { "matched": 120, "sent": 112, "skipped": 6, "failed": 2, "last_event_at": "2026-10-21T15:00:12.000Z" }, "created_at": "2026-10-20T14:32:10.000Z", "updated_at": "2026-10-20T14:35:42.000Z", "platforms": [ "instagram", "facebook" ], "automations": [ { "id": "318", "platform": "instagram", "status": "active" } ] } }, "warnings": [ { "code": "x_url_post_credits", "message": "message", "credits_required": 20, "credits_balance": 480, "enforced": true, "enforce_from": "2026-08-14" } ] }
json
application/json

Create and publish post

POST
https://api.omnisocials.com/v1
/posts/create-and-publish

Creates a new post and publishes it right away, with 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 post › Request Body

CreatePostRequest
content
​object · required

Post content. Use 'default' for all platforms, or platform-specific keys: instagram, facebook, linkedin, linkedin_page, youtube, tiktok, pinterest, x, threads, bluesky, mastodon, google_business, telegram, discord. Coming soon: reddit, snapchat.

Example: {"default":"Hello world!","instagram":"Hello from IG! #awesome"}
accounts
​string[] · required

Social 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/accounts in 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.

type
​string · enum

Post type: 'post' (feed), 'story' (Instagram/Facebook), 'reel' (Instagram/Facebook/YouTube/TikTok). Telegram and Discord have no reels: a reel that names them is still accepted, and they get the video as a normal post; send a video for them alone as a 'post'. 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. A 'story' takes 1 to 10 media items: each item is one slide, published as its own story in the order given (Instagram and Facebook have no multi-slide story container). More than 10 returns 400 validation_error.

Enum values:
post
story
reel
Default: post
​

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). For type 'story', each item is one slide (max 10, published in order).

​

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, Pinterest, Instagram (images) and LinkedIn (images). 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_at
​string · date-time

ISO 8601 datetime to schedule. Omit for a draft without a date. With draft: true the time is kept but the post stays a draft (a planned draft on the calendar, see draft).

Example: 2026-10-21T09:00:00Z
draft
​boolean

Planned draft. With schedule_at, the post is stored as draft and keeps that time: it shows on the dashboard calendar at that slot with a dashed outline, the scheduler never publishes it, and a person schedules it from the composer (or you do with PATCH /posts/{id} and draft: false). Use it when an agent proposes a slot that a human should confirm. Not allowed with publish_now or approval_workflow_id (400 validation_error). Without schedule_at it changes nothing: that post is a draft already.

Example: true
​object

Image fit per channel, for feed images (type post) whose ratio is outside what a channel shows uncropped. auto (the default when omitted) takes the channel's rule: Instagram crops a tall or wide image to 4:5 / 1.91:1 around the subject (Instagram cuts it to that window anyway, and Meta cannot boost a feed post outside it); Pinterest keeps a Pin taller than 2:3 and only reports it. crop crops for that channel, keep sends the original. Every decision is reported in the response warnings with code: "image_fit". The crop is a file of its own for that channel only; default and the other channels keep the original. On PATCH, media_fit alone (no media) re-decides the stored images: keep gives the original back, crop crops an image that was kept.

Example: {"instagram":"keep"}
publish_now
​boolean

Set true to publish immediately

Example: false
link_url
​string · uri

URL 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).

Example: https://goodlightai.com/blog/new-feature
link_title
​string

Optional 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.

Example: Our autumn menu
link_description
​string

Optional description for the link-share preview. LinkedIn uses this when set; Facebook auto-fetches the OG description. Omit to defer to OG metadata.

Example: Six new dishes, available from today.
link_thumbnail_url
​string · uri

Optional thumbnail image URL for the preview card. LinkedIn uploads this image as the card thumbnail; without it, LinkedIn uses the page's Open Graph image, and when the upload fails the card has no image. Facebook ignores it and uses the page's Open Graph image.

Example: https://example.com/preview.jpg
​VideoCover

Video thumbnail for a post whose media is one video. Applied on Instagram (feed videos and reels), Facebook (feed videos and reels), LinkedIn Profile and Page, TikTok, Pinterest and YouTube Shorts. On YouTube Shorts the cover shows only on channels where YouTube has enabled custom Shorts thumbnails (rolling out since July 2026, YouTube Partner Program channels first); on other channels YouTube stores it as the default thumbnail but shows a frame from the video on Shorts. TikTok only takes a frame, so a custom cover is skipped there (set a tiktok override with type frame to choose the frame). The per-platform reel fields (instagram.thumb_offset / cover_url, tiktok.video_cover_timestamp_ms, pinterest.video_cover) keep working and win over the base cover for their platform.

Example: {"type":"frame","thumb_offset":3000,"overrides":{"linkedin_page":{"type":"custom","cover_url":"https://example.com/cover.jpg"}}}
source
​string

Self-reported origin of the integration creating this post. Defaults to 'api' if omitted. Use 'zapier', 'make', 'n8n', etc. to identify your integration.

Example: zapier
location_id
​string

Instagram 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.

Example: 1234567890
collaborators
​string[] · maxItems: 3

Instagram 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.

Example: ["therock","kevinhart4real"]
​object[]

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.

Example: [{"username":"therock","x":0.5,"y":0.8}]
hashtag_set
​string

Name 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.

Example: Fitness Brand
hashtag_set_id
​string

Id of a saved hashtag set to apply. Same behavior as hashtag_set; pass one or the other.

Example: 57
hashtag_placement
​string · enum

Where 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, TikTok with comments enabled, Telegram), 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).

Enum values:
caption_append
first_comment
Default: caption_append
hashtag_platforms
​string[]

Optional subset of the post's selected platforms to apply the set to (e.g. only ["instagram", "tiktok"]). Defaults to all selected platforms.

approval_workflow_id
​string

Id of an approval workflow (see GET /approval-workflows) to route this post through. The post is created with status in_approval and approval_status: pending instead of scheduled: the workflow's first-step approvers are notified (dashboard badge, email, Slack), they review it in the dashboard's Approvals page, and it publishes at schedule_at only once the last step approves it (dashboard, or POST /posts/{id}/approve). A rejection leaves it rejected. Requires schedule_at; cannot be combined with publish_now. Errors: 404 workflow_not_found (not a workflow of this company/workspace), 400 validation_error (missing schedule_at, publish_now set, or the workflow has no approvers on its first step).

Example: 57823504
comment_dm_automation
​object | null

A comment-to-DM automation bound to this post (Instagram or Facebook must be in accounts). When somebody comments one of trigger.keywords on the post once it is live, the account DMs them actions.dm.text, once per person, and optionally posts one of actions.public_reply.variations under the comment. On a Facebook Page the DM lands in Messenger. The shape is the AutomationInput of POST /automations without post_id, scope or kinds (always this post, comment trigger), plus platforms. The created automations come back as comment_dm_automation on the post. Needs the opt-in automations:write scope on the API key (403 insufficient_scope without it).

Example: {"trigger":{"keywords":["guide"]},"actions":{"dm":{"text":"Here is the guide: https://example.com/guide"},"public_reply":{"enabled":true,"variations":["Sent you a DM!"]}},"limits":{"max_sends":500}}
​object

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 constraints: carousels hard-cap at 5 images: attaching more responds 400 validation_error at create/schedule time. Pinterest's v5 API also 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. Both checks 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.

​object

YouTube Shorts options. Only applies when type is reel and youtube is among the selected accounts.

​object

Instagram Reel options

​object

Facebook options

​object

LinkedIn Profile options

​object

LinkedIn Company Page options

linkedin_poll
​object | null

Non-sponsored LinkedIn poll(s), independent per channel, keyed by linkedin (personal profile) / linkedin_page (company page). A poll is mutually exclusive with media and a link share on that channel's post: a poll takes priority over both at publish time. Requires content.linkedin (or content.default) as that channel's caption/commentary; the poll itself only carries the question/options/duration.

​object

TikTok options

​object

X (Twitter) options

​object

Bluesky options

​object

Mastodon options

​object

Telegram options (2026-10-17). Telegram posts go to the connected channel or group through the OmniSocials bot. Text up to 4,096 characters; with media, text over 1,024 characters is sent as a reply under the media (Telegram's caption limit). Media: up to 10 photos and videos (an album), one GIF, one video up to 50 MB, or files. No Stories. Views are not available to bots: analytics report reactions and subscribers.

​object

Discord options (2026-10-22). Discord posts go to the channel the workspace connected, through that channel's webhook; the message shows the webhook's name and picture. Text up to 2,000 characters. Media: up to 10 images, GIFs and videos in one message (they may mix). A file over Discord's 20 MB attachment limit is sent differently: an image is re-encoded to fit, a video or GIF goes as a link in the text (listed in discord.result.video_links). No Stories; a reel is sent as one video message. Statistics: reactions and poll votes only (Discord gives webhooks no views). A sent message can be deleted at any time.

Example: {"silent":true,"link_preview":false,"buttons":[{"text":"Book a table","url":"https://example.com/book"}]}
​object

Threads options: thread mode via thread_parts, location tag via location_id, poll via poll.

​object

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 post › Responses

Post created and queued for immediate publishing

​Post
POST/posts/create-and-publish
curl -X POST "https://api.omnisocials.com/v1/posts/create-and-publish" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": {"default": "We are live"}, "accounts": ["linkedin", "x"] }'
Example Request Body
{ "content": { "default": "Hello world!", "instagram": "Hello from IG! #awesome" }, "accounts": [ "instagram" ], "type": "post", "media": [ "482913" ], "media_urls": [ "https://example.com/photo.jpg" ], "schedule_at": "2026-10-21T09:00:00Z", "draft": true, "media_fit": { "instagram": "keep" }, "publish_now": false, "link_url": "https://goodlightai.com/blog/new-feature", "link_title": "Our autumn menu", "link_description": "Six new dishes, available from today.", "link_thumbnail_url": "https://example.com/preview.jpg", "video_cover": { "type": "frame", "thumb_offset": 3000, "overrides": { "linkedin_page": { "type": "custom", "cover_url": "https://example.com/cover.jpg" } } }, "source": "zapier", "location_id": "1234567890", "collaborators": [ "therock", "kevinhart4real" ], "user_tags": [ { "username": "therock", "x": 0.5, "y": 0.8 } ], "hashtag_set": "Fitness Brand", "hashtag_set_id": "57", "hashtag_placement": "caption_append", "hashtag_platforms": [ "instagram" ], "approval_workflow_id": "57823504", "comment_dm_automation": { "trigger": { "keywords": [ "guide" ] }, "actions": { "dm": { "text": "Here is the guide: https://example.com/guide" }, "public_reply": { "enabled": true, "variations": [ "Sent you a DM!" ] } }, "limits": { "max_sends": 500 } }, "pinterest": { "board_id": "1234567890123456789", "title": "Autumn menu", "link": "https://example.com/menu", "video_cover": "https://example.com/cover.jpg", "alt_text": "A bowl of pumpkin soup on a wooden table", "product_tags": [ "813744226420795884", "813744226420795885" ], "product_tags_result": { "requested": 2, "tagged": [ "813744226420795884" ], "skipped": [ { "pin_id": "813744226420795885", "reason": "PIN_IS_PRIVATE" } ], "error": "error" } }, "youtube": { "title": "How we plan a week of posts", "tags": [ "social media" ], "privacy_status": "public", "category_id": "22", "made_for_kids": false, "notify_subscribers": false, "contains_synthetic_media": false, "first_comment": "Full menu at the link in our bio." }, "instagram": { "share_to_feed": false, "thumbnail_type": "from-video", "thumb_offset": 3000, "cover_url": "https://example.com/cover.jpg", "audio_id": "587784541076604", "audio_volume": 100, "video_volume": 100, "first_comment": "Full menu at the link in our bio.", "is_trial_reel": false, "trial_graduation_strategy": "MANUAL", "is_ai_generated": false }, "facebook": { "first_comment": "Full menu at the link in our bio.", "thumbnail_type": "from-video", "thumb_offset": 3000, "cover_url": "https://example.com/cover.jpg" }, "linkedin": { "first_comment": "Full menu: https://example.com/menu", "carousel_as_images": false, "document_source": "original_pdf" }, "linkedin_page": { "first_comment": "Full menu: https://example.com/menu", "carousel_as_images": false, "document_source": "original_pdf" }, "linkedin_poll": { "linkedin": { "question": "Which feature should we build next?", "options": [ "Bulk upload" ], "duration": "ONE_DAY" }, "linkedin_page": { "question": "Which feature should we build next?", "options": [ "Bulk upload" ], "duration": "ONE_DAY" } }, "tiktok": { "title": "Autumn menu", "privacy_level": "PUBLIC_TO_EVERYONE", "disable_comment": false, "disable_duet": false, "disable_stitch": false, "video_cover_timestamp_ms": 0, "is_aigc": false, "brand_content_toggle": false, "brand_organic_toggle": false, "auto_add_music": false, "first_comment": "Full menu at the link in our bio." }, "x": { "reply_settings": "", "paid_partnership": false, "made_with_ai": false, "poll": { "options": [ "Yes" ], "duration_minutes": 1440 }, "thread_parts": [ { "text": "1/3: our results are in", "media_ids": [ "12345" ] }, { "text": "2/3: grab your free pick at https://example.com/signup" }, { "text": "3/3: and here's the slip", "media_ids": [ "12346" ] } ] }, "bluesky": { "thread_parts": [ { "text": "1/3: our results are in" }, { "text": "2/3: read the full writeup at https://example.com/post" }, { "text": "3/3: thanks for reading! #buildinpublic" } ] }, "mastodon": { "poll": { "options": [ "Yes" ], "expires_in": 86400, "multiple": false, "hide_totals": false }, "thread_parts": [ { "text": "1/3: our picks are in" }, { "text": "2/3: read the full writeup at https://example.com/post" }, { "text": "3/3: thanks for reading! #fediverse" } ] }, "telegram": { "silent": false, "link_preview": true, "pin": true, "protect_content": false, "spoiler": false, "caption_above_media": false, "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "open_period": 86400, "multiple": false }, "first_comment": "Full menu at the link in our bio." }, "discord": { "silent": true, "link_preview": false, "buttons": [ { "text": "Book a table", "url": "https://example.com/book" } ] }, "threads": { "poll": { "options": [ "Yes" ] }, "location_id": "17841400000000000", "location": { "id": "17841400000000000", "name": "Griffith Observatory", "address": "2800 E Observatory Rd", "city": "Los Angeles", "country": "United States" }, "thread_parts": [ { "text": "1/3: our results are in" }, { "text": "2/3: read the full writeup: https://example.com/post" }, { "text": "3/3: thanks for reading! #buildinpublic" } ] }, "google_business": { "topic_type": "STANDARD", "cta": { "actionType": "LEARN_MORE", "url": "https://example.com/book" }, "event": { "title": "Autumn tasting night", "schedule": { "startDate": { "year": 2026, "month": 10, "day": 24 }, "startTime": { "hours": 18, "minutes": 0 }, "endDate": { "year": 2026, "month": 10, "day": 24 }, "endTime": { "hours": 22, "minutes": 0 } } }, "offer": { "couponCode": "AUTUMN20", "redeemOnlineUrl": "https://example.com/offer", "termsConditions": "Valid until 31 October 2026." } } }
json
Example Responses
{ "data": { "id": "1024", "status": "draft", "type": "post", "story_slides": { "key": [ { "index": 0, "native_post_id": "17912345678901234", "url": "url", "media_url": "media_url", "media_type": "image", "published_at": "2026-10-21T09:00:07.000Z" } ] }, "content": { "default": "Our autumn menu is here.", "instagram": "Our autumn menu is here. #autumnmenu" }, "accounts": { "instagram": true, "linkedin_page": true, "facebook": false, "x": false }, "media": { "default": [ { "url": "https://cdn.omnisocials.com/file/library-omnisocials/312a658f-2b45-4289-b240-890807221a74/library/1792573200000-k3j9xq_0c9e6b1a-2f4d-4b8e-a7c3-9d1e5f6a2b70.jpg", "id": "482913", "alt": "A bowl of pumpkin soup on a wooden table" } ] }, "location_id": "1234567890", "collaborators": [ "partnerbrand" ], "user_tags": [ { "username": "partnerbrand", "x": 0.5, "y": 0.8, "image_index": 0 } ], "schedule_at": "2026-10-21T09:00:00.000Z", "app_url": "https://app.omnisocials.com/create-post/1024", "published_urls": { "facebook": "https://www.facebook.com/123456789/posts/987654321", "instagram": "https://www.instagram.com/p/Cxyz123ABC/", "linkedin": "https://www.linkedin.com/feed/update/urn:li:share:7191234567890", "x": "https://x.com/yourhandle/status/1791234567890123456" }, "retry_of": "1023", "retries": [ "1031" ], "created_at": "2026-10-20T14:32:10.000Z", "approval_status": "none", "errors": { "facebook": "Already Posted: These photos were already posted.", "instagram": "Instagram couldn't accept one of your images. Check that every image is JPEG/PNG, at least 320×320, has an aspect ratio between 4:5 and 1.91:1, and isn't visually flagged by Instagram. Re-upload or replace the offending image and try again." }, "source": "api", "updated_at": "2026-10-20T14:35:42.000Z", "x": { "reply_settings": "", "paid_partnership": false, "made_with_ai": false, "poll": { "options": [ "Yes" ], "duration_minutes": 1440 }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "bluesky": { "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "mastodon": { "poll": { "options": [ "Yes" ], "expires_in": 86400, "multiple": false, "hide_totals": false }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "threads": { "poll": { "options": [ "Yes" ] }, "location": { "id": "17841400000000000", "name": "Griffith Observatory", "address": "2800 E Observatory Rd", "city": "Los Angeles", "country": "United States" }, "thread_parts": [ { "id": "6f1d8e2a-4b7c-4d9e-8a3f-2c5b9e7d1a60", "text": "1/3: our results are in", "media_urls": [ "https://www.example.com/path/to/resource" ] } ] }, "telegram": { "silent": false, "link_preview": true, "pin": true, "protect_content": false, "spoiler": false, "caption_above_media": false, "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "open_period": 86400, "multiple": false }, "result": { "chat_id": "-1001234567890", "message_ids": [ "42" ], "text_message_id": "43", "pinned": true, "pin_error": "no_right", "link_public": "https://t.me/brand/42", "link_private": "https://t.me/c/1234567890/42", "sent_at": "2026-10-21T09:00:07.000Z" } }, "discord": { "silent": false, "link_preview": true, "allow_mentions": false, "spoiler": false, "thread_name": "October menu", "buttons": [ { "text": "See the menu", "url": "https://example.com/menu" } ], "poll": { "options": [ "Yes" ], "duration_hours": 24, "multiple": false }, "result": { "webhook_id": "1290000000000000000", "guild_id": "1180000000000000000", "channel_id": "1180000000000000001", "thread_id": null, "message_id": "1300000000000000000", "url": "https://discord.com/channels/1180000000000000000/1180000000000000001/1300000000000000000", "sent_at": "2026-10-22T09:00:03.000Z", "video_links": [ "https://www.example.com/path/to/resource" ], "link_message_id": "link_message_id", "warnings": [ "media_sent_as_links" ] } }, "instagram": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "video_cover": { "type": "frame", "thumb_offset": 3000, "overrides": { "linkedin_page": { "type": "custom", "cover_url": "https://example.com/cover.jpg" } } }, "facebook": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "linkedin": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" }, "carousel_as_images": false, "document_source": "slides" }, "linkedin_page": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" }, "carousel_as_images": false, "document_source": "slides" }, "youtube": { "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "tiktok": { "title": "Autumn menu", "first_comment": "Full menu at the link in our bio.", "first_comment_result": { "status": "posted", "pending": false, "comment_id": "comment_id", "url": "url", "error": "error", "posted_at": "2026-10-21T09:00:07.000Z" } }, "comment_dm_automation": { "id": "318", "type": "comment_to_dm", "platform": "instagram", "status": "active", "name": "Guide DM", "post_id": "1024", "instagram_media_id": "17912345678901234", "facebook_post_id": "104857600123456_987654321098765", "post": {}, "trigger": { "kinds": [ "comment" ], "scope": "post", "keywords": [ "guide" ], "match": "word" }, "actions": { "dm": { "text": "Here is the guide: https://example.com/guide" }, "public_reply": { "enabled": true, "variations": [ "Sent you a DM!" ] } }, "limits": { "max_sends": 500, "stop_at": "2026-11-30T23:00:00.000Z" }, "stats": { "matched": 120, "sent": 112, "skipped": 6, "failed": 2, "last_event_at": "2026-10-21T15:00:12.000Z" }, "created_at": "2026-10-20T14:32:10.000Z", "updated_at": "2026-10-20T14:35:42.000Z", "platforms": [ "instagram", "facebook" ], "automations": [ { "id": "318", "platform": "instagram", "status": "active" } ] } } }
json
application/json

Publish a post now

POST
https://api.omnisocials.com/v1
/posts/{id}/publish

Publish a post now › path Parameters

id
​string · required

Publish a post now › Responses

Post queued for publishing

​object
POST/posts/{id}/publish
curl -X POST "https://api.omnisocials.com/v1/posts/12345/publish" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY"
Example Responses
{ "data": { "id": "1024", "status": "posting", "message": "Post queued for immediate publishing." } }
json
application/json

Retry failed post

POST
https://api.omnisocials.com/v1
/posts/{id}/retry

Re-publishes ONLY the platforms that failed, on the same post. Platforms that already succeeded are never re-published. Works on posts with status failed (every platform failed) or warning (some platforms failed). The retry is processed asynchronously by the publishing queue, usually within a minute; poll GET /posts/{id} to see the outcome (status becomes published and published_urls gains the platform URL on success, or the platform's entry reappears in errors on another failure). Each platform can be retried at most 3 times; after that, create a new post. Platforms dismissed with 'ignore' in the dashboard are not retried.

Retry failed post › path Parameters

id
​string · required

Retry failed post › Responses

Retry queued

​object
POST/posts/{id}/retry
curl -X POST "https://api.omnisocials.com/v1/posts/12345/retry" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY"
Example Responses
{ "data": { "id": "1024", "status": "posting", "platforms": [ "instagram" ], "message": "message" } }
json
application/json

Approve a post

POST
https://api.omnisocials.com/v1
/posts/{id}/approve

Approves the current step of the post's approval workflow, on behalf of the user who owns this API key. That user must be a listed approver for the workflow's CURRENT step. Steps are approved in order, and a key holder who is only an approver on a later step gets forbidden until earlier steps clear. If this is the last step, the post is finalized immediately: it moves to scheduled (future schedule_at) or posting (due now or in the past). If more steps remain, the post stays in_approval and the next step's approvers are notified. Check approval_status on GET /posts/{id} first: only a post with status in_approval can be approved.

Approve a post › path Parameters

id
​string · required

Approve a post › Responses

Approval recorded

​object
POST/posts/{id}/approve
curl -X POST "https://api.omnisocials.com/v1/posts/12345/approve" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY"
Example Responses
{ "data": { "id": "1024", "status": "scheduled", "approval_status": "pending", "message": "message" } }
json
application/json

Reject a post

POST
https://api.omnisocials.com/v1
/posts/{id}/reject

Rejects the post's approval workflow on behalf of the user who owns this API key. That user must be a listed approver for the workflow's CURRENT step. Unlike approval, a rejection stops the whole workflow immediately (not just the current step), and the post's status becomes rejected. An optional comment explaining the rejection is stored on the decision and posted into the post's review thread.

Reject a post › path Parameters

id
​string · required

Reject a post › Request Body optional

comment
​string · maxLength: 2000

Optional reason for the rejection, shown to the requester and other approvers.

Example: Wrong product photo

Reject a post › Responses

Rejection recorded

​object
POST/posts/{id}/reject
curl -X POST "https://api.omnisocials.com/v1/posts/12345/reject" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"comment": "Wrong CTA link, please fix."}'
Example Request Body
{ "comment": "Wrong product photo" }
json
Example Responses
{ "data": { "id": "1024", "status": "rejected", "approval_status": "rejected", "message": "message" } }
json
application/json

Get approval review

GET
https://api.omnisocials.com/v1
/posts/{id}/approval

Returns the review of a post that went through an approval workflow: every step with its approvers and their decisions, the rejection with its reason, and the comment thread. Use it after approval_status is rejected to learn who rejected the post and why, or while it is pending to see who the post waits for and what the reviewers wrote. A post without an approval workflow returns status: none with empty steps and comments.

Get approval review › path Parameters

id
​string · required

Post ID

Example: 1024

Get approval review › Responses

The approval review

​object
GET/posts/{id}/approval
curl "https://api.omnisocials.com/v1/posts/12345/approval" \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY"
Example Responses
{ "data": { "post_id": "123456", "status": "rejected", "workflow": { "id": "42", "name": "Content approval" }, "requested_by": { "id": "7d1f3c52-9a4e-4b6f-8c21-5e0a9d3b7f14", "name": "Alex" }, "requested_at": "2026-10-01T09:00:00.000Z", "current_step": null, "steps": [ { "order": 1, "name": "Team review", "require_mode": "any", "status": "approved", "approvers": [ { "id": "2b8e6f90-1c3d-4a57-9e84-6f2d0b1c3a75", "name": "Sam", "email": "[email protected]", "status": "approved", "decided_at": "2026-10-01T10:15:00.000Z", "comment": null } ] }, { "order": 2, "name": "Client approval", "require_mode": "all", "status": "rejected", "approvers": [ { "id": "c4a09e1d-7b52-4f38-a6d1-3e9f8b2c5d60", "name": "Jordan", "email": "[email protected]", "status": "rejected", "decided_at": "2026-10-01T14:30:00.000Z", "comment": "The image does not match the caption" } ] } ], "rejection": { "by": { "id": "c4a09e1d-7b52-4f38-a6d1-3e9f8b2c5d60", "name": "Jordan" }, "reason": "The image does not match the caption", "at": "2026-10-01T14:30:00.000Z", "step": 2 }, "comments": [ { "id": "5f3a2b1c-8d7e-4c69-b0a4-1e2d3c4b5a69", "author": { "id": "c4a09e1d-7b52-4f38-a6d1-3e9f8b2c5d60", "name": "Jordan" }, "message": "Please use the new logo", "account": "instagram", "created_at": "2026-10-01T14:28:00.000Z" } ] } }
json
application/json

Media