> For the complete documentation index, see [llms.txt](https://agentdex.gitbook.io/agentdex-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://agentdex.gitbook.io/agentdex-docs/developers/api-keys.md).

# API keys

API keys are how everything non-UI talks to AgentDex — bots, agents, MCP clients, server-to-server integrations. The same key works across REST, WebSocket, and MCP. Each key is scoped: `pub`, `ro`, or `rw`, with optional trading limits on `rw`.

### Key format

Two pieces:

| Identifier    | What it is                                      | Where it goes                                      |
| ------------- | ----------------------------------------------- | -------------------------------------------------- |
| `key`         | The full secret. **Returned once at creation.** | `X-Api-Key` header on every authenticated request. |
| `short_token` | A non-secret stable id.                         | Used to list and revoke keys; correlation in logs. |

You can have multiple keys per account. Different keys can have different scopes and different limits — common pattern is one key per bot or per agent.

### Permission model

The `permissions` object on a key:

{% code title="Example permissions object" %}

```json
{
  "scope": "rw",
  "expiration": "2026-12-31T00:00:00Z",
  "instruments": ["BTC_USDT_PERPETUAL"],
  "leverage_gte": 10,
  "leverage_lte": 20,
  "order_quoted_volume_gte": "1",
  "order_quoted_volume_lte": "100"
}
```

{% endcode %}

| Field                                                 | Notes                                                                         |
| ----------------------------------------------------- | ----------------------------------------------------------------------------- |
| `scope`                                               | `"ro"` or `"rw"` (no public key creation; public access works without a key). |
| `expiration`                                          | Optional ISO-8601 timestamp; key invalid after this time.                     |
| `instruments`                                         | Optional allowlist. Empty / missing = unrestricted.                           |
| `leverage_gte` / `leverage_lte`                       | Optional bounds. Hard cap is 100 regardless of `_lte`.                        |
| `order_quoted_volume_gte` / `order_quoted_volume_lte` | Optional bounds, quote currency.                                              |

Server-side enforcement:

* Leverage must be in `[1, 100]`.
* If both `gte` and `lte` are set, `gte ≤ lte`.
* Quoted volumes must be positive and ordered.

### Endpoints

#### Create

`POST /api/keychain/api-keys`

Requires an authenticated user session.

Request:

{% code title="Create key request" %}

```json
{
  "label": "trading-bot-1",
  "permissions": { "scope": "rw", "instruments": ["BTC_USDT_PERPETUAL"], "leverage_lte": 20 }
}
```

{% endcode %}

Response (`201 Created`):

{% code title="Create key response" %}

```json
{
  "key": "dexkey_XXXXXXXXXXXXXXXXXXXXXX",
  "short_token": "k_1234567890",
  "permissions": { ... },
  "created_at": "2026-05-28T00:00:00Z",
  "expires_at": null
}
```

{% endcode %}

**Store `key` securely now.** It will not be returned by `list`.

#### List

`GET /api/keychain/api-keys`

Returns the user's keys (without secrets):

{% code title="List keys response" %}

```json
[
  {
    "short_token": "k_1234567890",
    "label": "trading-bot-1",
    "permissions": { ... },
    "created_at": "2026-05-28T00:00:00Z",
    "expires_at": null,
    "last_used_at": "2026-05-29T12:00:00Z"
  }
]
```

{% endcode %}

#### Revoke

`DELETE /api/keychain/api-keys/{short_token}`

Returns `204 No Content`. Returns `404` if the key doesn't exist or doesn't belong to you.

#### Verify (internal services only)

`GET /api/keychain/permissions` with `X-Api-Key` header. Returns `{ user_id, permissions }`. Used by internal services to resolve a raw key; user-facing apps don't need this.

### Best practices

#### One key per workload

A bot and an agent should have separate keys. Granular revocation, granular limits, clearer audit trail.

#### Tight limits per key

You don't have to maximise scope. A scalping bot doesn't need `leverage_lte: 100`. Set it to what the strategy actually needs and revisit when the strategy changes.

If a key is meant for an LLM agent, the more constrained, the less you have to trust the agent. A key with `instruments: ["BTC_USDT_PERPETUAL"]`, `leverage_lte: 10`, `order_quoted_volume_lte: "100"` means an agent's worst case is a $100 BTC order at 10× — a small, recoverable mistake.

#### Rotate aggressively

If you suspect a key leaked: revoke first, replace second. There is no recovery; a revoked key is dead.

#### Never commit keys

Use environment variables or a secret manager. AgentDex's monitoring flags suspicious-looking strings in public PRs and tickets — but the only real defence is not putting the key on a public surface in the first place.

#### Don't share a key between services

Co-located bots that share a single key share rate limits, share the same kill switch, and share the same blast radius. Each service should have its own.

### What you cannot do

* **Recover a lost key.** There is no "show me my old key" endpoint. Revoke and create a new one.
* **Elevate a `ro` key to `rw` without recreating it.** Permissions are immutable on a key.
* **Set `scope: "pub"`.** Public access works without a key — there's no "public key" object.
* **Bypass the hard 100× leverage cap** via any combination of limits.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://agentdex.gitbook.io/agentdex-docs/developers/api-keys.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
