Developer API
A REST API over your workspace: posts, approvals, media, notes and analytics, on Ultra and Ultra+.
API keys from the dashboard, one error shape, and an OpenAPI 3.1 reference with samples in curl, Node and Python.
14-day free trialCancel anytime, no questions asked
https://api.schedchie.com/v1 # the same routes also answer on https://mcp.schedchie.com/v1
Getting started
Create a key
In the dashboard, under AI assistants, API keys. Keys are there after the workspace's first paid invoice, not during the trial. Copy the key when it appears: it is shown once.
Make the first call
GET /v1/mechecks the key and answers its workspace.GET /v1/mecurl https://api.schedchie.com/v1/me \ -H "Authorization: Bearer $SCHEDCHIE_API_KEY"
const res = await fetch("https://api.schedchie.com/v1/me", { method: "GET", headers: { Authorization: `Bearer ${process.env.SCHEDCHIE_API_KEY}`, }, }); const me = await res.json();import os import requests r = requests.get("https://api.schedchie.com/v1/me", headers={"Authorization": f"Bearer {os.environ['SCHEDCHIE_API_KEY']}"}) r.raise_for_status() me = r.json()Schedule a post
POST /v1/postswith the text, the account ids fromGET /v1/accountsand a time. It answers 201 with the post.POST /v1/postscurl -X POST https://api.schedchie.com/v1/posts \ -H "Authorization: Bearer $SCHEDCHIE_API_KEY" \ -H "Idempotency-Key: launch-2026-12-01-ig-li" \ -H "Content-Type: application/json" \ -d '{"text":"Launch day. The new collection is live.","accountIds":["64a1f0e2b3c4d5e6f7a8b9c1"],"scheduledTime":"2026-12-01T09:00:00.000Z","hashtags":["launch","newcollection"]}'const res = await fetch("https://api.schedchie.com/v1/posts", { method: "POST", headers: { Authorization: `Bearer ${process.env.SCHEDCHIE_API_KEY}`, "Idempotency-Key": "launch-2026-12-01-ig-li", "Content-Type": "application/json", }, body: JSON.stringify({ "text": "Launch day. The new collection is live.", "accountIds": [ "64a1f0e2b3c4d5e6f7a8b9c1" ], "scheduledTime": "2026-12-01T09:00:00.000Z", "hashtags": [ "launch", "newcollection" ] }), }); const post = await res.json();import os import requests r = requests.post("https://api.schedchie.com/v1/posts", headers={"Authorization": f"Bearer {os.environ['SCHEDCHIE_API_KEY']}", "Idempotency-Key": "launch-2026-12-01-ig-li"}, json={ "text": "Launch day. The new collection is live.", "accountIds": [ "64a1f0e2b3c4d5e6f7a8b9c1" ], "scheduledTime": "2026-12-01T09:00:00.000Z", "hashtags": [ "launch", "newcollection" ] }) r.raise_for_status() post = r.json()Or use the CLI
The
schedchiepackage gives you the CLI and an SDK on the same keys. To connect an AI assistant instead, see the MCP setup.Terminalnpm install -g schedchie
Authentication
One bearer header on every request, from your own server.
- Header
Authorization: Bearer schedchie_api_…on every request. A missing or unknown key answers 401.- Keys
- Up to 5 active keys per workspace on Ultra, 10 on Ultra+. Each key is shown once, when it is made.
- Permissions
- Each key is granted permission groups (posts, media, analytics, team, library), each read and write or read only. A read-only key is refused on every write.
- Workspace
- A key acts only in its own workspace.
- Format
- JSON both ways, bodies up to 8 MiB, camelCase field names. Creates answer 201.
- Browsers
- The API sends no CORS headers: call it from your server, not from browser code.
- Webhooks
- There are no webhooks. Poll GET /v1/posts with a status filter instead.
The limits
Per key and once more for the whole workspace, so more keys never mean more calls.
| Limit | Ultra | Ultra+ |
|---|---|---|
| Calls a minute, per key | 120 | 120 |
| Calls a minute, all keys of the workspace together | 120 | 120 |
| Calls an hour, per key | 1,200 | 3,600 |
| Calls an hour, all keys of the workspace together | 1,200 | 3,600 |
| Uncached live reads an hour, per workspace | 60 | 120 |
| Live read cache | 300 s | 300 s |
| Active keys per workspace | 5 | 10 |
- Headers
- Every response carries
RateLimit-Limit,RateLimit-RemainingandRateLimit-Reset; a 429 or 503 addsRetry-After. - Live reads
- The analytics overview and account routes reach a social platform. A repeat inside 300 s is served from the cache (
X-Schedchie-Cache: hit) and costs no live read. - Platforms
- Each platform meters its own API. A platform can refuse or slow a call that is inside these numbers.
One error shape
Every error carries the same envelope. details lists each failed field on a 422 validation_failed. Every response carries X-Request-Id: quote it when you write to us.
{
"error": {
"status": 422,
"code": "validation_failed",
"message": "…",
"requestId": "…",
"details": [{ "field": "…", "message": "…" }]
}
}| Status | Code and meaning |
|---|---|
| 400 | invalid_jsonthe body is not JSON. |
| 400 | invalid_argumentsthe tool behind the route refused the values (an unknown account id, a time in the wrong format, a caption over a platform's limit). |
| 400 | workspace_not_alloweda workspace field named another workspace. |
| 401 | missing_keyno Authorization: Bearer header. |
| 401 | invalid_keynot a Schedchie API key, or unknown or revoked. |
| 401 | key_refusedthe key was revoked during the call. The response carries WWW-Authenticate: Bearer realm="schedchie-api". |
| 403 | plan_requiredthe workspace left the Ultra plan. |
| 403 | not_permittedthe key was not granted this route's group, is read only for it, or is bound to an employee seat that cannot use this route. |
| 404 | not_foundno resource with that id in this workspace, or no such route under /v1. |
| 405 | method_not_allowedthe path exists, the method does not. Allow lists the methods that do. |
| 413 | body_too_largethe request body is over 8 MiB. |
| 422 | validation_failedthe body or the query did not match this route's schema; details names each field. |
| 422 | tool_errorthe request was well formed and Schedchie or the social platform refused it (a caption too long for a platform, an account that needs reconnecting, a file the platform does not accept). |
| 429 | rate_limitedover 120 calls this minute for this key or for the workspace's keys together, or too many refused requests from one address. |
| 429 | budget_exhaustedthe hour's calls are used up. |
| 429 | live_read_budgetthe workspace's uncached live reads this hour are used up. Retry-After says how long to wait. |
| 503 | unavailableSchedchie could not verify the key or reach its own API right now. Retry after Retry-After seconds. |
| 504 | timeoutthe call did not finish within 15 minutes and was stopped. |
| 500 | internalsomething failed on our side; the message carries a reference for support. |
How the API behaves
Pagination
GET /v1/posts pages with cursor and limit (default 25, max 100) and answers nextCursor, which is null on the last page. Every other list returns everything with nextCursor: null; limit is accepted there and reserved, so paging can come later without a new version.
Idempotency
POST /v1/posts takes an Idempotency-Key header, 1 to 255 characters of your choice. A repeat with the same key and the same API key answers the post already made with 200 and Idempotent-Replayed: true, never a second post. Keys are unique forever per API key. No other create is idempotent; a second DELETE answers 404.
Versioning and deprecation
The version is in the path. New routes, new optional fields and new enum values do not change it. A breaking change ships as /v2, and /v1 keeps answering for at least six months after /v2 is announced, with Deprecation and Sunset headers on its responses and an entry in the changelog below.
Advanced: calling a tool directly
The same keys reach every tool of the MCP server over HTTPS. GET /v1/tools lists the tools a key may call, and POST /v1/tools/{name} runs one with its arguments as the JSON body: the way to what the REST routes do not wrap. A destructive tool runs there only with X-Confirm-Destructive: true; on the REST routes, DELETE is the confirmation.
Changelog
v1 published, on https://api.schedchie.com/v1 and https://mcp.schedchie.com/v1.
Ultra, €24.99 a month, API included
Up to 5 keys and 1,200 calls an hour. Keys are available after the first paid invoice.
Start free trial14-day free trialCancel anytime, no questions asked
