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

# Authentication

> XO Orderbook uses two layered auth schemes. L1 ClobAuth (EIP-712 wallet signature) mints the API key. L2 HMAC signs every authenticated request thereafter.

The XO Orderbook uses two layered authentication schemes:

| Scheme          | Purpose                                            | Used by                                                                                         |
| --------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| **L1 ClobAuth** | EIP-712 wallet signature; proves wallet ownership. | `POST /auth/api-key`, `GET /auth/derive-api-key`, `DELETE /auth/api-key`, `GET /auth/api-keys`. |
| **L2 HMAC**     | Per-request secret-keyed signature.                | Every other authenticated endpoint.                                                             |

`signatureType = 3` (XO smart account, ERC-1271) is the only order-signing model accepted by the orderbook today. See [Smart accounts](/guides/smart-accounts) for the maker-side detail.

***

## L1 ClobAuth

A four-header EIP-712 wallet signature used to mint, derive, list, and delete API keys.

### Headers

| Header         | Required | Notes                                                                            |
| -------------- | -------- | -------------------------------------------------------------------------------- |
| `XO_ADDRESS`   | yes      | Maker address. For smart accounts, this is the smart account, not the owner EOA. |
| `XO_SIGNATURE` | yes      | Hex-encoded EIP-712 signature over the `ClobAuth` struct.                        |
| `XO_TIMESTAMP` | yes      | Unix seconds, as a string.                                                       |
| `XO_NONCE`     | no       | Integer nonce; defaults to `0` if absent.                                        |

Hyphenated forms (`Xo-Address`, `Xo-Signature`, etc.) are accepted as a fallback.

### Signed struct

```text theme={null}
ClobAuth(address address, string timestamp, uint256 nonce, string message)
```

### EIP-712 domain

```text theme={null}
name    = "ClobAuthDomain"
version = "1"
chainId = <XO chain id>
```

### Smart-wallet signatures

Smart-wallet signatures are verified via ERC-1271. For XO Privy/ZeroDev smart accounts, set `XO_ADDRESS` to the smart account; the owner EOA is only the controller and is not the authenticating principal.

***

## L2 HMAC

A four-header per-request signature used by every authenticated endpoint other than the L1 ClobAuth flow.

### Headers

| Header          | Required | Notes                                                           |
| --------------- | -------- | --------------------------------------------------------------- |
| `XO_API_KEY`    | yes      | API key identifier returned by `POST /auth/api-key`.            |
| `XO_TIMESTAMP`  | yes      | Unix seconds, as a string. Must be within ±30 s of server time. |
| `XO_PASSPHRASE` | yes      | Constant-time-compared passphrase returned with the API key.    |
| `XO_SIGNATURE`  | yes      | URL-safe base64 HMAC-SHA256 of the canonical request string.    |

### Canonical request string

```text theme={null}
timestamp + method + path + body
```

* `timestamp` — same value sent in `XO_TIMESTAMP`.
* `method` — uppercase HTTP method (e.g. `GET`, `POST`).
* `path` — request path **including** the query string when present.
* `body` — raw request body, or empty string for body-less methods.

The signature is then computed as:

```text theme={null}
URL_SAFE_BASE64( HMAC_SHA256(secret, timestamp + method + path + body) )
```

### Clock skew

Reject the request locally if your clock drifts more than ±30 s from server time. Use `GET /time` to align.

***

## Creating an API key

<Steps>
  <Step title="Sign the ClobAuth struct">
    Build the `ClobAuth(address, timestamp, nonce, message)` struct, sign it with the maker key under the `ClobAuthDomain` EIP-712 domain, and send `POST /auth/api-key` with the four L1 headers.
  </Step>

  <Step title="Persist the triplet">
    The response returns `{ apiKey, secret, passphrase }`. Store all three; the secret is only shown once.
  </Step>

  <Step title="Sign subsequent requests with L2 HMAC">
    Every authenticated request after the L1 flow uses the four L2 headers above.
  </Step>
</Steps>

***

## WebSocket authentication

The `/ws/user` channel authenticates with the **same L2 HMAC triplet** delivered inside the subscribe message body (not as HTTP headers). See the WebSockets section for the subscribe shape.

## Related guides

* [Smart accounts](/guides/smart-accounts) — signature types, ERC-1271, and the smart-account model.
