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
    Posting commandsInbox commandsAnalytics commandsPlatform commandsManagement commands
MCPDocs for AI agentsWebhooks
Guides
Platforms
Integrations
Migrate
Plans and billing
GlossaryChangelogAPI reference
CLI

CLI posting commands

Create, schedule, publish, update, and delete posts from the command line. All commands honor the global flags and print JSON with --json.

Commands

CommandDescription
posts:listList posts. Flags: --status <draft|in_approval|scheduled|published|failed|rejected>, --limit, --offset. A post that waits for approval or was rejected prints an Approval: line that names posts:approval <id>
posts:get <id>Full details for one post
posts:createCreate a draft or scheduled post. --text is required
posts:create-and-publishCreate a post and publish it immediately (no --schedule)
posts:update <id>Update a draft or scheduled post; takes the same flags as posts:create
posts:publish <id>Publish an existing draft or scheduled post now
posts:retry <id>Retry only the failed platforms of a failed or warning post; succeeded channels are never re-posted (max 3 retries per platform)
posts:approve <id>Approve the current step of a post's approval workflow (approval_status: "pending"). You must be a listed approver for that step; steps approve in order
posts:reject <id>Reject a post's approval workflow, stopping it immediately (not just the current step). Flag: --comment "..." (optional, shown to the requester and other approvers)
posts:approval <id>Read the review of a post that went through an approval workflow: the step it waits on and who still has to decide, who rejected it and why, every step with each approver's decision, and the comment thread. Read-only; --json returns the full review object
posts:delete <id>Delete a post (irreversible)
posts:recent-platformFetch recent posts live from the connected platforms, including content published outside OmniSocials. Flags: --limit (1-50, default 25; X defaults to 10 unless set explicitly), --platforms <a,b>. X results may be served from a snapshot up to 24h old (X bills per returned post); it refreshes right after you publish to X through OmniSocials. Requires the analytics:read scope

Post options

For posts:create, posts:create-and-publish, and posts:update:

FlagDescription
--text <str>Caption / post content (required on create)
--channels <a,b>Comma-separated channel ids
--type <post|story|reel>Content type (default post)
--schedule <ISO8601>Schedule time, e.g. 2026-08-01T09:00:00Z
--draftWith --schedule: store a planned draft that keeps the time but is not scheduled (a person confirms it in the dashboard, or posts:update <id> --no-draft). On posts:update alone, --draft unschedules a scheduled post and keeps its time
--no-draftposts:update only: schedule a planned draft at the time it already carries
--media-urls <url,url>Attach media by URL
--media-ids <id,id>Attach media from the library
--media-fit <ch=action,...>What happens to a feed image outside what a channel shows uncropped, per channel: instagram=keep,pinterest=crop. Actions auto (default), crop, keep. Without it Instagram crops a 9:16 image to 4:5 around the subject and Pinterest keeps a Pin taller than 2:3; every decision is printed as a warning after the post is created. On posts:update alone, re-decides the stored images (keep gives the original back). See Image fit per channel
--link-url <url>Link-preview card (LinkedIn / Facebook)
--link-title <str>Override the link-preview title
--link-description <str>Override the link-preview description
--link-thumbnail-url <url>Override the link-preview thumbnail
--location-id <id>Instagram place tag (find ids with locations:search)
--collaborators <a,b>Instagram co-author usernames (max 3)
--user-tags '<json>'Instagram photo tags: JSON array of {"username","x","y","image_index?"}
--x-thread "a || b || c"X thread; parts split on ||
--bluesky-thread "a || b || c"Bluesky thread
--mastodon-thread "a || b || c"Mastodon thread
--threads-thread "a || b || c"Threads thread (Meta Threads)
--video-cover-json '<json>'Thumbnail for a post whose media is one video: {"type":"frame","thumb_offset":3000} (milliseconds into the video) or {"type":"custom","cover_url":"https://..."}, plus optional "overrides" keyed by platform. Applied on Instagram, Facebook, LinkedIn, TikTok (frame only), Pinterest and YouTube Shorts (channel-dependent, see below). The literal value null removes it on update. See Creating reels
--threads-location-id <id>Threads place tag, rolling out (find ids with locations:search --platform threads; the literal value null clears the tag on update)

Platform-specific flags

Instagram

FlagDescription
--instagram-share-to-feedAlso share the reel to the feed
--instagram-cover-urlCustom reel thumbnail URL
--instagram-thumbnail-typefrom-video or from-library
--instagram-thumb-offsetVideo timestamp in ms (for from-video)
--instagram-audio-idLicensed music for reels (find ids with audio:search)
--instagram-audio-volumeMusic volume 0-100
--instagram-video-volumeOriginal audio volume 0-100 (0 = music only)
--instagram-first-commentFirst comment (not for stories)
--instagram-trial-reelPublish as a trial reel (roughly 1,000+ followers required)
--instagram-trial-graduation-strategyMANUAL or SS_PERFORMANCE

YouTube

