API reference
Posts
Create, list, edit, cancel and publish posts, and read the per-account delivery log.
Base URL https://api.overads.io/public/v1. Every route needs a key with the scope shown, sent as Authorization: Bearer sk_live_YOUR_KEY. The machine-readable contract is at https://api.overads.io/public/v1/openapi.json, no key needed. Scope for this family: posts:read, posts:write.
The post model
A post is one group with one content string, optional per-platform variants, media, and a targets list with one row per connection. status describes the group; each target carries its own status, postedId, permalink and error, so a post that reached two of three accounts is partial_published with the failure named on the third target.
status | Meaning |
|---|---|
draft | Saved, no scheduledAt. |
scheduled | Queued for scheduledAt. |
publishing | Delivery is running. |
published | Every target landed. |
partial_published | Some targets landed, some failed. |
failed | No target landed. |
cancelled | Cancelled before delivery. |
approvalStatus is none, pending, approved or rejected. A pending post does not publish until a member approves it; see Scheduling and approvals.
POST/posts
Scope posts:write. Create a draft, or a scheduled post when scheduledAt is set.
Answers 201 with { data, warnings }. When the workspace requires approval for scheduled posts the post lands with approvalStatus: "pending" and warnings carries APPROVAL_REQUIRED.
Platform limits (characters, media counts, required media) are checked here, so an over-limit post is refused at creation rather than at the scheduled minute. See the platform pages.
| Body | Type | Meaning | |
|---|---|---|---|
content | string | required | The shared copy, 1 to 10,000 characters. Per-platform overrides go in variants. |
connectionIds | string[] | required | 1 to 20 connection ids from GET /connections. |
scheduledAt | ISO 8601 | optional | When to publish. Omit for a draft. Up to five minutes in the past is moved to now with a SCHEDULED_TIME_COERCED warning; earlier is SCHEDULED_TIME_IN_PAST. |
mediaUrls | string[] | optional | Up to 10 public https image or video URLs. Downloaded server-side into overads storage. A URL already in overads storage is used as-is. |
mediaIds | string[] | optional | Up to 10 ids of media completed through POST /media/:id/complete. |
platformSettings | object | optional | Per-platform delivery settings keyed by platform, for example { "linkedin": { "visibility": "PUBLIC" } }. Unknown keys are refused with PLATFORM_SETTING_UNKNOWN. Settings for a platform the post does not target are refused too. |
variants | object | optional | Per-platform copy overrides: { "twitter": { "content": "..." } }. |
requireApproval | boolean | optional | Queue the scheduled post for approval even when the workspace does not require it. |
Response: { data: Post, warnings: Warning[] }. Post carries targets, one row per connection.
{
"data": {
"id": "b6a0f6b2-1d0e-4d4a-8f2f-0c1f2a3b4c5d",
"content": "Shipping day. Full notes on the blog.",
"variants": null,
"mediaUrls": ["https://media.overads.io/social-media/.../launch.jpg"],
"platforms": ["linkedin", "twitter"],
"connectionIds": ["3f1c…", "9a77…"],
"status": "scheduled",
"approvalStatus": "none",
"scheduledAt": "2026-09-14T16:00:00.000Z",
"publishedAt": null,
"platformSettings": null,
"platformPostIds": null,
"error": null,
"createdAt": "2026-09-11T09:30:12.000Z",
"updatedAt": "2026-09-11T09:30:12.000Z",
"targets": [
{ "id": "…", "connectionId": "3f1c…", "platform": "linkedin", "status": "pending", "postedId": null, "permalink": null, "error": null, "attempts": 0, "publishedAt": null, "updatedAt": "…" },
{ "id": "…", "connectionId": "9a77…", "platform": "twitter", "status": "pending", "postedId": null, "permalink": null, "error": null, "attempts": 0, "publishedAt": null, "updatedAt": "…" }
]
},
"warnings": []
}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": "Shipping day. Full notes on the blog.",
"connectionIds": ["3f1c1a2e-6b2a-4a0e-9a5f-0d5a7d0f2b11"],
"scheduledAt": "2026-09-14T16:00:00Z",
"variants": { "twitter": { "content": "Shipping day. Notes: overads.io/blog" } }
}'GET/posts
Scope posts:read. List posts, newest first.
| Query | Type | Meaning | |
|---|---|---|---|
status | enum | optional | draft, scheduled, publishing, published, partial_published, failed or cancelled. |
platform | string | optional | One platform id, for example linkedin. |
from | ISO 8601 | optional | Lower bound on scheduledAt. |
to | ISO 8601 | optional | Upper bound on scheduledAt. |
page | integer | optional | Default 1. |
limit | integer | optional | Default 50, max 200. |
Response: { data: Post[], page, limit, total }. Rows in the list do not carry targets; read one post for those.
curl "https://api.overads.io/public/v1/posts?status=scheduled&limit=20" -H "Authorization: Bearer sk_live_YOUR_KEY"GET/posts/:id
Scope posts:read. One post with its per-account delivery log in targets.
Response: { data: Post }.
curl https://api.overads.io/public/v1/posts/b6a0f6b2-1d0e-4d4a-8f2f-0c1f2a3b4c5d -H "Authorization: Bearer sk_live_YOUR_KEY"PATCH/posts/:id
Scope posts:write. Edit a draft or scheduled post. Only the fields you send change.
Takes the same fields as create, all optional. Refused with POST_NOT_EDITABLE once the post is publishing, published, partially published or cancelled.
Scheduling a draft through this edit applies the workspace approval rule the same way create does, with the same APPROVAL_REQUIRED warning.
Response: { data: Post, warnings: Warning[] }.
curl -X PATCH https://api.overads.io/public/v1/posts/b6a0f6b2-1d0e-4d4a-8f2f-0c1f2a3b4c5d -H "Authorization: Bearer sk_live_YOUR_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{ "scheduledAt": "2026-09-15T09:00:00Z" }'DELETE/posts/:id
Scope posts:write. Cancel a draft or scheduled post. The row is kept with status: "cancelled".
Nothing is removed from any platform. A post that already published cannot be cancelled (POST_NOT_EDITABLE).
Response: { data: Post, warnings: [] }.
curl -X DELETE https://api.overads.io/public/v1/posts/b6a0f6b2-1d0e-4d4a-8f2f-0c1f2a3b4c5d -H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Idempotency-Key: $(uuidgen)"POST/posts/:id/publish
Scope posts:write. Publish now and wait for the outcome.
Refused with APPROVAL_REQUIRED (409) while the post is pending approval; a member approves it in the app. The call returns when delivery has been attempted on every target, so read targets for the per-account result.
Response: { data: Post, warnings: [] } with targets filled in: postedId and permalink on success, error verbatim from the platform on failure.
curl -X POST https://api.overads.io/public/v1/posts/b6a0f6b2-1d0e-4d4a-8f2f-0c1f2a3b4c5d/publish -H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Idempotency-Key: $(uuidgen)"GET/posts/:id/targets
Scope posts:read. The per-account delivery log for one post.
Response: { data: Target[] }. Each target has connectionId, platform, status, postedId, permalink, error, attempts, publishedAt, updatedAt.
curl https://api.overads.io/public/v1/posts/b6a0f6b2-1d0e-4d4a-8f2f-0c1f2a3b4c5d/targets -H "Authorization: Bearer sk_live_YOUR_KEY"