Start
Getting started
Create a key, schedule a post with one request, then plug the same key into your AI assistant.
Everything lives under https://api.overads.io/public/v1. The same key works for REST, for the MCP server and for outbound webhooks. Three steps, about five minutes.
1. Create a key
Open Settings > API Keys & MCP in the app, pick the scopes the integration needs, set an expiry if you want one, and copy the key. It starts with sk_live_ and is shown once. A key belongs to one workspace and only ever sees that workspace.
Keys are included on the Growth and Scale plans. On a plan without API access the key is minted but every call answers 402.
2. Find a connection, then post
A post targets connection ids, not platform names. List them first.
curl https://api.overads.io/public/v1/connections \
-H "Authorization: Bearer sk_live_YOUR_KEY"Take an id whose tokenStatus is valid, then create a scheduled post. scheduledAt is ISO 8601; leave it out to save a draft instead.
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: launch-2026-09-14-a" \
-d '{
"content": "Shipping day. Full notes on the blog.",
"connectionIds": ["3f1c1a2e-6b2a-4a0e-9a5f-0d5a7d0f2b11"],
"scheduledAt": "2026-09-14T16:00:00Z",
"mediaUrls": ["https://cdn.example.com/launch.jpg"]
}'The answer is 201 with the post and a warnings list. Read the warnings: they are the things that happened without failing the call.
{
"data": {
"id": "b6a0…",
"status": "scheduled",
"approvalStatus": "pending",
"scheduledAt": "2026-09-14T16:00:00.000Z",
"platforms": ["linkedin"],
"targets": [
{ "connectionId": "3f1c…", "platform": "linkedin", "status": "pending", "postedId": null, "permalink": null }
]
},
"warnings": [
{ "code": "APPROVAL_REQUIRED", "message": "This workspace requires approval for scheduled posts. The post is queued as pending and will not publish until a member approves it in the app." }
]
}An APPROVAL_REQUIRED warning means the workspace has the approval switch on. The post is real and scheduled; a member approves it in the app. Read Scheduling and approvals for the full rule.
3. Give your assistant the same key
The MCP server is at https://api.overads.io/public/v1/mcp. For Claude Code that is one line:
claude mcp add --transport http overads https://api.overads.io/public/v1/mcp --header "Authorization: Bearer sk_live_YOUR_KEY"Every other client (Claude Desktop, Cursor, VS Code, Codex, Windsurf, n8n, Zapier) is on the MCP page. The tools the assistant sees are the ones the key is scoped for.
Where next
- Authentication: scopes, expiry, what each status code means.
- Posts: every field on the create call, variants, per-platform settings.
- Webhooks: get told when a post lands instead of polling.
- OpenAPI: the machine-readable contract, no key needed.
Other languages
The API is plain JSON over HTTPS, so any HTTP client works. Two equivalents of the create call above.
const res = await fetch("https://api.overads.io/public/v1/posts", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.OVERADS_API_KEY,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
content: "Shipping day. Full notes on the blog.",
connectionIds: ["3f1c1a2e-6b2a-4a0e-9a5f-0d5a7d0f2b11"],
scheduledAt: "2026-09-14T16:00:00Z",
}),
});
const { data, warnings } = await res.json();import os, uuid, requests
r = requests.post(
"https://api.overads.io/public/v1/posts",
headers={
"Authorization": f"Bearer {os.environ['OVERADS_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"content": "Shipping day. Full notes on the blog.",
"connectionIds": ["3f1c1a2e-6b2a-4a0e-9a5f-0d5a7d0f2b11"],
"scheduledAt": "2026-09-14T16:00:00Z",
},
timeout=30,
)
body = r.json()
print(r.status_code, body.get("warnings"))