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:
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 shorthandreadortrade, which map onto the scopes above:readis satisfied by eitherposition:readortrade:read, andtradebytrade:execute. A403readingAPI key missing required scope: readis 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 returnsNo anonymous tier for trading on Order Execution. Every trading endpoint on403 FORBIDDENwithThis procedure does not accept API key authentication, regardless of scope.
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
kalshi_offchain uses the kalshi access decision.
When access is disabled, the data API returns 403 with:
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.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 receive403 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: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
sidlives 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 fails401even before it expires.
Transport
SendAuthorization: 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.{ "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.

