# API access

> Get an API key, keep it on your backend, and know what it can and cannot do.

Khalani issues API keys during onboarding. There is no self-serve sign-up. With your key you receive:

- **Your integrator name**, which scopes your orders. Error messages identify you by its `integratorId`, the `keccak256` hash of the name.
- **Your commercial terms**: your commission in basis points and the hub wallet it is paid to. They live in an on-chain integrator registry that the hub contract reads when each order publishes, so no request can change them.
- **Your order deadline** (`orderTtl`): how long each order stays open after the build. It is an API setting that every build signs into its order.

Read all of them with `GET /v2/params`.

## Send the key from your backend

Send the key in the `X-API-Key` header:

```bash
curl -s https://api.hyperstream.dev/v2/params -H "X-API-Key: $KHALANI_API_KEY"
```

Call the API from your backend only. CORS is open (`*`) for convenience, not permission: a key shipped in a browser or app bundle is a key anyone can use.

| Route | Auth |
|---|---|
| `GET /v2/params` | API key |
| `GET /v2/quote` | API key |
| `POST /v2/build` | API key |
| `GET /v2/orders` | API key |
| `POST /v2/orders/{orderId}/cancel` | API key |
| `GET /v2/orders/{orderId}` | Public: the `orderId` is the credential |
| `GET /v2/health` | Public |

## What a key can do

One key is your whole integration. It can build orders under your name, list every order you built along with each depositor and recipient, and read your terms.

It cannot move funds. A deposit is a transaction the user signs, and a cancel needs the user's signature. A leaked key cannot spend anyone's tokens, but it can build orders under your name and read your order history, so treat it as a secret.

Keys have no scopes and no expiry. Rotation is arranged with Khalani: the old key keeps working for an agreed grace period. A change to your terms can take up to 60 seconds to show.

## Authentication errors

| Status | `error` | Meaning |
|---|---|---|
| `401` | `X-API-Key required` | The header is missing. |
| `403` | `Unknown or inactive integrator` | The key is not recognised, or its rotation grace period has ended. |
| `403` | `Integrator <integratorId> is not enabled on the integrator registry` | The key is valid, but your account is disabled or not set up yet. |
| `403` | `Integrator <integratorId> owes a commission with no wallet configured` | Your terms are invalid. |
| `403` | `Integrator <integratorId> carries a fee at or above 100%` | Your terms are invalid. |
| `503` | `Integrator terms are temporarily unreadable` | Your terms could not be read from the hub. This says nothing about your key. Retry. |

A `403` is always about your account and a `503` never is, so retry logic can treat every `403` as final. Contact Khalani through your onboarding channel to resolve one.

## Check that you are ready

`GET /v2/params` is the readiness check for your key. It reflects your account, is not rate limited, and keeps working during maintenance. A `200` means your key works and your account is enabled; a `403` names the problem. The `tokens` list is the same for every integrator.

`GET /v2/health` is not a readiness check. It reports the order pipeline across all integrators.
