Post from your own code
A small REST API over the same pipeline the app uses — including the pre-flight checks and the per-network delivery isolation. JSON in, JSON out, bearer auth.
One request shape covers all 11 networks we support. 5 publish for anyone today, the rest are clearing each platform's review — the status page says exactly which, and your integration does not change as they clear.
Authentication
Create a key in the app under API keys. It is shown once — we store only a hash, so it cannot be recovered afterwards. Send it as a bearer token.
Authorization: Bearer pilot_your_key_hereEndpoints
/api/v1/accountsThe accounts this key can post to./api/v1/postsRecent posts and where each one landed, per network./api/v1/mediaUpload an image or video — multipart or by URL — and get an id back./api/v1/postsCreate a post — queue it, schedule it, or publish immediately.Upload media, get an id back
Most posts carry an image or a video. Upload it once to /api/v1/media and attach the returned id to any post. When the bytes are on your machine, send multipart form-data:
curl -X POST https://attentionpilot.com/api/v1/media \
-H "Authorization: Bearer $PILOT_API_KEY" \
-F "[email protected]"When the file is already hosted somewhere — the common case for an agent that just generated an image — send JSON with a url instead and we fetch it:
curl -X POST https://attentionpilot.com/api/v1/media \
-H "Authorization: Bearer $PILOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://cdn.example.com/launch.jpg"}'Both return 201 with the stored file. filename, width, height and durationMs are optional on either path — send them if you already know them, skip them if you don't.
{
"media": {
"id": "9b2e…",
"filename": "launch.jpg",
"kind": "image",
"mime": "image/jpeg",
"size": 184320,
"width": null, "height": null, "durationMs": null
}
}Post to every network
Attach media ids with media — the order you list them is the carousel order. Omit schedule and it drops into your next free queue slot. Pass "now" to publish immediately, or an ISO timestamp for a specific time.
curl -X POST https://attentionpilot.com/api/v1/posts \
-H "Authorization: Bearer $PILOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"caption": "We shipped per-network retries today.",
"media": ["9b2e…"],
"accounts": "all"
}'On some networks media is not optional: Instagram, TikTok and Pinterest will not accept a text-only post at all, and YouTube needs a video. Target one of them without the right attachment and pre-flight rejects the request with a 422 naming the network — before anything is scheduled.
Pick networks by name
accounts takes account ids, platform names, or handles — whichever you have to hand.
{
"caption": "Short version for the fast networks.",
"accounts": ["x", "bluesky", "threads"],
"schedule": "2026-08-01T09:00:00Z"
}What comes back
Publishing immediately returns the per-network outcome, because each network succeeds or fails on its own. A partly-published post is a normal result, not an error.
{
"id": "0f3c…",
"status": "partial",
"targets": [
{ "platform": "bluesky", "status": "posted",
"url": "https://bsky.app/profile/you/post/3k…" },
{ "platform": "x", "status": "failed",
"error": "312 chars — X allows 280." }
]
}Errors worth handling
400Bad body, unknown accounts, or an unparseable schedule.401The key is missing, malformed or revoked.402The workspace has more connected accounts than its billing covers. Posts are never metered — disconnect an account or add billing, then retry.422Pre-flight failed — the response lists which network and why.Live: the same API over MCP
Point Claude or any MCP client at https://attentionpilot.com/api/mcp with your key as a bearer token and the agent gets the same capabilities — list accounts, add media, create a post, read back the delivery. Setup takes one config block.
Posting is an API call. Make one.
Start freeOne account free. No card.