> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kairos.trade/llms.txt
> Use this file to discover all available pages before exploring further.

# Partner API authentication

> Partner ids, API keys, the version header, and the wallet sign-in token: which request needs what.

Every wallet API request answers two questions:

1. **Who is the integrator?** Your partner id, or your API key.
2. **Who is the wallet owner?** For most calls, the wallet's own signatures prove it. Reads of private data and a few preview endpoints also need a **sign-in token** or an API key that owns the wallet.

## Base URL

Kairos gives you a base URL together with your partner id. Every path in these docs is relative to it. Preview features are tested on staging at `https://staging-execution.kairos.trade`.

## Headers

| Header | When | Value |
| - | - | - |
| `X-Kairos-Wallet-Api` | Every request | `2`. Only the exact value `2` turns on every venue. See [the version header](#the-version-header) |
| `X-Kairos-Partner-Id` | Every request, **or** send an API key instead | Your partner id. Letters, digits, `.`, `_`, `:` and `-`, up to 64 characters. Case doesn't matter |
| `X-Client-Id`, `X-Api-Key`, `X-Api-Secret` | Instead of the partner id, when you trade for yourself | An API key with the `trade:execute` scope |
| `Authorization: SIWE <token>` | Orders and positions reads; trade plans, fees and on-chain intents | The token from a [`login` action](#the-sign-in-token) |
| `Idempotency-Key` | Preparing a trade plan or an on-chain intent | 1–128 printable ASCII characters, no spaces. Not used by `/v3/actions`: use `clientOrderId` there |
| `Content-Type: application/json` | Every request with a body | |

## Partner id or API key

> [tab] Apps and wallets (partner id)
>
> Your users sign with their own wallets and need no Kairos account. Send your partner id on every request:
>
> ```bash theme={null}
> curl "$BASE/v3/wallets/$WALLET" \
>   -H "X-Kairos-Partner-Id: $PARTNER" \
>   -H "X-Kairos-Wallet-Api: 2"
> ```
>
> The partner id isn't a secret: it names your integration. Every action still needs the wallet's own signature, so a partner id alone can't trade for anyone.

> [tab] Trading for yourself (API key)
>
> Ask Kairos to enable the wallet API for your account. Then send an API key **instead of** the partner id:
>
> ```bash theme={null}
> curl "$BASE/v3/wallets/$WALLET" \
>   -H "X-Client-Id: $CLIENT_ID" -H "X-Api-Key: $API_KEY" -H "X-Api-Secret: $API_SECRET" \
>   -H "X-Kairos-Wallet-Api: 2"
> ```
>
> * The key needs `trade:execute`, **even for reads**. A key with only `trade:read` is refused with `403`.
> * Add `trade:read` too if you use trade plans, fees or on-chain intents: their reads check it.
> * A key bound to one wallet can only reach that wallet. Any other wallet answers `404`.
> * Keep keys on your server. Never ship them to a browser.
>
> If Kairos gave you a partner id that belongs to your own account, send your key, not that id. The id alone answers `403`.

```js SDK theme={null}
// Partner id: a browser app or wallet
createKairos({ wallet: { baseUrl, partnerId, provider } })

// API key: your own server
createKairos({ wallet: { baseUrl, apiKey: { clientId, apiKey, apiSecret }, provider } })
```

## The version header

Send `X-Kairos-Wallet-Api: 2` on every request. The SDK does it for you.

Without it, the same paths serve the original Polymarket-only contract. That contract ignores `expiresAt` and `setup.venues`, and doesn't accept `polymarket:` market prefixes. Its reads return different shapes. It also refuses an order on a wallet that isn't set up, instead of running setup first. Every page here describes version `2`.

## The sign-in token

Orders and positions are private. To read them, the wallet signs in once with Ethereum (SIWE), and you send the token it returns:

1. `POST /v3/actions` with `{ "wallet": "0x…", "action": { "type": "login" } }`.

2. The step asks for one `personal_sign` of a message like this:

   ```text theme={null}
   <host> wants you to sign in with your Ethereum account:
   0xYourChecksummedAddress

   Allow this app to read your Kairos orders and positions.

   URI: https://<host>
   Version: 1
   Chain ID: 137
   Nonce: 4f1c…
   Issued At: 2026-10-28T12:00:00Z
   Expiration Time: 2026-10-29T12:00:00Z
   Resources:
   - urn:kairos:partner:<your partner id>
   ```

3. Post the signature back. The action ends `done` with `result: { "token": "…", "expiresAt": "…" }`.

4. Send `Authorization: SIWE <token>` on the calls that need it.

What to know about the token:

* **It can't move funds.** Every order, cancel, plan and transfer still needs its own wallet signature.
* It lasts 24 hours. A token that has expired, belongs to another wallet, or was issued for another partner or environment answers `401` (or `404` for another wallet).
* Kairos checks it by signature alone and stores nothing. It can't be revoked early, so it just expires.
* Signing in needs a wallet that has run [setup](https://docs.kairos.trade/wallets/setup.md) on at least one venue. Otherwise you get `409`.

| Call | Partner id | API key | Sign-in token |
| - | - | - | - |
| Actions (`/v3/actions`) | Yes | Yes (`trade:execute`) | Not needed |
| Wallet status (`GET /v3/wallets/{address}`) | Yes | Yes | Not needed |
| Orders and positions reads | Yes, plus the token | Only if the key's account owns the wallet; otherwise add the token | **Required** with a partner id |
| Trade plans, fees, on-chain intents (preview) | Yes, plus the token | Only if the key's account owns the wallet; otherwise add the token | **Required** with a partner id |

> [!NOTE]
>
> Wallet status is not private. It shows readiness and collateral balances, which are on-chain facts. Any integrator can read it for any address.

## Calling from a browser

The API allows browser requests only from origins Kairos has allowlisted. A web app calling your base URL directly from its own domain will fail the CORS preflight. When you get your partner id, either:

* ask Kairos to allowlist your app's origins, or
* call the API from your own server and pass the wallet's signatures through.

## Rate limits

| Limit | Value |
| - | - |
| Requests per route | 120 a minute per client IP, or 1000 a minute when the request carries `X-Client-Id` |
| New wallets | Each partner can create about 1000 new wallets an hour. Ask Kairos if you need more |
| Cancel | Up to 100 order ids per cancel |

The limit is per route and per IP. A server that proxies many users from one IP shares one budget. A `429` answers `{"error":"rate limit exceeded for this endpoint; retry later"}` with no `Retry-After` header: back off on your own schedule. When the limiter itself is unavailable, the API refuses with `503 {"error":"rate limiter unavailable"}` rather than letting requests through.

## Auth errors

| Status | `error` | Fix |
| - | - | - |
| `400` | `partner id header is not valid ASCII` | Check the header value |
| `400` | `partner id header must not be blank`, `partner id header too long (max 64 chars)`, `partner id header contains invalid characters (allowed: A-Z a-z 0-9 . _ - :)` | Fix the header value |
| `401` | `send X-Kairos-Partner-Id or your API key (X-Client-Id, X-Api-Key, X-Api-Secret)` | Send one of them |
| `401` | `invalid API key` | Check the three key headers |
| `401` | `malformed sign-in token`, `sign-in token has expired; run a login action` | Sign in again |
| `401` | `sign-in token was issued for another partner or node` | Use a token from this partner and environment |
| `401` | `sign-in token signature is not from its wallet` | Sign in again |
| `403` | `unknown partner id` | Check the id, or ask Kairos to enable it |
| `403` | `this partner id is used with its API key; send the key instead of X-Kairos-Partner-Id` | Send your API key |
| `403` | `this API key lacks the trade:execute scope` | Add the scope to the key |
| `403` | `the wallet API is not enabled for this account` | Ask Kairos to enable it |
| `403` | `API key missing trade:read scope` | Add `trade:read` for plan, fee and intent reads |
| `404` | `wallet not found` | The token or key doesn't own this wallet, or the wallet isn't set up |
| `503` | `partner registry unavailable; retry shortly` | Retry |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.