Last updated 2026-10-25
Authentication
Every /v1 call carries an API key as a bearer token:
Authorization: Bearer ksy_live_…
The catalogues (/v1/themes, /v1/templates) and the spec (/v1/openapi.json) need no key.
Keys
- Create and revoke keys in Settings → API keys on kinsy.ai. Each account can hold up to 10 active keys.
- A key is shown once, when it is created. Kinsy stores only a hash, so a lost key cannot be recovered; revoke it and create another.
- A key acts as the whole account: it spends the account's credits and reads the account's decks. There are no narrower scopes yet.
- Keys are accepted only on
/v1. The web app's own routes, billing and key management always need a signed-in session, so a leaked key can never create keys or change billing. - Revoking a key takes effect within a minute everywhere.
Keep a key out of source control, logs and prompts. Read it from an environment variable (KINSY_API_KEY) or a secrets store, and never paste it into a chat with an agent; give the agent the environment variable instead.
Signing in from the command line
kinsy login does not ask for a key. It uses a device sign-in: the terminal asks the API for a short code (POST /v1/auth/device), shows it as WXYZ-2345, and opens https://kinsy.ai/cli-auth. You confirm the code there while signed in; the page names the machine that asked and tells you to continue only if you started this from your terminal. Confirming records your approval; the terminal's next poll (POST /v1/auth/device/token) creates an ordinary API key labelled "CLI on hostname" at that very moment and is the only call that ever sees it. Nothing waits anywhere in between, and the key never passes through the browser.
Codes expire after ten minutes, are single use, and can be denied from the same page. Anything that can create an account or a key still needs a signed-in browser session, so a key alone can never mint another key. Both calls need no key and are documented in the reference, so another client can sign a user in the same way.
Headers
| Header | Purpose |
|---|---|
Authorization: Bearer ksy_live_… | The key. Required on every call except the catalogues and the spec. |
X-Kinsy-Client: name/version | Optional. Names the tool making the call (cli/1.2.0, mcp, my-agent/0.3); lowercase letters, digits and _ . / + -, up to 40 characters. Recorded on each deck you create so your own tooling can tell its decks apart. |
Idempotency-Key: … | Optional on POST /v1/decks, up to 128 characters. See below. |
Content-Type: application/json | On every request with a JSON body. POST /v1/files takes multipart/form-data with one file field. |
Idempotency
Network timeouts happen, and an agent that retries blindly would start, and pay for, a second deck. Send a unique Idempotency-Key (a UUID works) with POST /v1/decks. For 24 hours, any retry with the same key and the same account returns the original response, with Idempotent-Replayed: true, and charges nothing, even if the body differs.
Rate limits
Each key may make 120 requests per minute. Beyond that the API answers 429 with retry_after in seconds. The account-level backstops (15 builds a day, 40 edits an hour) apply to keys and the web app alike.
Signed download links
File links from GET /v1/decks/{id}/files/{kind} and from the artifacts block of a finished status are signed and valid for one hour (expires_at tells you when). Do not cache them; ask the status call for a fresh one when you need it.
Who am I?
GET /v1/me returns the account behind the key: plan, credit balance, whether the watermark applies, and the key's own id and label. It is the cheapest way to check a key works.