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
Overview
Get started
SDKs
CLI
MCPDocs for AI agentsWebhooks
Guides
Platforms
Integrations
Migrate
    From AyrshareFrom ZernioFrom Upload-PostFrom Postiz
Plans and billing
GlossaryChangelogAPI reference
Migrate

Migrate from the Postiz public API to the OmniSocials API

This guide is for developers who post through the Postiz public API, on Postiz Cloud or a self-hosted instance, and want to move to the OmniSocials API. In Postiz, one request carries a separate entry for each channel, with its own text, media, and settings. In OmniSocials, one post lists its channels in accounts, and per-channel text and options sit in objects keyed by channel ID. Scheduling moves from a type field to schedule_at and publish_now. Social accounts are connected in the OmniSocials dashboard. Postiz facts on this page come from docs.postiz.com and were checked on October 21, 2026.

Concepts

PostizOmniSocialsNotes
API key (Authorization: your-api-key, no Bearer)API key (Authorization: Bearer omsk_live_...)
Organization (the key reaches all its channels)Workspace (the key reaches one workspace)Create one key per workspace.
Customer (GET /groups)WorkspaceGive each customer its own workspace and key.
Integration (a channel) with an idAccount with an id, or the bare channel IDA workspace has one account per channel ID.
Connect URL (GET /social/{integration})Dashboard connectionAccounts are connected only in the dashboard, never through the API.
One posts[] entry per integrationOne post with an accounts arrayOne post id covers every channel.
Extra value[] entries (thread or comments)thread_parts on X, Bluesky, Mastodon, and Threads, or first_commentSee Threads and comments.
settings.__type and its fieldsA top-level object named after the channelFor example x, pinterest, youtube.
type: draft, schedule, nowNo schedule_at, schedule_at, publish_now: true
States QUEUE, PUBLISHED, ERROR, DRAFTscheduled, published (or warning), failed, draftwarning means some channels published and some failed.
TagsNone
Find slotGET /analytics/best-timesRecommended slots from your own history. You pick the time.

Authentication

Text
Postiz: Authorization: your-api-key OmniSocials: Authorization: Bearer omsk_live_...

Postiz takes the raw key in the header. OmniSocials needs the Bearer prefix. A Postiz key reaches every channel of the organization. An OmniSocials key is bound to one workspace, chosen when you create the key under Settings → API. GET /accounts returns workspace_id and workspace_name, so you can check which workspace a key belongs to.

Keys have scopes, such as posts:write and media:write. A key's scopes cannot be edited later. See Authentication.

Endpoint mapping

OmniSocials paths are relative to https://api.omnisocials.com/v1. Postiz paths are relative to https://api.postiz.com/public/v1 on Postiz Cloud, or https://{your-domain}/api/public/v1 when self-hosted.

PostizOmniSocialsNotes
POST /postsPOST /posts/createPOST /posts is an alias. POST /posts/create-and-publish publishes at once.
GET /postsGET /postsNo date range. Filter with status and page with limit (max 100) and offset, newest first.
DELETE /posts/{id}DELETE /posts/{id}Removes the post from OmniSocials and cancels a scheduled publish. It does not delete a live post on the platform.
DELETE /posts/group/{group}DELETE /posts/{id}One post covers all its channels, so there is no group.
PUT /posts/{id}/statusPATCH /posts/{id}Send draft: true to unschedule, or draft: false to schedule a draft that has a schedule_at.
PUT /posts/{id}/settingsPATCH /posts/{id}Drafts and scheduled posts only. Any create field can change.
GET /integrationsGET /accountsReturns the key's workspace and its accounts, with status and needs_reconnect.
GET /is-connected, GET /meGET /accountsA 200 means the key works.
GET /groupsNoneEach customer becomes a workspace with its own key.
GET /social/{integration}NoneConnect accounts in the dashboard.
DELETE /integrations/{id}NoneDisconnect accounts in the dashboard.
GET /find-slot/{id}GET /analytics/best-timesRecommendations, not the next free slot.
POST /uploadPOST /media/uploadMultipart with a file field, up to 100 MB.
POST /upload-from-urlPOST /media/upload-from-urlSame { "url": "..." } body. Up to 1 GB.
GET /media/{id}/statusGET /media/{id}Wait for status: "ready".
GET /mediaGET /mediaSearch with search and filter with folder_id.
GET /analytics/{integration}GET /analytics/accountsGET /analytics/overview gives workspace totals.
GET /analytics/post/{postId}GET /analytics/posts/{id}GET /analytics/posts?ids= takes up to 100 post IDs.
GET /notificationsNoneUse webhooks or poll GET /posts?status=failed.
POST /generate-video, POST /video/function, clipping endpointsNone

Create a post

