Kinoseed

Start

Authentication

Every call that spends or reads account data carries an API key as a bearer token. Keys are made on the account page, shown once, and scoped to what they may do.

Keys

  • Create a key on your account page, under API keys. Name it after where it will live ("CI", "my agent") so you know which one to revoke later.
  • The full key is shown once, when it is created. We keep only a hash of it, so it cannot be shown again; the account page lists keys by their first characters, like ks_live_3fA9.
  • A key looks like ks_live_ followed by 43 random characters. An account can hold up to 20 live keys.
  • A key spends the account's credits exactly like the Generate button does. Treat it like a password: keep it in an environment variable or a secret store, never in a repository or a browser.

Put it in the Authorization header of every request:

Header
Authorization: Bearer ks_live_YOUR_KEY

A client that cannot set the Authorization header (Smithery, some MCP gateways) can send the same key, without the Bearer prefix, in X-Kinoseed-Key. It is checked exactly the same way. If both headers are sent they must carry the same key. A key is never read from the query string, because URLs end up in logs.

Alternative header
X-Kinoseed-Key: ks_live_YOUR_KEY

Only GET /models and GET /openapi.json are public. Any Authorization or X-Kinoseed-Key header at all is treated as an attempt to use a key: a malformed one is refused, never ignored.

Scopes

A key carries a set of scopes fixed when it is created. A call outside them answers 403 forbidden_scope. New keys get every scope but webhooks:manage unless you untick some. Give a key only what its job needs: an agent that only reads results needs jobs:read.

ScopeAllowsOperations
images:generateGenerate imagesPOST /images
videos:generateGenerate videosPOST /videos
jobs:readRead jobsGET /jobsGET /jobs/{id}
jobs:writeDelete jobsDELETE /jobs/{id}
files:writeUpload filesPOST /files
credits:readRead the credit balanceGET /credits
webhooks:manageManage webhooksGET /webhooksPOST /webhooksDELETE /webhooks/{id}POST /webhooks/{id}/test

POST /quote works with any live key, whatever its scopes: it never charges.

Rotation and revocation

  • Revoke a key on the account page. It stops working on the next request; there is no grace period.
  • To rotate, create the new key, deploy it, then revoke the old one. Two live keys at once is normal for the length of a deploy.
  • If a key leaks, revoke it first and look second: a leaked key can spend the balance. The per-key rate limits (see Rate limits) slow a stranger down, they do not stop one.

The 401

A missing, malformed, unknown or revoked key answers 401 unauthorized with a bearer challenge, and details.reason says which: missing, invalid or revoked.

Response
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="kinoseed"
Content-Type: application/json

{
  "error": {
    "code": "unauthorized",
    "message": "This API key has been revoked.",
    "details": {
      "reason": "revoked"
    }
  }
}