AI agents
Plan and publish from the AI you already use
Ask your agent for a week of posts in your voice. Skryvo shows each one and waits for your go-ahead.
Channels
One post, written for every channel
11 channels publish today and 6 are in platform review. Skryvo reads each post back to confirm it went live.
AI agent integration: Skryvo REST API and MCP server
Everything an agent does in Skryvo, your code can do too: list a person's brands and channels, write posts in a brand's voice, design their pictures, schedule them and read how they did. Agents connect to the MCP server; scripts call the REST API with a key. Both run the same code as the app, so plan limits, brand rules and approvals apply.
Checked against the product on 2 November 2026.
At a glance
- MCP server
- https://api.skryvo.ai/mcp
- REST API
- https://api.skryvo.ai/api/v1/agent
- Sign-in
- OAuth 2.1 with dynamic client registration, or an API key as a Bearer token
- Public tools
- 10, each with a REST route
- Rate limit
- 60 requests a minute and 1,000 an hour per key or sign-in
- Agent setup
- Step-by-step pages for Claude, ChatGPT, Cursor, VS Code and more at /agents/
Two ways in
MCP server, for AI agents
https://api.skryvo.ai/mcp speaks streamable HTTP, stateless, with JSON responses. Claude, ChatGPT, Cursor, VS Code, Claude Code, Codex, Gemini and any client that supports remote MCP servers can add it.
REST API, for scripts and CI
https://api.skryvo.ai/api/v1/agent takes JSON and returns JSON, one route per tool. Use it from a script, a CI job or an n8n workflow, with an API key.
Authentication
OAuth sign-in
Clients discover Skryvo at /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server on api.skryvo.ai, register themselves, and send the person to a consent page that names the app and the account. Codes are single-use with an S256 challenge; access tokens last 1 hour and refresh tokens 90 days, rotating on each use.
API key
Create one in Skryvo under Settings › API & agents. It starts with sk_skryvo_, is shown once and stored only as a hash. A person can keep up to 10, and a key opens the agent API and nothing else in the account.
Send either as Authorization: Bearer. A request to the MCP server with no credential gets a 401 whose WWW-Authenticate header points to the sign-in metadata. Revoking a key or disconnecting an app in Settings stops it at once. In a team, a key or sign-in acts in the workspace it was made in, with that member's role and brands.
curl https://api.skryvo.ai/api/v1/agent/me -H "Authorization: Bearer $SKRYVO_API_KEY"
{"email": "you@example.com", "plan": "pro"}
The 10 tools
Each MCP tool has a REST route with the same parameters. Tools marked "changes" alter the calendar or the brand's look; an agent asks the person before it calls them.
list_brands
no changes
GET /api/v1/agent/brands
The person's brands: id, name and whether it is the default.
list_channels
no changes
GET /api/v1/agent/channels
Connected accounts: id, platform, name, the brands that use it, social or blog, and whether it needs reconnecting.
write_post
no changes
POST /api/v1/agent/drafts
Drafts a post per platform in the brand's voice, one generation for the whole batch. Schedules nothing.
| Parameter | Type | What it is |
|---|---|---|
topicrequired |
string | What the post is about, 3 to 200 characters. |
platforms |
string[] | Up to 4 platforms; omitted, the brand's default. |
brand_id |
string | A brand from list_brands; omitted, the person's default brand. |
tone | string | Omitted, the brand's tone. |
language |
string | A language code; omitted, the brand's writing language. |
audience | string | Who the post is for. |
call_to_action | string | What the reader should do next. |
hashtags | string[] | Hashtags the person asked for. |
link | string | A web page the post points to. |
pictures |
boolean | A picture in the brand's kept look with each post. |
confirmed |
boolean | true once the person approved the summary of what was assumed. |
design_picture
no changes
POST /api/v1/agent/pictures
One picture in the brand's kept look, with a copy at each platform's post size. Uses image credits; schedules nothing.
| Parameter | Type | What it is |
|---|---|---|
textrequired |
string | The post the picture goes with. |
platformsrequired |
string[] | The platforms to size it for. |
brand_id |
string | A brand from list_brands; omitted, the person's default brand. |
direction |
string | How it should differ, in the person's words: warmer, closer, bolder, calmer. |
headline |
string | The line set on the picture, up to nine words; omitted, the post's opening. |
photo_id |
string | One of the brand's own photos, as brand_design lists them. |
post_results
no changes
GET /api/v1/agent/results
Reach, engagement and clicks per channel, best posting times, findings and the top ten posts.
| Parameter | Type | What it is |
|---|---|---|
days | integer | 7, 30 or 90; default 30. |
brand_id |
string | A brand from list_brands; omitted, the person's default brand. |
schedule_post
changes
POST /api/v1/agent/posts
One calendar post per channel. Skryvo publishes it on the quarter hour and reads it back to confirm it went live.
| Parameter | Type | What it is |
|---|---|---|
textrequired |
string | The post the person approved. |
channel_idsrequired |
string[] | Social channels from list_channels. |
at |
string | ISO 8601 time, moved to the next quarter hour; omitted, about 5 minutes from now. |
image_url | string | One picture for every channel. |
brand_id |
string | A brand from list_brands; omitted, the person's default brand. |
tiktok_privacy |
string | PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR or SELF_ONLY, as the person chose. |
link | string | A web page the post points to. |
images |
object | {channel_id: image_url}: a channel's own picture, such as its sized copy. |
list_scheduled_posts
no changes
GET /api/v1/agent/posts
Posts from yesterday to the next days, with status and any publish error.
| Parameter | Type | What it is |
|---|---|---|
days | integer | How far ahead, up to 90; default 30. |
cancel_post
changes
DELETE /api/v1/agent/posts/{id}
Removes a scheduled post before it goes out.
| Parameter | Type | What it is |
|---|---|---|
post_idrequired |
string | A post id from list_scheduled_posts. |
brand_design
no changes
GET /api/v1/agent/design
The brand's logo, colour roles, fonts, kept look and own photos.
| Parameter | Type | What it is |
|---|---|---|
brand_id |
string | A brand from list_brands; omitted, the person's default brand. |
change_look
changes
POST /api/v1/agent/design/look
Designs the look, designs it again closer, bolder, calmer or with another photo (twice, free), or keeps the one on show.
| Parameter | Type | What it is |
|---|---|---|
changerequired |
string | design, closer, bolder, calmer, photo or keep. |
brand_id |
string | A brand from list_brands; omitted, the person's default brand. |
Over REST, schedule_post takes TikTok settings as a tiktok object: privacy (required), allow_comments, allow_duet, allow_stitch, your_brand and branded_content. GET /me returns the key holder's email and plan.
End to end: a post, its picture, then the schedule
A release post for LinkedIn and X, written in the brand's voice, given a picture in its kept look and scheduled only after the person approves. The calls are REST; an agent makes the same calls as list_channels, write_post, design_picture and schedule_post. Ids, text and links are example values; the shapes are the API's own.
-
Find the channels
List the connected accounts and keep the ids of the ones the post goes to.
curl https://api.skryvo.ai/api/v1/agent/channels \
-H "Authorization: Bearer $SKRYVO_API_KEY"
{
"channels": [
{"id": "ch_li_8Kq2", "platform": "linkedin", "name": "Dana Okafor", "brand_ids": ["bv_northwind"],
"kind": "social", "needs_reconnect": false},
{"id": "ch_x_4Tz9", "platform": "twitter", "name": "@northwindapp", "brand_ids": ["bv_northwind"],
"kind": "social", "needs_reconnect": false}
]
}
-
Write the drafts
Name the platforms and say whether to add pictures, and Skryvo writes at once, one version per platform. Each setting says where it came from. Nothing is scheduled.
curl -X POST https://api.skryvo.ai/api/v1/agent/drafts \
-H "Authorization: Bearer $SKRYVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"topic": "Version 2.4 adds a week view to the calendar",
"platforms": ["linkedin", "twitter"], "pictures": false}'
{
"status": "written",
"topic": "Version 2.4 adds a week view to the calendar",
"brand_id": "bv_northwind",
"generation_id": "gen_5c1e…",
"posts": [
{"platform": "linkedin", "text": "Planning a week used to mean five tabs…", "hashtags": []},
{"platform": "twitter", "text": "The week view is here. …", "hashtags": []}
],
"settings": [
{"field": "platforms", "value": ["linkedin", "twitter"], "from": "you"},
{"field": "tone", "value": "Friendly", "from": "brand"},
{"field": "language", "value": "en", "from": "brand profile"},
{"field": "pictures", "value": false, "from": "you"}
],
"differs_from_brand": []
}
Leave platforms or pictures out and the first call writes nothing. It returns a summary to show the person: every setting with its source, the cost and what is left this month. Call again with their final values and "confirmed": true.
{
"status": "confirm",
"topic": "Version 2.4 adds a week view to the calendar",
"brand_id": "bv_northwind",
"settings": [
{"field": "platforms", "value": ["linkedin", "twitter"], "from": "brand"},
{"field": "pictures", "value": true, "from": "brand"}
],
"cost": {"generations": 1, "image_credits": 4},
"left": {"generations": 118, "image_credits": 66, "resets_at": "2026-12-01T00:00:00+00:00"},
"differs_from_brand": []
}
-
Design the picture
One design in the brand's kept look, with a copy at each platform's size. It takes about a minute and spends image credits for each page shape, square or wide; a shape that fails its checks is not charged.
curl -X POST https://api.skryvo.ai/api/v1/agent/pictures \
-H "Authorization: Bearer $SKRYVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Planning a week used to mean five tabs…", "platforms": ["linkedin", "twitter"]}'
{
"brand_id": "bv_northwind",
"headline": "Planning a week used to mean five tabs",
"pictures": [
{"platform": "linkedin", "image_url": "https://…/design-…-1200x1200.jpg", "width": 1200, "height": 1200},
{"platform": "twitter", "image_url": "https://…/design-…-1600x900.jpg", "width": 1600, "height": 900}
],
"credits_used": 4,
"credits_left": 62
}
-
Show it, then schedule
Show the person the text and the picture. On their yes, schedule each platform's text to its channel with its own picture; repeat the call for X with the X text and copy. The time moves to the next quarter hour in the calendar's time zone.
curl -X POST https://api.skryvo.ai/api/v1/agent/posts \
-H "Authorization: Bearer $SKRYVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Planning a week used to mean five tabs…", "channel_ids": ["ch_li_8Kq2"],
"at": "2026-11-10T09:00:00Z", "images": {"ch_li_8Kq2": "https://…/design-…-1200x1200.jpg"}}'
{
"posts": [
{"id": "item_7Hn3", "platform": "linkedin", "channel_id": "ch_li_8Kq2",
"date": "2026-11-10", "time": "09:00", "status": "scheduled", "reason": null,
"awaiting_approval": false, "reviewer_approval": null, "auto_publish": true,
"text": "Planning a week used to mean five tabs…", "topic": "Planning a week used to mean five tabs…",
"written": true, "publish_error": null, "posted_url": null,
"open_in_skryvo": "https://app.skryvo.ai/calendar?date=2026-11-10"}
]
}
Skryvo publishes at that time and reads the post back to confirm it went live; GET /posts shows its status and posted_url. In a team, a post on a brand that needs approval comes back with awaiting_approval and waits for a reviewer.
Errors and limits
Every refusal carries a sentence a person can act on, in detail. A missing or revoked key:
HTTP/1.1 401 Unauthorized
{"detail": "Send a live Skryvo API key as 'Authorization: Bearer sk_skryvo_…'."}
A request the account or the rules refuse, such as a time in the past, an unknown channel or a month's allowance spent:
HTTP/1.1 422 Unprocessable Entity
{"detail": "That time has passed. Pick a time in the future."}
Each key or sign-in may make 60 requests a minute and 1,000 an hour. Past that:
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 12
{"error": "rate_limit_exceeded", "message": "…", "action": "requests_per_minute",
"limit": 60, "reset_seconds": 12, "retry_after": 12}
Plan allowances apply as in the app: a post batch uses one generation, pictures use image credits, and scheduled posts count toward the plan's queue. write_post takes up to 4 platforms and a topic of up to 200 characters.
Coming to the API
Article, email and product-listing tools are built and switch on after an app directory review. The roadmap lists them, with the tools planned after them.
Questions from developers
Is the API free?
It comes with every plan and trial, and calls spend the same generations and image credits as the app.
Can I post the same text to several networks in one call?
Yes. schedule_post takes several channel ids and makes one calendar post per channel.
Does the API publish without a person?
It schedules what you send it. The tools tell agents to show each post and wait for a yes, and we recommend the same approval step in scripts.
Where is the source for the agent plugins?
In the public repository github.com/Skryvo/agent, under the MIT licence.
How do I connect an AI agent to Skryvo?
Add https://api.skryvo.ai/mcp in Cursor, VS Code, Claude Code, Codex or any MCP client, or call the REST API with an API key from Settings › API & agents.
Get a key and make the first call
Your trial includes 35 generations and 20 image credits on Hobby, or 120 generations and 70 image credits on Pro.
- 7-day free trial
- Every channel included
- Cancel any time
Hi, I'm Ivo
Ask about plans, channels or your AI agent. I talk back, and you can interrupt any time.