Post to social from your own code, or from your agent.

Cadenus holds the connections to Instagram, Facebook, TikTok, LinkedIn, YouTube and X. You get three ways to use them: an MCP server your agent can call, a small skill for agents in a terminal, and four plain HTTP calls for everything else.

Same accounts, same rules, one token.

Endpoints at a glance

Base URL
https://app.cadenus.io/api
MCP server
https://app.cadenus.io/api/mcp
29 tools
Auth
OAuth 2.1 one click,
or Bearer cdn_…
Scopes
read · write
Rate limit
120 MCP calls / minute
Upload ceiling
300 MB per file

Connect your agent.

Pick the client you actually use. Publishing needs the full MCP server and write access. The ChatGPT apps connection does not include publishing tools.

Claude Code
MCP · one click

Add the server, then approve access in the browser. No token to copy.

$ claude mcp add --transport http \ cadenus https://app.cadenus.io/api/mcp # then, inside the session /mcp # pick Cadenus, Authenticate, approve
Claude web and desktop
MCP · one click

Settings, then Connectors, then Add custom connector. Paste the URL and sign in.

https://app.cadenus.io/api/mcp # Claude registers itself and opens our # consent screen. You choose read or write.
ChatGPT
MCP · one click

Settings, Connectors, Create. Use the apps mount: it hides the four tools that publish, because ChatGPT reviews connectors that post on your behalf.

https://app.cadenus.io/api/mcp-apps # 25 tools. Drafting and reading, not posting. # Use /api/mcp anywhere else for all 29.
Codex
MCP · token

Add it to ~/.codex/config.toml with a token from Settings.

[mcp_servers.cadenus] url = "https://app.cadenus.io/api/mcp" http_headers = { Authorization = "Bearer cdn_…" }
OpenClaw
Skill · shell

OpenClaw has your files and a shell, so give it the skill, not a connector. It reads the skill file and runs the script.

$ export CADENUS_TOKEN=cdn_… $ cadenus post ./clip.mp4 --to tiktok \ --caption "…"
n8nMakecron
REST

Anything that can send an HTTP request. Four calls, described below.

$ curl -X POST https://app.cadenus.io/api/agent/posts \ -H "Authorization: Bearer $CADENUS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"caption":"…","channels":["tiktok"]}'
Which URL when. /api/mcp is the full server, 29 tools, for Claude, Cursor, Codex and your own client. /api/mcp-apps is the same server with publish_post, schedule_post, reschedule_post and cancel_post removed, for the ChatGPT app directory. Both take the same credentials.

Do you need an API key?

Not if your client speaks OAuth. Claude and ChatGPT register themselves and send you to a consent screen. If your client does not, or you are writing a script, make a token by hand.

One-click OAuth

Standard OAuth 2.1 with dynamic client registration and PKCE. Your client finds everything it needs in two documents. In most tools you only paste the MCP URL.

# what the client reads, in this order GET /api/.well-known/oauth-protected-resource/api/mcp GET /api/.well-known/oauth-authorization-server # then the normal dance POST /api/register # the client registers itself GET /api/authorize # you log in and approve, read or write POST /api/token # code + PKCE S256 to access token POST /api/revoke

A token issued this way is a normal Cadenus token. It shows up in Settings under the tool's name. Delete it there and the tool is disconnected at once.

A token you make yourself

Settings, then API & MCP, then New token. The full value is shown once and never again, because we only keep its hash.

# every request, MCP or REST Authorization: Bearer cdn_0Td… # scopes read # look and report. Cannot change anything. write # upload, publish, schedule, cancel.
A token carries your permissions, not more. It is bound to one workspace and to the person who made it. It runs under the same role and client visibility that person has in the app. An agent cannot reach a brand you cannot reach.

29 tools. Most of them read.

A read token can call everything marked read. Anything marked write needs a write token, and says so when it is refused.

Publishing and media

11 tools
ToolWhat it doesScope
list_channelsThe connected accounts a post can go to, and what each one accepts, including that platform's caption limit.read
create_media_uploadReserve a signed address so the agent can upload a file straight from its own disk, past the API.write
confirm_media_uploadMake an uploaded file usable. Checks it is what it claims to be and rewrites video Instagram would refuse.write
import_media_from_urlPull a file from a link into the workspace instead of uploading it.write
publish_postCreate and schedule in one call, on accounts whose brand does not require client approval.write
schedule_postSchedule an approved draft on its proposed channels.write
reschedule_postMove a scheduled post to another time, on every channel it was queued for.write
cancel_postCancel a scheduled post before it goes out.write
get_post_resultWhat actually happened, per channel, with the link to the live post.read
list_mediaFiles already in the workspace, newest first, with the reference to pass as media.read
get_connect_linkA link the person opens to connect a social account, when there are none yet.read

