# Authentication

HermesTrade uses three authentication patterns depending on which API and operation you are performing.

***

## CLOB API — L1 Authentication (EIP-712 wallet)

L1 authentication proves ownership of an EOA (externally owned account) using an EIP-712 signature. It is used only for API key management operations — not for trading.

**Required headers:**

| Header           | Value                                              |
| ---------------- | -------------------------------------------------- |
| `PRED_ADDRESS`   | Your EOA wallet address                            |
| `PRED_SIGNATURE` | EIP-712 signature of a timestamped request message |
| `PRED_TIMESTAMP` | Current Unix timestamp in seconds                  |
| `PRED_NONCE`     | Random nonce string                                |

**Endpoints that require L1 auth:**

| Method   | Path                   | Description                     |
| -------- | ---------------------- | ------------------------------- |
| `POST`   | `/auth/api-key`        | Create a new API key            |
| `DELETE` | `/auth/api-key`        | Revoke an existing API key      |
| `GET`    | `/auth/derive-api-key` | Re-derive a lost API key secret |

***

## CLOB API — L2 Authentication (API key)

L2 authentication uses an API key and HMAC signature for all trading and account operations. It is faster to compute than EIP-712 and is used for every authenticated request during normal trading.

**Required headers:**

| Header            | Value                                     |
| ----------------- | ----------------------------------------- |
| `PRED_API_KEY`    | The `apiKey` string from `APIKeyResponse` |
| `PRED_PASSPHRASE` | The passphrase set at key creation        |
| `PRED_SIGNATURE`  | HMAC signature of the request             |
| `PRED_TIMESTAMP`  | Current Unix timestamp in seconds         |

**Optional header:**

| Header          | Value                                                  |
| --------------- | ------------------------------------------------------ |
| `PRED_SCOPE_ID` | Tenant scope identifier (whitelabel integrations only) |

**Endpoints that require L2 auth:** All authenticated trade endpoints (`POST /order`, `DELETE /order`, `POST /orders`, `DELETE /orders`, etc.) and account endpoints (`GET /balance-allowance`, `GET /transactions`, `GET /orders`, `GET /trades`).

**L2 signing algorithm:** The `PRED_SIGNATURE` value is an HMAC signature computed over the request. The exact algorithm details (hash function, message construction, key derivation) should be confirmed with the HermesTrade team or an official SDK when available. A common pattern for CLOB APIs is HMAC-SHA256 over `timestamp + method + requestPath + body`, but do not assume this without confirmation.

***

## API key management

API keys are scoped to your wallet address. Key operations:

| Method   | Path                   | Auth | Description                                 |
| -------- | ---------------------- | ---- | ------------------------------------------- |
| `POST`   | `/auth/api-key`        | L1   | Create a new key — returns `APIKeyResponse` |
| `GET`    | `/auth/api-keys`       | L2   | List all active keys                        |
| `DELETE` | `/auth/api-key`        | L1   | Revoke a key                                |
| `GET`    | `/auth/derive-api-key` | L1   | Re-derive a lost key secret                 |

**`APIKeyResponse` fields:**

| Field        | Type   | Notes                                           |
| ------------ | ------ | ----------------------------------------------- |
| `apiKey`     | string | The key identifier used in `PRED_API_KEY`       |
| `secret`     | string | Returned only at creation; store it immediately |
| `passphrase` | string | Set at creation; used in `PRED_PASSPHRASE`      |

{% hint style="warning" %}
The `secret` is returned only when the key is first created. If you lose it, use `GET /auth/derive-api-key` (L1 auth required) to recover it.
{% endhint %}

***

## Gamma API — Bearer JWT (EIP-712 login flow)

The Gamma API uses a JWT-based login flow. The JWT is obtained by signing an EIP-712 nonce with your wallet.

### Step 1 — Get a nonce

```
GET /auth/nonce?address=<your_EOA_address>
```

Response (`nonceResponse`):

| Field       | Type    | Description                                    |
| ----------- | ------- | ---------------------------------------------- |
| `nonce`     | string  | The nonce to sign                              |
| `scopeId`   | string  | Tenant scope (may be empty for standard users) |
| `issuedAt`  | string  | Issuance timestamp                             |
| `chainId`   | integer | The Monad chain ID                             |
| `statement` | string  | Human-readable login statement                 |

