# Authentication & API keys

> How to authenticate Crius API requests with the x-api-key header, key scopes, IP allow-lists, browser origins, expiry, rotation with a grace period, and dashboard sessions.

Source: https://docs.crius.sh/authentication/ · Updated 2026-10-28

Send your API key in the **`x-api-key`** header on every request:

Terminal window

```bash
curl "https://api.crius.sh/v1/robinhood/stats" -H "x-api-key: $CRIUS_API_KEY"
```

WebSocket clients that can’t set headers may pass it as a query parameter instead: `wss://api.crius.sh/v1/robinhood/stream?api_key=…`.

Requests **without a key** are allowed for the core endpoints (prices, tokens, pools, trades, candles, search, stats) under the anonymous plan: 2 requests per second per client IP, read-only. Everything else needs a key.

## Key format

Keys look like `crs_live_AbCd1234_<secret>`:

-   `crs` identifies a Crius key (handy for secret scanners);
-   `live` or `test` is the key’s environment label;
-   `AbCd1234` is the public **prefix** shown in your dashboard and in emails;
-   the rest is the secret. It is shown **once** when the key is created. We store only a salted SHA-256 hash, so a lost key can’t be recovered: rotate it.

An account can have up to **20 active keys**. Credits and plan limits belong to the account and are shared by all its keys.

## Scopes

| Scope | Allows |
| --- | --- |
| `read` | All REST data endpoints your plan includes |
| `stream` | The WebSocket stream (also implies `read`) |
| `simulate` | Fresh on-demand security simulations (`/security?fresh=1`) |
| `export` | Bulk exports (reserved) |

The key issued when you sign up has `read`, `stream` and `simulate`; keys you create get `read` and `stream` unless you choose otherwise. Account management (keys, wallets, billing) is never possible with an API key: it needs a signed-in dashboard session, so a leaked key can read data but can’t take over your account.

## Restricting a key

Every key can be narrowed in the dashboard or through the [Account API](https://docs.crius.sh/reference/account/):

-   **IP allow-list**: one or more IPs or CIDR ranges (`203.0.113.7`, `10.0.0.0/8`, IPv6 too). Requests from anywhere else get `403 ip_not_allowed`.
-   **Allowed origins**: browser origins such as `https://app.example.com`. A key with origins becomes **read-only** and only works from those pages (`403 origin_not_allowed` otherwise). Use this for keys that must live in front-end code.
-   **Rate limit**: a per-key requests-per-second cap below your plan’s limit, so one service can’t starve another.
-   **Expiry**: the key stops working after a number of days (`401 key_expired`).

## Rotating a key

Rotation issues a new secret and keeps the old one working for a **grace period** (1 hour by default, up to 7 days) so you can deploy the new key without downtime. After the grace period the old key returns `401 key_rotated`. Revoking a key stops it immediately (`401 key_revoked`), on every region within seconds.

## Dashboard sessions

Signing in at [dashboard.crius.sh](https://dashboard.crius.sh) (email code or a linked wallet) creates a **session key** that lasts 7 days. Session keys can only call the Account API; using one on a data endpoint returns `403 session_not_api_key`. API keys calling account-management endpoints get `403 session_required`.

## Failed authentication

Invalid keys get `401 invalid_key`. After 20 failed attempts in a minute from one IP, that IP is blocked for 60 seconds (`429 auth_banned`).

Treat keys like passwords. Don’t put an unrestricted key in browser code, mobile apps or public repositories. If a key leaks, revoke or rotate it in the dashboard; we also email you whenever a key is created, rotated or revoked.