The same post in both APIs: a tweet scheduled for 08:00 UTC on November 2, 2026, that everyone can reply to.

Postiz:

TerminalTerminal
curl -X POST https://api.postiz.com/public/v1/posts \ -H "Authorization: $POSTIZ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "schedule", "date": "2026-11-02T08:00:00.000Z", "shortLink": false, "tags": [], "posts": [ { "integration": { "id": "your-x-integration-id" }, "value": [{ "content": "We shipped dark mode today.", "image": [] }], "settings": { "__type": "x", "who_can_reply_post": "everyone" } } ] }'

OmniSocials:

TerminalTerminal
curl -X POST https://api.omnisocials.com/v1/posts/create \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": "We shipped dark mode today.", "accounts": ["x"], "schedule_at": "2026-11-02T08:00:00Z" }'

Everyone can reply by default. To limit replies, set x.reply_settings to following or mentionedUsers.

To post to more channels, add them to accounts. Where Postiz needs a second posts[] entry for different text, OmniSocials uses one content object:

JSON
{ "content": { "default": "We shipped dark mode today.", "linkedin": "We shipped dark mode today. Here is what changed for teams." }, "accounts": ["x", "linkedin", "bluesky"], "schedule_at": "2026-11-02T08:00:00Z" }

The response is a 201 with one post under data, not an array per channel. After publishing, published_urls on GET /posts/{id} maps each channel to its live URL.

Field mapping

Postiz fieldOmniSocials fieldNotes
type: "now"publish_now: trueOr call POST /posts/create-and-publish.
type: "schedule" with dateschedule_atISO 8601 in UTC. Alias: scheduled_at.
type: "draft"Leave out schedule_at and publish_nowdraft: true with schedule_at keeps the time on the calendar without publishing.
posts[].integration.idaccountsAccount id from GET /accounts, or the channel ID. Alias: channels.
posts[].value[0].contentcontent, or content.<channel> for one channel
posts[].value[0].image[]media_ids or media_urlsUse the id from an OmniSocials upload, or pass public URLs. Per-channel media is an object keyed by channel.
image[].thumbnailTimestampvideo_covertype: "frame" with thumb_offset in milliseconds.
posts[].value[1..]x.thread_parts and the like, or first_commentSee below.
posts[].settingsA top-level object named after the channel
settings.__typeThe channel IDRename linkedin-page to linkedin_page and gmb to google_business.
who_can_reply_post (X)x.reply_settingsfollowing or mentionedUsers. Leave it out for everyone.
shortLinkNoneLinks are posted as written.
tagsNone
posts[].groupNone

Threads and comments

In Postiz, extra entries in value become a thread or comments, depending on the platform. OmniSocials splits these two cases:

  • Threads on X, Bluesky, Mastodon, and Threads use thread_parts under the channel key. Each part has text and optional media_ids or media_urls. A thread has 2 to 25 parts.
  • One first comment on Instagram, Facebook, LinkedIn, YouTube, TikTok, and Telegram uses first_comment under the channel key. It is text only.
JSON
{ "content": "We shipped dark mode today.", "accounts": ["x", "instagram"], "media_urls": ["https://example.com/dark-mode.png"], "x": { "thread_parts": [ { "text": "We shipped dark mode today." }, { "text": "It follows your system setting by default." } ] }, "instagram": { "first_comment": "Update the app to try it." } }

Chains of more than one comment have no equivalent. See X threads for the details.

Media and scheduling

Media. The upload calls map one to one. POST /media/upload takes a multipart file, and POST /media/upload-from-url takes { "url": "..." }. Both return the media record under data. Reference it on a post with media_ids: ["<data.id>"]. There is no path to send along. You can also skip uploads and pass public URLs in media_urls, up to 10 files of 100 MB each.

OmniSocials accepts JPEG, PNG, GIF, WebP, HEIC, MP4, MOV, AVI, and PDF. AVIF, BMP, and TIFF are not on that list, so convert them first. A PDF is turned into one image per page. On LinkedIn it publishes as a document. See Media.

Scheduling. Send schedule_at as an ISO 8601 time in UTC. OmniSocials publishes within one minute of that time. A time in the past returns 400 validation_error. To publish now, send publish_now: true.

Webhooks

Postiz webhooks are set up in the app, under Settings, and fire when a post publishes. OmniSocials webhooks are registered through the API with POST /webhooks. The response returns a secret once. Store it.

TerminalTerminal
curl -X POST https://api.omnisocials.com/v1/webhooks \ -H "Authorization: Bearer $OMNISOCIALS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.com/webhooks/omnisocials", "events": ["post.published", "post.failed"] }'
EventWhen it fires
post.scheduledA post is scheduled through the API
post.publishedAt least one channel published. A partial publish has data.status set to warning
post.failedEvery channel failed
post.approvedThe last step of an approval workflow approved the post
post.rejectedAn approver rejected the post

