REST API
Base URL, bearer auth, the OpenAPI spec at api.inklate.com/api/v1/openapi.json, and the create → preflight → schedule → publish flow over HTTP.
Inklate’s REST API exposes the same guarded operations as the dashboard and the MCP server over plain HTTPS and JSON. It is versioned under /api/v1 and fully described by an OpenAPI 3.1 document you can read or generate a client from.
Base URL and auth
- Base URL:
https://api.inklate.com/api/v1 - Auth header:
Authorization: Bearer <token>, where the token is either an Organization API key (prefixinklate_) or an OAuth 2.1 access token. Anx-api-key: <token>header is also accepted, butAuthorization: Beareris the canonical form. - Content type:
application/jsonfor request bodies.
Create a key under Settings → API in the dashboard — see API keys. A key is bound to one organization, so requests act on that organization automatically. A missing or invalid credential returns 401 with a JSON body of shape { "error": { "code": "UNAUTHORIZED", "message": "…" } }.
Read the OpenAPI spec
The spec is served unauthenticated and is the authoritative source for every path, request body, and response shape:
curl https://api.inklate.com/api/v1/openapi.jsonIt is an OpenAPI 3.1 document with a single bearerAuth security scheme. Point any OpenAPI-aware tool at it — Swagger UI, openapi-generator, @hey-api/openapi-ts — to generate a typed client in your language. There is no separately published SDK package today; the OpenAPI spec is the contract to build against.
The create → preflight → schedule flow
The core lifecycle mirrors the MCP tools. A post starts as a draft, gets fit-checked, then is scheduled or published. Endpoints below are relative to the base URL.
| Step | Method and path | Purpose |
|---|---|---|
| Discover | GET /channels | Connected destinations and their health |
| Discover | GET /capabilities | Per-channel publish verdicts and provider manifests |
| Create | POST /posts | Create a draft (honors an Idempotency-Key header) |
| Preflight | POST /posts/preflight | Stateless fit-check of post content — no persistence |
| Fix | POST /posts/{id}/apply-fix | Apply a preflight repair to one placement’s rendition |
| Sync | POST /posts/{id}/sync-variants | Copy Story or a Rendition into target Renditions |
| Schedule | POST /posts/{id}/schedule | Schedule (or reschedule) the whole post |
| Schedule | POST /posts/{id}/schedule-placements | Per-placement scheduling with optional cascade |
| Publish | POST /posts/{id}/publish | Publish now (also the retry path; honors Idempotency-Key) |
| Unschedule | POST /posts/{id}/unschedule | Cancel a pending schedule, return to draft |
| Track | GET /posts/{id}/status | Per-target async status, external id, URL, last error |
| Media | POST /media · GET /media/{handle} | Upload an image, then poll until ready |
| Metrics | GET /posts/{id}/metrics | Per-channel totals and snapshot series for one post |
| Metrics | GET /channels/{id}/metrics | Aggregated per-day engagement for a channel |
| Find | GET /posts · GET /search · GET /interactions | List, full-text search, comments and mentions |
| Skills | GET /skills · POST /skills/{name}/run · GET /skills/runs/{id} | Run durable multi-step workflows |
curl example: create a draft
curl -X POST https://api.inklate.com/api/v1/posts \
-H "Authorization: Bearer inklate_XXXXXXXX" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3f1c-announce-series-a" \
-d '{
"content": "We just closed our Series A.",
"channel_ids": ["chn_linkedin_page", "chn_x_account"]
}'Then fit-check before committing to a ship:
curl -X POST https://api.inklate.com/api/v1/posts/preflight \
-H "Authorization: Bearer inklate_XXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"content": "We just closed our Series A.",
"channel_ids": ["chn_linkedin_page", "chn_x_account"]
}'And schedule the created draft for a future instant (ISO-8601 with an offset):
curl -X POST https://api.inklate.com/api/v1/posts/pst_123/schedule \
-H "Authorization: Bearer inklate_XXXXXXXX" \
-H "Content-Type: application/json" \
-d '{ "at": "2026-07-21T09:00:00-07:00" }'Field names in request bodies follow the OpenAPI spec — treat it as authoritative and check it for
the exact shape of each endpoint (the manifest also mirrors the argument names documented for the
MCP tools, e.g. content, body, channel_ids, placements, variants, media_handles,
platform_options, idempotency_key). Timestamps must always carry an offset; naive local times
are rejected.