Skip to main content
Every protected Kairos endpoint takes one of two credentials: an API key triple for programmatic access, or a session JWT for user-facing apps. This page covers both — how to send them, what they unlock, and how each service reports an auth failure. Start with the quickstart; read the per-service detail when something returns 401 or 403. If you only need read-only market data and don’t want a credential at all, use the Market Data API’s free tier instead.

Quickstart

1. Create an API key in the Kairos dashboard. You get three values, shown once, at creation: 2. Export them:
3. Send all three headers on every request. This candles read needs no special scope, so it is the fastest way to confirm your credential works:
A 200 means you are authenticated. A 401 means the triple is wrong or incomplete — see Authentication Responses. 4. To trade, point the same three headers at https://execution.kairos.trade and make sure your key carries the trade:execute scope. See Scopes.
The three headers travel together. Sending X-Client-Id pins the request to the API-key path: there is no fallback to an Authorization: Bearer header on the same request. A partial triple is a 401, not a downgrade to anonymous.

Which Surface Takes Which Credential

Four Kairos surfaces accept credentials, and they do not behave identically. Check this table before assuming a key that works on one will work on another.
Two asymmetries to plan around. Presenting a credential to the Market Data API raises your rate limit but grants no additional scope-gated data. And JWT sessions bypass scope checks entirely on the Data API — a behaviour you cannot reproduce with an API key.

API Key Authentication (Programmatic Access)

The recommended credential for bots, backends, and anything non-interactive.

Supported Endpoints

API key auth works on all read-only data endpoints: It also works on the Order Execution API for trading endpoints, gated by scope.

Scopes

Scopes answer what an API key may do. A key may also carry the wildcard scope *, which satisfies any requirement. Market data, discover, search, candle, top-holders, and search-traders endpoints require no specific scope — any active API key grants access. See Order Types for the scope each order-management call requires.
The RPC API names its scope requirements differently. An RPC procedure can require the shorthand read or trade, which map onto the scopes above: read is satisfied by either position:read or trade:read, and trade by trade:execute. A 403 reading API key missing required scope: read is that mapping, not a fourth scope.
Scope is not the only gate on RPC. Admin procedures never accept API-key authentication, and non-admin procedures are opt-in — a procedure that has not been enabled for API keys returns 403 FORBIDDEN with This procedure does not accept API key authentication, regardless of scope.
No anonymous tier for trading on Order Execution. Every trading endpoint on execution.kairos.trade requires a credential or session JWT. The shallow GET /health load-balancer probe is public.

Platform Access

Where scopes answer what, the platform-access gate answers where: Kairos can disable API-key access to an individual provider. This gate applies to:
  • /trades/* and /pnl/* routes that read one or more providers
  • Selected RPC procedures that explicitly enforce provider access, including positions, selected balances/portfolio reads, chart fills, PnL, copy-trading reads, combo history, and Polymarket balance reads
  • Order execution REST and WebSocket commands
  • Provider-scoped events sent to API-key WebSocket connections
JWT/browser sessions are not affected. Candles, search, discover, and other general market-data routes are also outside this gate. kalshi_offchain uses the kalshi access decision. When access is disabled, the data API returns 403 with:
The detail may include an operator-supplied reason after the provider name. RPC returns 403 FORBIDDEN with the same API access is disabled for <provider> message. Order Execution words it differently — API-key access to <provider> is disabled — and returns 403 with error_details.code: "AUTH_INSUFFICIENT_SCOPE" where the endpoint carries a structured envelope.
Order submit and cancel are status-only: a provider denial there is a bodyless 403. Match on the status code, not the body.
If the access setting cannot be verified, the request fails closed (503 on the data and execution APIs, 500 INTERNAL_SERVER_ERROR on RPC). Treat that failure as transient rather than assuming access is enabled. Multi-provider requests fail as a whole when any included provider is disabled. Public GET /providers/api-access lists active providers currently enabled for API-key callers. If access settings cannot be loaded, it returns 503 instead of a partial list.

IP Whitelisting

API keys can optionally be restricted to specific IP addresses; requests from a non-whitelisted IP receive 403 Forbidden. An empty list means unrestricted. Matching is exact string match on the address — CIDR ranges are not supported.
The two APIs resolve your IP differently. The Data API and RPC take the last X-Forwarded-For hop; the Order Execution API deliberately ignores forwarded headers and compares the direct socket peer. A key whitelisted for your public IP can therefore pass on data.kairos.trade and fail on execution.kairos.trade when your traffic is proxied. Whitelist the address your egress actually presents to each service.

Security

  • Keys are hashed, not stored raw — API keys and secrets are SHA-256 hashed before storage.
  • Comparisons are constant-time — credential checks resist timing attacks.

JWT Bearer Token (User Auth)

The credential behind user-facing applications and browser sessions. Header format:
Example request:

Token Structure

JWT tokens are RS256-signed and contain: sub, sid, jti, ver, iat, and exp are all required — a token missing any of them is rejected. Token properties:
  • Issuer: kairos.trade
  • Audience: kairos-api
  • Algorithm: RS256
  • Expiration: at most 24 hours, capped by the underlying Turnkey session expiry

Lifetime and Revocation

  • Refresh grace — an expired token can still be exchanged for a fresh one for 4 hours past exp. Beyond that you must log in again.
  • Session lineage — a sid lives at most 28 hours (24h token life + the 4h grace), after which no token in that lineage refreshes.
  • Revocation — tokens are revocable two ways: by exact token, and by sid (logout-everywhere). A revoked token fails 401 even before it expires.

Transport

Send Authorization: Bearer <token>. Browser sessions may instead present the turnkey_session_jwt cookie. WebSocket clients pass the token in Sec-WebSocket-Protocol.
Query-parameter authentication is not supported — it was removed.

Authentication Responses

The services use different error envelopes, and the Data API distinguishes failure modes that Order Execution deliberately collapses. Match on the status code first; treat the message as diagnostic.

Data API (data.kairos.trade)

Body shape is { "detail": "<message>" }. The Code column below is the exact detail string. A 401 on a missing credential also carries WWW-Authenticate: Bearer.

Order Execution API (execution.kairos.trade)

Body shape is { "error": "<message>" }. The messages are deliberately generic — the specific cause is never echoed back, so the Code column tells you less than the Data API’s does.
Repeated auth failures trip a per-IP brute-force limiter that replaces the original error with 429. Back off rather than retrying a bad credential.
Handler-level scope and provider denials on endpoints with a structured envelope instead return { "error": ..., "error_details": { "code": "AUTH_INSUFFICIENT_SCOPE", ... } } — see Response Format.

RPC API

RPC wraps errors in the tRPC envelope:
UNAUTHORIZED is 401, FORBIDDEN is 403, INTERNAL_SERVER_ERROR is 500.

Endpoint Protection Levels

Best Practices

  • Store credentials securely — never expose keys or tokens in client-side code or logs.
  • Handle expiration — refresh before the token’s exp; lifetime is capped at 24 hours and can be shorter when the Turnkey session expires first.
  • Use HTTPS — all API requests must use HTTPS.
  • Monitor usage — track API-key usage for anomalies.