Every delivery is signed. X-OmniSocials-Signature: t=<timestamp>,v1=<hex> is an HMAC-SHA256 of the timestamp, a dot, and the raw body, keyed with your webhook secret. Verify it before you trust the payload, and deduplicate on X-OmniSocials-Delivery. Answer with a 2xx within 10 seconds. Failed deliveries are retried twice. See Webhooks for verification code.

Platform coverage

As of October 21, 2026, from docs.postiz.com and the OmniSocials platforms page.

PlatformPostizOmniSocials
FacebookYes (facebook)Yes (facebook), Pages
InstagramYes (instagram, instagram-standalone)Yes (instagram), Business and Creator accounts
ThreadsYes (threads)Yes (threads)
LinkedInYes, profile (linkedin) and page (linkedin-page)Yes, profile (linkedin) and page (linkedin_page)
YouTubeYes (youtube)Shorts only (youtube)
TikTokYes (tiktok)Yes (tiktok)
PinterestYes (pinterest)Yes (pinterest)
BlueskyYes (bluesky)Yes (bluesky)
MastodonYes (mastodon)Yes (mastodon)
XYes (x)Yes (x)
Google Business ProfileYes (gmb)Yes (google_business)
TelegramYes (telegram)Yes (telegram), a channel or group
RedditYes (reddit)Coming soon
SnapchatNot listedComing soon
Discord, SlackYesNo
Farcaster, Nostr, VK, LemmyYesNo
Twitch, KickYesNo
Dribbble, Medium, Dev.to, Hashnode, WordPress, Tumblr, MeWeYesNo
Listmonk, Moltbook, Skool, WhopYesNo

What is different

  • Hosted only. OmniSocials has no self-hosted version.
  • Account connection. OmniSocials has no connect-URL endpoint. Accounts are connected in the dashboard.
  • One key per workspace. A Postiz key reaches the whole organization. An OmniSocials key reaches one workspace, so a multi-customer setup needs one key per customer.
  • One account per channel. A workspace holds one account per channel ID. Two X accounts need two workspaces.
  • One post, many channels. Per-channel text and settings live in objects keyed by channel, not in separate entries.
  • Threads and comments. Threads work on X, Bluesky, Mastodon, and Threads. Other channels get one text-only first comment.
  • Rate limit. OmniSocials allows 100 requests per minute per key, on every endpoint. Postiz limits only POST /posts, per organization and per hour. Its docs give 30 and 90 requests per hour on different pages, and self-hosted instances set the value with API_LIMIT. See Rate limits and errors.
  • No tags, link shortening, video generation, or clipping.
  • GET /posts has no date range. Page through with status, limit, and offset.
  • X links. X posts whose text contains a link use prepaid credits. Posts without a link do not. See X.
  • Fewer channels. The channels in the last rows of the table above are not part of OmniSocials. YouTube is Shorts only, and Reddit is not live yet.
  • No test mode. On OmniSocials, use drafts or a workspace with test accounts.
  • What OmniSocials adds. Signed webhooks registered through the API, a Social inbox API for DMs and comments, approval workflows, alt text per image, PDF to carousel, hashtag sets, Instagram comment-to-DM automations, and SDKs in 8 languages.

Migration steps

  1. Create an OmniSocials account. Add one workspace per Postiz customer, or one for the whole organization if you use no customers.
  2. Connect each social account in the dashboard, under Settings → Organisation → Workspaces.
  3. Create one API key per workspace under Settings → API. Start with posts:write, posts:read, media:write, accounts:read, and webhooks:manage.
  4. Call GET /accounts with each key. Map every Postiz integration id to an OmniSocials channel ID or account id.
  5. Change the base URL and add Bearer before the key.
  6. Rewrite the post body. Merge the posts[] entries into one accounts array and one content object, and move settings to channel keys. Use the field mapping table.
  7. Re-upload media with POST /media/upload or POST /media/upload-from-url, and reference it with media_ids.
  8. Register your webhooks with POST /webhooks, and add signature verification.
  9. Recreate the posts that are still queued in Postiz with schedule_at. Then delete them in Postiz with DELETE /posts/{id}, so nothing publishes twice.
  10. Test with drafts first, since there is no test mode. Then publish one post with publish_now: true and check published_urls on GET /posts/{id}.

Posts without schedule_at or publish_now are drafts and never publish on their own. Use them to check your field mapping against real accounts.

Last modified on October 21, 2026
From Upload-PostPricing
On this page
  • Concepts
  • Authentication
  • Endpoint mapping
  • Create a post
  • Field mapping
  • Threads and comments
  • Media and scheduling
  • Webhooks
  • Platform coverage
  • What is different
  • Migration steps
JSON
JSON