FlagDescription
--youtube-titleVideo title
--youtube-privacypublic, private, or unlisted
--youtube-tagsComma-separated tags
--youtube-category-idCategory ID
--youtube-made-for-kidsMark as made for kids
--youtube-notify-subscribersNotify subscribers on publish
--youtube-contains-synthetic-mediaMark as AI-generated
--youtube-first-commentFirst comment (video must allow comments)

A custom thumbnail (--video-cover-json) shows on a Short only on channels where YouTube has enabled custom Shorts thumbnails (Partner Program channels first). Other channels show a frame from the video.

TikTok

FlagDescription
--tiktok-privacyPUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY
--tiktok-disable-commentDisable comments
--tiktok-disable-duetDisable duets
--tiktok-disable-stitchDisable stitches
--tiktok-video-cover-timestamp-msCover frame timestamp in ms
--tiktok-is-aigcMark as AI-generated content
--tiktok-brand-content-togglePaid partnership disclosure
--tiktok-brand-organic-toggleOwn-brand disclosure
--tiktok-auto-add-musicAuto-add music to photo carousels
--tiktok-titleTitle of a photo carousel (max 90 characters; ignored on video)
--tiktok-first-commentFirst comment on the video (max 150 characters; needs comments enabled on the TikTok channel, and the video must be public)

Pinterest

FlagDescription
--pinterest-board-idBoard ID (required for Pinterest; find it with accounts:get)
--pinterest-titlePin title
--pinterest-linkDestination URL
--pinterest-video-coverCover image URL for video pins
--pinterest-alt-textAccessibility alt text
--pinterest-product-tagsProducts to tag on the Pin: comma-separated Pin IDs or Pin links of your own product Pins, max 24 (find ids with pinterest:products)

Product tags are added right after the Pin is published. Pinterest accepts a product only when its Pin is public, belongs to the same Pinterest account and links to a website that account claimed. A product that Pinterest refuses never fails the post. After publishing, posts:list prints the outcome as Pinterest products: 1 of 2 tagged (skipped: <pin_id> PIN_IS_PRIVATE), and posts:get returns it as pinterest.product_tags_result. On posts:update the Pinterest flags replace the stored Pinterest options as one object, so pass them all again; leaving --pinterest-product-tags out removes the tags.

Other platforms

FlagDescription
--facebook-first-commentFirst comment on the page post
--linkedin-first-commentFirst comment on a personal profile post
--linkedin-page-first-commentFirst comment on a company page post
--linkedin-carousel-as-imagestrue = publish 2+ images as a plain gallery instead of the default document carousel (profile post)
--linkedin-page-carousel-as-imagesSame for the company page post
--linkedin-document-sourceoriginal_pdf (default) or slides. When the images are the unchanged pages of one uploaded PDF, the default sends that original file to LinkedIn; slides rebuilds the document from the slide images (profile post)
--linkedin-page-document-sourceSame for the company page post
--x-reply-settingsfollowing or mentionedUsers (empty = everyone)
--google-business-cta-actionGoogle Business button: LEARN_MORE, BOOK, ORDER, SHOP, SIGN_UP, or CALL
--google-business-cta-urlButton link, http(s):// (required for every action except CALL)
--google-business-topic-typeSTANDARD (default), EVENT, or OFFER
--google-business-jsonThe full google_business object, for EVENT and OFFER posts (an offer needs event.title and event.schedule.startDate too, see Google Business)

Telegram