Drafts, approvals and the calendar

10 tools
ToolWhat it doesScope
create_draftCreate a post as a draft. Nothing publishes until it is scheduled.write
update_draft_captionReplace a draft's caption.write
submit_draft_for_reviewSend a draft to the client's approval portal.write
approve_draftApprove internally, without client review.write
list_pending_approvalsPosts waiting on someone, with client and thumbnail.read
list_postsDrafts and posts with status, type and proposed date.read
get_post_detailsOne post in full: caption, first comment, channels, date.read
get_content_calendarWhat is planned for the next N days.read
get_workspace_infoThe workspace, the person behind the token, the token's scope, and every connected account.read
list_clientsClients with retainer and production health signals.read

Production and research

8 tools
ToolWhat it doesScope
list_production_itemsVideo items with stage, deadline and priority.read
list_stalled_itemsItems stuck in a stage for at least N days.read
promote_idea_to_productionTurn a saved idea into a production item, carrying its script.write
list_content_ideasIdeas saved from the Radar research feed.read
list_outlier_videosVideos from the watchlist that beat their channel's median by a wide margin.read
find_creatorFind the accounts matching a person or brand name.read
get_creator_top_videosA creator's top videos, ranked against their own median.read
get_financial_summaryIncome, expense and margin over a period, against the one before it.read

Four calls from a file on disk to a published post.

The file does not travel through the API. We hand out a signed address, your code uploads to it, and we check the file before anything is queued. No base64, no request-size wall.

1

Reserve an address

Tell Cadenus the file name, type and size. You get back a signed upload address, valid for one hour.

POST /api/agent/media { "filename": "clip.mp4", "content_type": "video/mp4", "size": 52428800 } to 200 { "media_id": "Ge…", "upload_url": "https://…", "content_type": "video/mp4", "expires_in": 3600 }
2

Upload the bytes yourself

A plain PUT to the address, with the same content type you reserved.

PUT <upload_url> Content-Type: video/mp4 # the same one you reserved: the signature covers it <raw bytes>
3

Confirm it

This is where a phone's HEVC becomes H.264. Instagram accepts HEVC and then fails it in processing hours later, so we rewrite it here. The converted copy gets a new name, and you get that name back.

POST /api/agent/media/confirm { "media_id": "Ge…", "content_type": "video/mp4" } to 200 { "ref": "https://app.cadenus.io/api/media/acme/Ge….mp4", "kind": "video", "normalized": true }
4

Publish or schedule

One call, with the channels, the media reference and the time. Leave out the time and it goes on the next pass.

