Skip to content
Getting Started

Authentication

The Kirim Public API uses bearer-token authentication. Every request to /v1/* (except /v1/health and /v1/openapi.json) must carry an Authorization: Bearer <token> header.

GET /v1/me HTTP/1.1
Host: api-kckit.kirim.chat
Authorization: Bearer kdv_live_TavbPKwIuqOr69ALEKLNennZ
kdv_live_<24 url-safe base64 chars>
  • The kdv_ prefix identifies the key as Kirim-issued.
  • live indicates the production environment.
  • The 24-character suffix is generated from 18 bytes of CSPRNG entropy.
  • Total length: 33 characters.

A future kdv_test_* prefix is reserved for the sandbox environment (not yet shipped).

API keys are issued through the dashboard under Developers → API Keys. Each key belongs to one organisation and grants full org-wide access — there is no scoped/granular permission system in v1 (deferred to a later phase, non-breaking when added).

The plaintext is shown once in the create-key modal and never again. Kirim stores only an argon2id hash plus the first 12 and last 4 characters for display.

Pass the plaintext as a bearer token on every request:

Terminal window
curl https://api-kckit.kirim.chat/v1/me \
-H "Authorization: Bearer $KIRIM_KEY"

The API does not accept the key as a query parameter, basic auth, or cookie. Bearer header only.

Keys may be issued with an optional expires_at timestamp. Once the clock passes that moment, requests return:

HTTP/1.1 401 Unauthorized
{
"error": {
"type": "authentication_error",
"code": "expired_api_key",
"message": "This API key has expired.",
"request_id": "req_…"
}
}

Expiration is enforced server-side at the auth-middleware layer; there is no client-visible warning before it triggers, so wire your own heads-up alert if needed.

Click Revoke next to a key in the dashboard. Effective immediately — the verification cache is invalidated synchronously. The next request with that key returns:

HTTP/1.1 401 Unauthorized
{
"error": {
"type": "authentication_error",
"code": "revoked_api_key",
"message": "This API key has been revoked.",
"request_id": "req_…"
}
}

Revocation is irreversible. To rotate, issue a new key first, update your application, then revoke the old key.

For each request Kirim:

  1. Reads the Authorization: Bearer <token> header.
  2. Parses the first 20 characters as the key_prefix index.
  3. Looks up the row in api_keys (single-row index hit).
  4. Verifies the full plaintext against the stored argon2id hash in constant time.
  5. Checks revoked_at IS NULL and expires_at IS NULL OR expires_at > now().

A 60-second Redis cache amortises the argon2id cost for high-RPS keys. Revoke / rotate / expiration changes invalidate the cache synchronously.

HTTPtypecodeTrigger
401authentication_errormissing_api_keyNo Authorization header
401authentication_errorinvalid_api_keyMalformed token, unknown prefix, or hash mismatch
401authentication_errorrevoked_api_keyKey has been revoked
401authentication_errorexpired_api_keyexpires_at has passed

All four return the standard error envelope with a request_id you can quote in support tickets.

  • Store keys in a secrets manager (Doppler, 1Password, AWS Secrets Manager, Vault) — never in .env files committed to git, never in client-side bundles.
  • Issue one key per environment (dev / staging / prod) and per consumer (Zapier, n8n, your custom backend). Granular tracking makes the next step painless when a key leaks.
  • Rotate proactively — there is no enforced rotation cadence, but every 90 days is a reasonable industry default.
  • Set an expiration on temporary keys — for one-off scripts, contractor access, or trial integrations.
  • Audit the API request log in the dashboard under Developers → API Logs. Every /v1/* call lands there with method, path, status, latency, IP, and request id. 30-day retention.
  • Subscribe to webhook.subscription.* events (Phase 4) if you need real-time alerts when a key is created or revoked.