Guides
Cross-platform posting
One request, several channels: shared copy, per-platform variants, per-platform settings, per-account results.
A post is one group. content is the copy every channel gets; variants overrides it per platform; platformSettings tunes delivery per platform; targets reports the result per account.
Pick connections, not platforms
connectionIds is the only way to say where a post goes. The post's platforms array is derived from the connections you named. Two LinkedIn pages are two connection ids on one post.
Fit every channel
Each target is checked against its platform's limits at creation: X takes 280 characters, Bluesky 300 graphemes, LinkedIn 3,000. When the shared copy is too long for one channel, give that channel a variant instead of shortening everything.
curl -X POST https://api.overads.io/public/v1/posts -H "Authorization: Bearer sk_live_YOUR_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"content": "We rebuilt the scheduler from the ground up. Per-account delivery logs, approvals, webhooks, and an MCP server so your assistant can post for you. Full notes on the blog.",
"connectionIds": ["LINKEDIN_ID", "X_ID", "BLUESKY_ID", "MASTODON_ID"],
"variants": {
"twitter": { "content": "The scheduler is new: per-account delivery logs, approvals, webhooks, MCP. Notes: overads.io/blog" },
"bluesky": { "content": "The scheduler is new: per-account delivery logs, approvals, webhooks, MCP. overads.io/blog" }
},
"platformSettings": {
"linkedin": { "visibility": "PUBLIC" },
"mastodon": { "visibility": "public", "language": "en" }
},
"scheduledAt": "2026-09-14T16:00:00Z"
}'Settings for a platform the post does not target are refused with PLATFORM_SETTING_UNKNOWN, because a script that sends LinkedIn settings to an X-only post has the wrong connection id and should hear so.
Read the result per account
After delivery, GET /posts/:id carries one target per connection. The group status is published when every target landed, partial_published when some did, failed when none did. A failed target has the platform's error text in error; the others have postedId and permalink.
{
"status": "partial_published",
"targets": [
{ "platform": "linkedin", "status": "published", "postedId": "urn:li:share:7241…", "permalink": "https://www.linkedin.com/feed/update/urn:li:share:7241…", "error": null },
{ "platform": "twitter", "status": "failed", "postedId": null, "permalink": null, "error": "403 Forbidden: Your account is not permitted to create tweets." }
]
}Subscribe to post.published and post.failed to be told per target instead of polling.
Media across channels
One mediaUrls list is attached to every target, and each channel's rules are applied to it: Bluesky takes up to 4 images or one video (never both), YouTube exactly one video, Pinterest one image or one video with an optional cover image. A list that breaks one channel's rule is refused for the whole post. Split into two posts when the channels want different media.