create_and_publish_post
Create a new post and publish it immediately (no scheduling). Same media rules, channel IDs, and workspace selection rule as create_post apply (only one workspace → use it; multiple workspaces with no named one → ask first; named workspace → use and remember; mention workspace name on success). linkedin (personal profile) and linkedin_page (company page) are independent channels.
Pinterest board (auto-default to first board): If Pinterest is in channels and pinterest.board_id is NOT provided, do NOT block on asking — and do NOT skip Pinterest. Call get_account on the Pinterest account, take the FIRST board from the returned boards list, and pass its id as pinterest.board_id. In your reply, mention which board you used (e.g. "Published to your 'Marketing' board on Pinterest — let me know if you'd prefer a different one.") so the user can redirect. If the user named a specific board in the request, match it (case-insensitive) against the list and use that one instead.
X threads: For a chained X thread, pass x.thread_parts (2–25 { text } parts, each <= 280 chars). Do NOT split into "1/", "2/" inside content — that posts a single tweet, not a thread.
X posts containing a link use credits: X's API charges more for posts whose text contains a URL; OmniSocials passes that platform fee through as credits from the organisation's existing balance. Only a link written with http:// or https:// counts; a bare domain or www. link is free. Credits are only deducted once the post publishes successfully (a failed publish is never charged) — if the balance can't cover it at publish time, the X target alone fails and explains the shortfall while other platforms still publish. Relay any x_url_post_credits warning and X failure to the user; never strip their link to avoid the fee without asking. If the balance (minus credits reserved by scheduled X link posts) can't cover this post, the request is refused up front with a 402 x_credits_insufficient error instead of failing at publish — tell the user their X credit balance is too low for this post, don't retry.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | X (Twitter) options, including thread mode via `thread_parts`. | |
| type | No | ||
| tiktok | No | TikTok options | |
| bluesky | No | Bluesky options, including thread mode via `thread_parts`. | |
| content | Yes | Post caption. String or object with platform keys for per-channel captions: { "default": "fallback", "linkedin": "long", "threads": "short" }. Prefer one call per topic. | |
| threads | No | Threads options: thread mode via `thread_parts`, location tag via `location_id`. | |
| youtube | No | YouTube Shorts options. Only applies when type is 'reel' and youtube is among the selected channels. A custom Shorts thumbnail is set with the top-level `video_cover` (a `youtube` override for a YouTube-only image); it shows on Shorts only on channels where YouTube has enabled custom Shorts thumbnails (Partner Program channels first, since July 2026), other channels show a frame from the video. | |
| channels | No | Array of channel IDs to post to (e.g. linkedin, linkedin_page, instagram). | |
| No | Facebook options | ||
| link_url | No | URL to share as a rich preview card on platforms that support link-share posts (LinkedIn and Facebook). Renders as a tile with thumbnail/title/description instead of plain text. Ignored on platforms that don't support link shares, and ignored on posts that already have media attached (media wins). | |
| No | LinkedIn Profile options | ||
| mastodon | No | Mastodon options, including thread mode via `thread_parts`. | |
| No | Instagram options | ||
| media_ids | No | ||
| No | |||
| user_tags | No | Instagram only. Tag public accounts at x/y positions on a PHOTO (not video/reels/stories). For a single image omit image_index; for a carousel, set image_index to the slide each tag belongs to. Private/non-existent usernames are rejected at publish time. Ignored by other platforms. | |
| link_title | No | Optional title for the link-share preview. LinkedIn uses this when set; Facebook ignores it and fetches OG metadata server-side. Omit to let LinkedIn auto-fetch the page title. | |
| media_urls | No | External image/video/PDF URLs — flat array or per-platform object. Max 10 total (Pinterest: max 5 images per carousel pin), each file ≤ 100 MB. Entries are URL strings or { url, alt } objects (alt = accessibility description, delivered to Mastodon/Bluesky/X/Pinterest/Instagram (images)/LinkedIn (images)). For larger files (up to 1 GB): upload_media with method 'url' first, then pass the returned media id in `media`. | |
| hashtag_set | No | Name of a saved hashtag set (from list_hashtag_sets, matched case-insensitively) to apply to this post. The set's tags are merged in once at create time; tags already present in a caption are skipped. When the user says something like 'add my usual hashtags', check list_hashtag_sets first. Instagram's 30-hashtag cap is enforced with a clear error (hashtag_limit_exceeded). | |
| location_id | No | Instagram only. Facebook Place ID for a single physical venue (with a street address) to tag the post's location. Find it via the location search in the OmniSocials dashboard. Ignored by other platforms. | |
| video_cover | No | 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. YouTube Shorts: the cover shows on Shorts only on channels where YouTube has enabled custom Shorts thumbnails (rolling out since July 2026, Partner Program channels first); on other channels YouTube stores it as the default thumbnail but shows a frame from the video on Shorts. Say that it depends on the channel; do not promise it. TikTok only takes a frame: a 'custom' cover is skipped there, so add a tiktok override with type 'frame' when the user wants a specific TikTok 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. get_post reads it back as `video_cover`. | |
| collaborators | No | Instagram only. Up to 3 public Instagram usernames to invite as co-authors (the 'Collab' feature). Works on image, carousel, and reel posts — NOT Stories. Invited users get an invite in the Instagram app; once they accept, the post also appears on their profile and feed. A leading '@' is stripped; usernames are case-insensitive. Private or non-existent usernames are rejected by Instagram at publish time. Ignored by other platforms. | |
| linkedin_page | No | LinkedIn Company Page options | |
| linkedin_poll | No | 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. Still requires `content.linkedin` (or `content.default`) as that channel's caption; the poll itself only carries the question/options/duration. On update_post, set a channel's key to `null` to clear that channel's poll and revert it to a normal post — send the full desired state for both channels, since the whole object replaces wholesale. | |
| google_business | No | Google Business Profile options. Use to publish EVENT or OFFER posts, attach a CTA button, or both. Shape mirrors Google's LocalPost resource (see https://developers.google.com/my-business/reference/rest/v4/accounts.locations.localPosts#LocalPost). Google Business caption rules (enforced at scheduling — text that violates these will return a `validation_error` 400 before the post is saved): • Phone numbers in the caption are rejected — use a CALL button instead. • Inline URLs / bare domains / emails are rejected — use LEARN_MORE / BOOK / SHOP / SIGN_UP / ORDER buttons instead. • Caption max 1500 characters. • Media is optional (text-only posts are 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 — otherwise returns a 400. | |
| link_description | No | Optional description for the link-share preview. LinkedIn uses this when set; Facebook auto-fetches the OG description. | |
| hashtag_placement | No | Where the set's tags land. caption_append (default): appended to each target caption after a blank line. first_comment: posted as the auto first comment on Instagram/Facebook/LinkedIn/LinkedIn Page/YouTube/TikTok (TikTok only when the workspace enabled TikTok comments) (keeps hashtags out of the caption — appended after any explicit first_comment); platforms without a comment API fall back to caption_append. Stories always use captions. | |
| hashtag_platforms | No | Optional subset of the post's channels to apply the hashtag set to (e.g. ["instagram", "tiktok"]). Defaults to all selected channels. | |
| link_thumbnail_url | No | Optional thumbnail image URL for the preview card. Currently applied on Facebook; reserved for LinkedIn. |