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.kirim.chat
Authorization: Bearer kdv_live_TavbPKwIuqOr69ALEKLNennZ
kdv_live_<24 url-safe base64 chars>
  • The kdv_ prefix identifies the key as issued by Kirim.
  • 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 organization and grants full org-wide access — there is no scoped permission system today (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:

import { Kirim } from '@kirimdev/sdk'
const kirim = new Kirim({ apiKey: process.env.KIRIM_KEY! })
const ctx = await kirim.me()

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.

One key per environment + consumer

Dev / staging / prod, and per integration (Zapier, n8n, your backend). Granular tracking makes leak response painless.

Rotate proactively

No enforced cadence, but every 90 days is a reasonable default. Issue new → update apps → revoke old.

Set expirations on temporary keys

For one-off scripts, contractor access, or trial integrations.

Audit the API log

Every /v1/* call appears under Developers → API Logs with method, path, status, latency, IP, request id. 30-day retention.

Subscribe to key-lifecycle webhooks

Once shipped, webhook.subscription.* events give real-time alerts when a key is created or revoked.