Skip to content
Developers · REST API, MCP server and webhooks

The Setupe API for your apps and AI agents. One request, every channel.

Create, schedule and publish posts to Instagram, TikTok, LinkedIn, YouTube, X and 15 more networks from your own code, or let AI assistants do it through our hosted MCP server. Get a signed webhook when a post goes live or fails. Included with Automation on Setupe plans.

curl -X POST "https://setupe.com/api/automation/v1/posts" \
  -H "Authorization: Bearer $SETUPE_API_KEY" \
  -H "Idempotency-Key: launch-2026-11-20" \
  -H "Content-Type: application/json" \
  -d '{
    "account_ids": [12, 15, 18],
    "caption": "Meet our autumn blend. Out tomorrow.",
    "media_urls": ["https://example.com/launch.jpg"],
    "mode": "scheduled",
    "schedule_at": "2026-11-20T09:00:00",
    "timezone": "Europe/London"
  }'
201 Created POST /posts
{
  "ok": true,
  "data": [
    { "id": 9041, "account_id": 12, "status": 3, "scheduled_at": "2026-11-20T09:00:00+00:00" },
    { "id": 9042, "account_id": 15, "status": 3, "scheduled_at": "2026-11-20T09:00:00+00:00" },
    { "id": 9043, "account_id": 18, "status": 3, "scheduled_at": "2026-11-20T09:00:00+00:00" }
  ]
}

REST API

JSON over HTTPS. Check your key, list your connected accounts, and create drafts, scheduled posts or instant posts.

MCP server

Hosted tools for Claude, ChatGPT, Cursor and any MCP client. Sign in with OAuth, no key to paste.

Webhooks

post.created, post.published and post.failed, sent to your URL and signed with HMAC-SHA256. Failed deliveries are retried.

Safe to retry

Every post request carries an Idempotency-Key. Send the same request twice and you get the first answer back, never a double post.

Post to every channel with one API call

Three steps, about five minutes.

Create an API key

In Setupe, open Developer and create a key. It starts with spauto_ and is shown once: keep it in your server secrets, never in a browser.

Get your account ids

Connect your social accounts in the Setupe dashboard, one sign-in per network. GET /accounts lists them with their ids.

Send the post

Pick one or many accounts, then save it as a draft, schedule it for a time, or publish it now.

GET /accounts
curl "https://setupe.com/api/automation/v1/accounts" \
  -H "Authorization: Bearer $SETUPE_API_KEY"
{
  "ok": true,
  "data": [
    { "id": 12, "provider_key": "instagram",
      "display_name": "Northbeam Coffee", "username": "northbeam.coffee" },
    { "id": 15, "provider_key": "linkedin",
      "display_name": "Northbeam Coffee", "username": "" }
  ]
}
GET /me
curl "https://setupe.com/api/automation/v1/me" \
  -H "Authorization: Bearer $SETUPE_API_KEY"
{
  "ok": true,
  "workspace_owner_user_id": 1,
  "team_id": 4,
  "permissions": ["posts:write", "accounts:read"]
}

Authentication and permissions

Send your key on every request as Authorization: Bearer spauto_…. The X-Automation-Key header works too. A key belongs to the workspace it was created in. Revoke it any time from the same Developer page. Call the API from a server or script, not from a web page, because the key is a secret.

PermissionAllowsDefault
accounts:readGET /accounts: list the connected accounts you can post to.On
posts:writePOST /posts as a draft or a scheduled post.On
posts:publishPOST /posts with mode publish_now, which sends the post straight away.Off

Base URL: https://setupe.com/api/automation/v1. Every response is JSON with "ok": true or "ok": false and a message.

POST /posts

Creates one post per account in account_ids. The Idempotency-Key header is required: 8 to 255 characters with no spaces, such as a UUID. Reuse the same key when you retry. A repeat returns the first response with Idempotency-Replayed: true.

FieldTypeDescription
account_idsRequiredarray of integersOne or more account ids from GET /accounts. One post is created per account.
captionOptionalstringThe post text. Up to 5,000 characters.
media_urlsOptionalarray of URLsUp to 10 public http(s) links to photos or videos.
modeOptionalstringdraft, scheduled (the default) or publish_now. publish_now needs the posts:publish permission.
schedule_atFor scheduledstringA future date and time, e.g. 2026-11-20T09:00:00. Read in timezone, or include a UTC offset.
timezoneOptionalstringAn IANA timezone such as Europe/London. Defaults to your workspace timezone.
campaign_idOptionalintegerAdd the post to one of your campaigns.
label_idsOptionalarray of integersLabels to tag the post with.
network_optionsOptionalobjectExtra settings per network, keyed by network, e.g. { "tiktok": { … } }.
notesOptionalstringInternal notes for your team. Up to 1,000 characters.
sourceOptionalstringA label for where the post came from, e.g. zapier or my-app.
external_referenceOptionalstringYour own id for the post, so you can match it later.

Post status codes: 1 draft, 2 processing, 3 scheduled, 4 published, 5 failed.

StatusMeaningWhen
201CreatedThe posts were created. The body lists one entry per account.
400Bad requestThe Idempotency-Key header is missing or not valid.
401UnauthorizedThe API key is missing, wrong or revoked.
403ForbiddenThe key lacks the permission, or your plan does not include Automation.
409ConflictThe Idempotency-Key was used with a different body, or the first request is still running.
422UnprocessableA field is not valid. The errors object says which one.
429Too many requestsSlow down and try again shortly.