POST /api/agent/posts { "caption": "Three things I stopped doing after 100 posts", "channels": ["instagram", "@studio.north"], # handle, platform, native:39, or all "media": ["<ref from step 3>"], "post_type": "reel", # post or reel "when": "2026-09-10T09:00:00+03:00", # omit to go on the next pass "first_comment": "Links below" } # Instagram and Facebook only to 200 { "ok": true, "scheduled": [ { "channel": "native:39", "post_id": 453, "status": "scheduled" } ], "errors": [] }
Read the outcome with get_post_result. Publishing is queued, not instant. The publisher sends each channel when it is due, and the live link exists only after the network accepts it. A post that failed on one channel and went out on another says exactly that, per channel.

What will be refused, and when.

Everything here is checked on our side before a post is queued. A mistake comes back in seconds, not as a platform error hours later.

Captions

PlatformCharactersHashtags
Instagram2,20030
TikTok2,200no limit
LinkedIn3,000no limit
YouTube5,000no limit
X280no limit
Facebook63,206no limit

Only rules the network itself enforces are here. LinkedIn's five hashtags is advice. Refusing a post over advice would invent a failure that would not have happened.

Files

Acceptedmp4 · mov · jpg · png · webp
Maximum size300 MB
Signed address valid1 hour
Converted for youHEVC to H.264
StoredEU object storage

Rate limits

MCP calls120 / minute per token
Upload reservations60 / hour per person, 200 / day per workspace
Publishes120 / hour per person

Naming channels

Anywhere channels are accepted, you can write them the way a person would. A bare platform name only works when it is unambiguous. When it is not, the error names the candidates instead of guessing.

"all" # every connected account "tiktok" # the platform, if you have one account there "@studio.north" # a handle "native:39" # the exact channel ref from list_channels

What comes back when something is wrong.

Errors are written to be passed on. If your agent repeats ours to the person, the sentence tells them what to do.

StatuserrorWhat it means
401invalid_tokenMissing, wrong or revoked token. The response also carries a WWW-Authenticate header pointing at the OAuth metadata. That is how Claude and ChatGPT offer to reconnect.
402billing_requiredThe subscription is not active. The agent is told to open Cadenus and settle it.
403plan_upgrade_requiredThis plan does not include the agent connection.
403read-only tokenA write tool was called with a read token.
403approval requiredThe brand behind that channel requires client approval. The message names the draft flow to use instead.
429rate_limitedToo many calls. Retry-After says how long to wait.

The rules an agent cannot talk its way around.

They live in the workspace, next to the people who set them. They apply the same to a browser, a Notion row or an agent.

01

It will not see past its own workspace

A token is bound to one workspace and carries its creator's role. Rows are isolated in the database itself, not only in the code that queries them.

02

It will not post the same thing twice

Send the same post again by mistake and you get the first one back, with its original id. Retrying is safe.

03

It will not publish around an approval

If the brand requires client approval, publish_post refuses and names the draft flow. The agent can create and submit a draft. The client approves in their portal, as always.

04

It will not survive a revoke

Delete the token and every call stops at once, OAuth ones included. What the agent scheduled stays in the calendar under the token's name, so you can cancel or move it.

Questions we get asked.

Does Cadenus have an MCP server?

It does, at https://app.cadenus.io/api/mcp, with 29 tools over streamable HTTP. It works with Claude, Claude Code, ChatGPT, Cursor, Codex and any other MCP client.

Do I need an API key to use it?

Only if your client cannot do OAuth. Claude and ChatGPT register themselves and send you to a consent screen, where you pick read or write. Everyone else uses a bearer token from Settings.

How does an agent upload a video?

In three steps: reserve an address, PUT the bytes to it, confirm. The file never travels inside a tool argument or a JSON body. So there is no base64, and the ceiling is 300 MB.

Which platforms can it publish to?

Instagram, Facebook, TikTok, LinkedIn and YouTube, plus X as a per-account add-on because X charges for its API. Photos, carousels and video, as posts or reels.

Is there a REST API as well as MCP?

Yes, for the things a tool call cannot carry: reserving an upload, confirming it, and publishing in one call. Four endpoints under /api/agent, same token, same limits.

What are the rate limits?

120 MCP calls a minute per token. 60 upload reservations an hour per person, with 200 a day per workspace. 120 publishes an hour per person. A 429 tells you how long to wait.

Which plan includes this?

Connect, at €19 a month, is the smallest one that does: eight channels, the MCP server, the skill and the API. It is also on Starter, Agency and Scale.

Where does my data live?

In the EU. Media sits in EU object storage, and video is removed once it has been published. Each workspace's rows are isolated at the database level.

The whole thing on one screen.

The same values as on the pricing page, in llms.txt and in the MCP server's own description.

product
Cadenus, social media publishing for teams, agencies and AI agents
agent_door
MCP server (29 tools), shell skill for local agents, REST endpoints under /api/agent
mcp_url
https://app.cadenus.io/api/mcp
auth
OAuth 2.1 one click in Claude and ChatGPT, or Bearer token cdn_…; scopes read and write
works_with
Claude Code, Codex, OpenClaw, Claude, ChatGPT, Cursor, any MCP client, any HTTP client
platforms
Instagram, Facebook, TikTok, LinkedIn, YouTube; X per connected account
media
mp4, mov, jpg, png, webp; direct upload up to 300 MB; HEVC converted to H.264 automatically
caption_limits
Instagram 2,200 and 30 hashtags · TikTok 2,200 · LinkedIn 3,000 · YouTube 5,000 · X 280 · enforced server-side
price
Connect plan €19 per month, 8 channels, 5 GB, 7-day free trial; Starter from €39 adds client approvals and portals
hosting
EU, media stored in EU object storage
docs
cadenus.io/developers/ · cadenus.io/llms.txt
updated
2026-09-07

Paste the URL into your agent.
See your channels in a minute.

€19 a month on Connect. 7 days free, card required.

Start your free trial ››