FlagDescription
--telegram-silentSend without a notification sound
--telegram-link-preview falseHide the link preview of a text-only post (shown by default)
--telegram-pinPin the post in the chat (needs the bot's Edit messages right in a channel, Pin messages in a group)
--telegram-protectStop forwarding and saving of the post
--telegram-spoilerBlur the photos and videos until someone taps them
--telegram-caption-aboveShow the text above the media
--telegram-buttons-json '<json>'Up to 3 link buttons: [{"text":"Shop now","url":"https://..."}]. Not on an album or a poll
--telegram-first-commentA silent reply under the post (max 4,096 characters)
--telegram-json '<json>'The full telegram object, merged over the flags

See Telegram for the rules.

Discord

FlagDescription
--discord-silentSend without a push or desktop notification
--discord-no-link-previewHide the previews of the links in the text (shown by default)
--discord-allow-mentionsLet @everyone, @here, role and user mentions in the text ping. Off by default: they show as text and ping nobody
--discord-spoilerBlur every image and video until someone clicks it
--discord-thread-name "<title>"The post title in a forum or media channel (1 to 100 characters). Required there; on a text channel the post goes out without it
--discord-button "text|url"A link button (label up to 80 characters, https:// or http:// link). Repeat the flag for up to 5. Not with a poll
--discord-json '<json>'The full discord object, merged over the flags

See Discord for the rules.

Polls

Each flag takes one JSON object, and the post text is the question (LinkedIn polls carry their own question). A poll and media do not go together: X, Threads, Mastodon, Telegram and Discord refuse the request, and on LinkedIn the poll wins over the media. On a thread the poll goes on the first part. On posts:update, the literal value null removes the poll.

FlagDescription
--linkedin-poll-json '<json>'LinkedIn polls, independent per channel: {"linkedin":{"question":"...","options":["...","..."],"duration":"SEVEN_DAYS"},"linkedin_page":{...}}. Question max 140 characters, 2 to 4 options of up to 30, duration ONE_DAY, THREE_DAYS, SEVEN_DAYS or FOURTEEN_DAYS
--x-poll-json '<json>'{"options":["A","B"],"duration_minutes":1440}: 2 to 4 options of up to 25 characters, 5 to 10080 minutes (default 1440)
--threads-poll-json '<json>'{"options":["A","B"]}: 2 to 4 options of 1 to 25 characters; Threads closes the poll after 24 hours. Text-only posts
--mastodon-poll-json '<json>'{"options":["A","B"],"expires_in":86400,"multiple":false,"hide_totals":false}, within the instance's limits (expires_in defaults to 86400)
--telegram-poll-json '<json>'{"options":["A","B"],"open_period":86400,"multiple":false}: 2 to 12 options of up to 100 characters, 5 to 2628000 seconds (leave it out to keep the poll open); the question is max 300 characters
--discord-poll-json '<json>'{"options":["A","B"],"duration_hours":24,"multiple":false}: 2 to 10 options of up to 55 characters, 1 to 768 hours (default 24); the question is max 300 characters. No buttons with a poll

See Polls for the rules.

Comment to DM (Instagram and Facebook)

These flags attach a comment-to-DM automation to the post: whoever comments one of the keywords gets a DM, once per person. Instagram or Facebook must be in --channels, and the key needs the automations:write scope. On Facebook the DM lands in Messenger.

FlagDescription
--dm-keywords <a,b>The keywords
--dm-message "<text>"The DM to send (max 1000 characters)
--dm-reply "<text>"Public reply under the comment; repeat the flag (or pass a comma list) for up to 10 variations
--dm-match <word|contains|any>word (default): the keyword on its own; contains: anywhere; any: every comment
--dm-max-sends <n>Stop after this many DMs
--dm-stop-at <ISO8601>Stop at this time
--dm-platforms <instagram,facebook>The channels that get the automation, one each with the same keywords and DM. Each must be in --channels. Leave it out for Instagram when the post goes there, else Facebook. On posts:update a channel left out loses its automation

Examples

Schedule an image post to Instagram and LinkedIn:

TerminalTerminal
omnisocials posts:create \ --text "Launch day! Here is what we built." \ --channels instagram,linkedin \ --media-urls https://example.com/launch.jpg \ --schedule 2026-08-01T09:00:00Z

Publish an X thread right away:

TerminalTerminal
omnisocials posts:create-and-publish \ --channels x \ --text "How we cut our posting time by 90%" \ --x-thread "How we cut our posting time by 90% || Step 1: stop copy-pasting between tabs || Step 2: automate the boring parts"

Publish a reel with licensed music:

TerminalTerminal
omnisocials audio:search "summer vibes" omnisocials posts:create-and-publish \ --type reel \ --channels instagram \ --text "POV: your content calendar fills itself" \ --media-urls https://example.com/reel.mp4 \ --instagram-audio-id 123456789 \ --instagram-video-volume 0

Tag products on a Pinterest Pin:

TerminalTerminal
omnisocials pinterest:products omnisocials posts:create \ --text "Autumn outfit" \ --channels pinterest \ --media-urls https://example.com/outfit.jpg \ --pinterest-board-id 1234567890 \ --pinterest-product-tags 813744226420795884,813744226420795885

Find out why a post was rejected, or who it waits for:

TerminalTerminal
omnisocials posts:list --status rejected omnisocials posts:approval 123456
Text
Approval review for post 123456 ──────────────────────────────────────── Status: rejected Workflow: Content approval (ID: 42) Requested by: Alex at 2026-10-01T09:00:00.000Z Rejected by: Jordan on step 2 at 2026-10-01T14:30:00.000Z Reason: The image does not match the caption Steps Step 1: Team review [any one approves]: approved Sam: approved at 2026-10-01T10:15:00.000Z Step 2: Client approval [all must approve]: rejected Jordan: rejected at 2026-10-01T14:30:00.000Z ("The image does not match the caption") Comments (1, oldest first) 2026-10-01T14:28:00.000Z Jordan [instagram]: Please use the new logo

While a post is still in review, the same command prints a Waiting on: line with the current step and the approvers who still have to decide.

Ask your X and Threads followers a question:

TerminalTerminal
omnisocials posts:create \ --text "Which feature should we build next?" \ --channels x,threads \ --x-poll-json '{"options":["Polls","Reports","Ads"],"duration_minutes":1440}' \ --threads-poll-json '{"options":["Polls","Reports","Ads"]}'

Check what went out recently, straight from the platforms:

TerminalTerminal
omnisocials posts:recent-platform --platforms instagram,tiktok --limit 10
Last modified on October 22, 2026
CLIInbox commands
On this page
  • Commands
  • Post options
  • Platform-specific flags
    • Instagram
    • YouTube
    • TikTok
    • Pinterest
    • Other platforms
    • Telegram
    • Discord
    • Polls
    • Comment to DM (Instagram and Facebook)
  • Examples