### Step 2 — Sign the nonce

Sign the nonce message using EIP-712 with your EOA wallet. The message format uses the `statement`, `nonce`, `issuedAt`, and `chainId` from the nonce response.

### Step 3 — Log in

```
POST /auth/login
```

Request body (`loginRequest`):

| Field           | Type   | Description                                         |
| --------------- | ------ | --------------------------------------------------- |
| `signature`     | string | Your EIP-712 signature of the nonce message         |
| `messageParams` | object | The full message parameters from the nonce response |

Response (`docTokenResponse`):

| Field   | Type   | Description      |
| ------- | ------ | ---------------- |
| `token` | string | JWT Bearer token |

### Step 4 — Use the token

Include the token in all authenticated Gamma API requests:

```
Authorization: Bearer <token>
```

**Authenticated Gamma endpoints:** `POST /profiles` (create/update profile), `POST /auth/refresh`.

### Refreshing the token

Call `POST /auth/refresh` with a valid `Authorization: Bearer <token>` header before the token expires to obtain a new token.

***

## Relayer API — Authentication

The Relayer API accepts either a `RelayerAPIKey` or a `Bearer JWT` (the same JWT issued by the Gamma login flow).

### Obtaining a RelayerAPIKey

```
POST /relayer/api/auth
```

Requires a valid `Authorization: Bearer <JWT>` header. Returns an `APIKeyResponse`:

| Field       | Type     | Description                        |
| ----------- | -------- | ---------------------------------- |
| `apiKey`    | string   | The relayer API key                |
| `address`   | string   | Wallet address the key is bound to |
| `scopeId`   | string   | Tenant scope                       |
| `createdAt` | datetime | Creation timestamp                 |
| `updatedAt` | datetime | Last updated timestamp             |

### Managing Relayer API keys

| Method   | Path                     | Auth          | Description                  |
| -------- | ------------------------ | ------------- | ---------------------------- |
| `POST`   | `/relayer/api/auth`      | Bearer JWT    | Create a new relayer API key |
| `GET`    | `/relayer/api/keys`      | RelayerAPIKey | List your active keys        |
| `DELETE` | `/relayer/api/keys/{id}` | RelayerAPIKey | Revoke a specific key        |

***

## Order signing (EIP-712)

Every order submitted to the CLOB API must be signed by the maker using EIP-712. The EIP-712 domain separator uses the Monad chain ID (retrieve from `GET /auth/nonce` on the Gamma API or from `GET /public-info`).

**Order struct fields that are signed:**

| Field           | Type   | Description                                          |
| --------------- | ------ | ---------------------------------------------------- |
| `maker`         | string | Maker address (typically your proxyWallet)           |
| `makerAmount`   | string | Amount the maker is giving                           |
| `side`          | enum   | `BUY` or `SELL`                                      |
| `signer`        | string | EOA that is signing the order                        |
| `taker`         | string | Taker address (typically the CLOB exchange contract) |
| `takerAmount`   | string | Amount the taker receives                            |
| `tokenID`       | string | Uint256 token ID of the outcome share                |
| `expiration`    | string | Unix timestamp; `"0"` for GTC orders                 |
| `feeRateBps`    | string | Fee rate in basis points                             |
| `nonce`         | string | Order nonce                                          |
| `salt`          | string | Random salt for uniqueness                           |
| `scopeId`       | string | Optional tenant scope                                |
| `signatureType` | string | Signature type identifier                            |

The exact EIP-712 type hash and domain separator parameters should be confirmed with the HermesTrade team or an official SDK when available.

***

## scopeId

`scopeId` is an optional tenant identifier for whitelabel and embedded integrations. It appears in:

* Gamma API nonce response (`scopeId` field)
* CLOB API headers (`PRED_SCOPE_ID`)
* Relayer API requests and responses
* The `Order` struct (`scopeId` field)

Standard users can omit `scopeId` in all contexts. Whitelabel partners must set it to their assigned scope value in every request.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hermestrade.xyz/reference/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