Webhooks

Add a webhook URL on the Developer page and pick the events you want. Setupe sends a JSON POST each time one happens. Each webhook has its own signing secret.

EventSent when
post.createdA post is created through the API.
post.publishedA post goes live on the network.
post.failedA post could not be published. The payload includes the error.
HeaderValue
X-Automation-EventThe event name
X-Automation-Request-IdUnique per delivery. Stays the same on retries, so you can skip duplicates.
X-Automation-TimestampUnix time in seconds
X-Automation-Signaturesha256=HMAC of timestamp + "." + body
Verify the signature (Node.js)
import crypto from "node:crypto";

function verify(rawBody, headers, secret) {
  const ts = headers["x-automation-timestamp"];
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(ts + "." + rawBody)
    .digest("hex");
  const given = headers["x-automation-signature"] || "";
  return given.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}
Example payload: post.published
{
  "event": "post.published",
  "occurred_at": "2026-11-20T09:00:04+00:00",
  "post": {
    "id": 9041, "status": 4, "status_key": "published",
    "caption": "Meet our autumn blend. Out tomorrow.",
    "account_id": 12, "provider_key": "instagram",
    "remote_post_id": "17985…", "url": "https://www.instagram.com/p/…",
    "error": null
  },
  "account": { "id": 12, "username": "northbeam.coffee", "provider_key": "instagram" }
}

Delivery: answer with any 2xx status within 20 seconds. If your server times out, returns 408 or 429, or returns a 5xx error, Setupe tries again after 30 seconds, then after 2 minutes, for 3 attempts in total. Redirects are not followed, so use the final URL.

What the API supports on each network

Accounts are connected in the Setupe dashboard through our own approved apps. There is no developer app for you to register and no review to pass on each network.

NetworkAccount typeWhat a post can carryAPI
InstagramProfessional accountA photo, a video published as a Reel, or a carousel of photos and videos. Media required.Available
TikTokAny accountA video, or a photo post. Media required.Available
LinkedInPersonal profiles and company pagesText with a photo or a video.Available
YouTubeChannelA video, titled from the first line of the caption.Available
XAny accountText with photos, a GIF or a video. Keep text to 280 characters.Available
FacebookPagesText, photos or a video.Available
ThreadsProfileText, a photo or a video.Available
PinterestAccount and boardA photo or a video Pin, titled from the first line. Media required.Available
BlueskyAccountText up to 300 characters, with photos or a video.Available
RedditUser account and subredditA text post (first line is the title) or a link post.Available
TelegramChannel, with our bot as adminText, or a photo or video with a caption.Available
DiscordChannel webhookText with photos.Available
SlackOne channel, picked when adding our appText with photos.Available
MastodonAccount on any serverText (500 characters on most servers) with photos or a video.Available
WordPressSelf-hosted site, Author or aboveA blog post titled from the first line. The first photo becomes the featured image.Available
MediumAccount, with an integration tokenA story titled from the first line. The first photo is the cover.Available
DEVAccount, with its API keyAn article titled from the first line, Markdown body. No video.Available
HashnodeBlog, with a personal access tokenAn article titled from the first line, Markdown body. No video.Available
TumblrMain, side and group blogsText, with photos or a video.Available
Google Business ProfileVerified locations you manageAn update with text and one photo. No video.Available

Media goes in as public links in media_urls, up to 10 per post. Use links that do not expire before the post goes out. Each network still applies its own limits on text length and file size.

MCP server for AI assistants

Setupe runs a hosted Model Context Protocol server at https://setupe.com/mcp. Add it to Claude, ChatGPT, Cursor or any MCP client, sign in to Setupe once with OAuth, and ask in plain words: "schedule this for Tuesday at 9 on Instagram and LinkedIn" or "how did last week's posts do?".

// Settings → Connectors → Add custom connector
Name: Setupe
URL:  https://setupe.com/mcp
ToolWhat it does
list_accountsList the social accounts connected to your workspace.
create_postDraft, schedule or publish a post to one or many accounts.
list_postsFind scheduled, published and failed posts by date or account.
update_postChange the caption, media or time of a scheduled post.
delete_postRemove a draft or a scheduled post.
get_analyticsReach, engagement and follower growth per account or post.
next_free_slotFind the next open time in your posting schedule.
generate_captionWrite a caption in your brand voice with Setupe AI.

Safe by default: the assistant only sees the workspaces you approve when you sign in, and you can disconnect it any time from the Developer page in Setupe.

Built for AI agents

Connect through the MCP server, or give your agent the REST endpoints as tools. Because every post needs an Idempotency-Key, an agent that retries never posts twice. Keep the agent on drafts with a posts:write key, and let a person publish from the Setupe calendar.

Drafts for review

Send "mode": "draft" and the post waits in Setupe for a person to check it.

Automation workflows

Chain AI writing, approval, a delay and scheduling on the visual Automation canvas, no code needed.

Trace every post

Set source and external_reference to see which agent or app created each post.

Start building with Setupe

Create a key, connect your accounts and send your first post in minutes. Questions about the API? We are happy to help.

Scan to get started on Setupe

QR code to sign up for Setupe