# Authentication

One header, four key forms, and the replay-protection pair that travels with them. x-sidaxis-api-key on every call; one read takes a first-party user token instead.

```
x-sidaxis-api-key: sk_live_… | sk_test_… | pk_live_… | pk_test_…
```

The legacy header `x-sieve-api-key` is accepted with identical semantics; when both are present, `x-sidaxis-api-key` wins. The legacy contract will not be broken.

> There is no `Authorization: Bearer sk_live_…` on this API. A secret key is never a bearer token here.

## Four key forms

| Key | Where it runs | What it reaches |
| --- | --- | --- |
| pk_live_ / pk_test_ | Browser | face-identify, process-biovital-enrollment, handoff-register-public, merchant-theme-get, alias-availability |
| sk_live_ / sk_test_ | Your server | Everything else |

A `pk_*` key on a server endpoint is `401 AUTH_REQUIRED`. A `pk_*` key is publishable by design: it is in the page source of every hosted surface.

### Why merchant-theme-get accepts a publishable key

Its response carries no key, no policy, no threshold and no subject data — nothing that changes a verdict — and the hosted surface has to paint itself before any identity exists, so it can only carry a browser key. See [theme](/theme).

## The one exception: a first-party user token

`get-merchant-receipts-v2` authenticates with a first-party Sieve ID JWT in `Authorization: Bearer`, because the ownership model is “the Sieve ID user owns the merchant”. A merchant API key there is refused with `403 sieve_id_jwt_required`. See [receipts/get](/receipts/get).

## Replay protection

Required alongside the key on `face-identify`, `process-biovital-transaction` and all `mandate-*` calls:

| Header | Value | Rule |
| --- | --- | --- |
| x-sidaxis-timestamp | Unix seconds | Accepted within ±300 s of server time |
| x-sidaxis-nonce | ≥8 characters | Single use; reuse answers 409 |

```
-H "x-sidaxis-api-key: sk_live_..." \
-H "x-sidaxis-timestamp: 1789564803" \
-H "x-sidaxis-nonce: 9f2c41ab7d"
```

## Sandbox

Sandbox is not a host. Same base URL, same tables; the merchant and the key prefix decide the environment. See [sandbox](/sandbox).

## Versioning

There is no dated API version header today, and no `Sidaxis-Version`. Dated versioning is an intention, not a contract — see [roadmap](/roadmap).

- Errors and refusals: https://docs.sidaxis.com/errors
- Rate limits: https://docs.sidaxis.com/rate-limits
