# API keys

Keys for calling the API from your servers. Integrators manage them here.

## Endpoints

-   [GET `/v2/api-keys`](https://public-api.dapi.digital/docs/reference/api-keys.md#list_api_keys)
-   [POST `/v2/api-keys`](https://public-api.dapi.digital/docs/reference/api-keys.md#create_api_key)
-   [DELETE `/v2/api-keys/{id}`](https://public-api.dapi.digital/docs/reference/api-keys.md#revoke_api_key)

## The api key object

A secret key for calling the API from your servers, sent in the `x-api-key` header. Its secret is shown once, when it is created.

### Attributes

-   `id` (string): Unique identifier of the api key, prefixed with `key_`. Treat it as an opaque string: store it and compare it, never parse it.
-   `object` (string): Names the type of this object. Always `api_key`.
-   `name` (string): Your label for the key, for example where it is used.
-   `preview` (string): The first characters of the key, to recognise it. Never enough to authenticate with.
-   `scopes` (array of string): What the key may do. Integrator keys carry `quotes:read`, `quotes:write`, `orders:read`, `orders:write`, `orders:read_customer`, `extras:read`, `extras:write`, `wallet:read`, `webhooks:read`.
-   `created_at` (timestamp): Point in time, ISO 8601 in UTC.
-   `last_used_at` (timestamp or null): When the key last authenticated a request, to the minute. Null if it was never used.

**The api key object**

```json
null
```

## List API keys

GET `/v2/api-keys`

- **Credentials**: A signed-in dashboard session only; API keys are refused.

- **For**: Integrators

- **Operation id**: `list_api_keys`

Lists your active API keys, newest first, without their secrets. Revoked keys are not listed. Integrators only, and only with a signed-in dashboard session: an API key cannot manage keys (`credential_not_allowed`).

### Returns 200 OK

Your active keys, all on one page.

Response attributes (ApiKeyList):

-   `object` (string): Names the type of this object. Always `list`.
-   `data` (array of ApiKey): The page of results.
    
    Described in [the api key object](https://public-api.dapi.digital/docs/reference/api-keys.md#api_key_object).
    
-   `has_more` (boolean): True when more results exist after this page. Fetch them by passing `next_cursor` as `cursor`.
-   `next_cursor` (string or null): Opaque cursor for the next page, or null on the last page. Pass it back unchanged as `cursor`.

### Responses

-   `200`: Your active keys, all on one page.
-   `401`: Credentials are missing (`missing_credentials`), the API key is unknown or inactive (`invalid_api_key`), the session expired (`invalid_session`), or both a key and a session were sent (`ambiguous_credentials`).
-   `403`: The credentials are valid but not allowed to do this: a scope is missing (`missing_scope`), the endpoint is for another kind of account (`actor_not_allowed`) or another kind of credential (`credential_not_allowed`), the account may no longer use the API (`account_blacklisted`), or the account must change something first, in which case `details.fix_url` links to the dashboard page that fixes it.
-   `429`: Too many requests (`rate_limited`): the limit is 500 per minute per API key (or signed-in user). Wait for the number of seconds in the `Retry-After` header, then retry; `details` has `limit`, `window_seconds`, `reset_at` and `retry_after_seconds`.

Errors use [the error object](https://public-api.dapi.digital/docs/guides/errors.md#error-object).

**Request**

```bash
curl "https://public-api.dapi.digital/v2/api-keys" \
  -H "x-api-key: $DAPI_API_KEY"
```

**Response 200**

```json
{
  "object": "list",
  "data": [
    {
      "id": "key_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
      "object": "api_key",
      "name": "Production server",
      "preview": "sk_3f9a1c2b7...",
      "scopes": [
        "quotes:read",
        "quotes:write"
      ],
      "created_at": "2026-10-20T09:30:00Z",
      "last_used_at": null
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

## Create an API key

POST `/v2/api-keys`

- **Credentials**: A signed-in dashboard session only; API keys are refused.

- **For**: Integrators

- **Operation id**: `create_api_key`

Creates a secret key for calling the API from your servers. The response is the only time the full key (`secret`) is shown; store it securely.

Keys work before your account is approved, with the same onboarding limits as the dashboard. Up to 10 active keys per account; revoke one to make room.

Integrators only, and only with a signed-in dashboard session: an API key cannot manage keys (`credential_not_allowed`).

### Request body

-   `name` (string, required): A label for the key, 1 to 50 characters.
-   `scopes` (array of string, required): What the key may do. Allowed for integrators: `quotes:read`, `quotes:write`, `orders:read`, `orders:write`, `orders:read_customer`, `extras:read`, `extras:write`, `wallet:read`, `webhooks:read`.

### Returns 201 Created

The key, with its secret shown once.

Response attributes (CreatedApiKey):

-   `id` (string): Unique identifier of the api key, prefixed with `key_`. Treat it as an opaque string: store it and compare it, never parse it.
-   `object` (string): Names the type of this object. Always `api_key`.
-   `name` (string): Your label for the key, for example where it is used.
-   `preview` (string): The first characters of the key, to recognise it. Never enough to authenticate with.
-   `scopes` (array of string): What the key may do. Integrator keys carry `quotes:read`, `quotes:write`, `orders:read`, `orders:write`, `orders:read_customer`, `extras:read`, `extras:write`, `wallet:read`, `webhooks:read`.
-   `created_at` (timestamp): Point in time, ISO 8601 in UTC.
-   `last_used_at` (timestamp or null): When the key last authenticated a request, to the minute. Null if it was never used.
-   `secret` (string): The full key. Shown only in this response: store it securely now, it cannot be retrieved later. If it is lost, revoke the key and create a new one.

### Responses

-   `201`: The key, with its secret shown once.
-   `400`: The request is invalid (`validation_failed`).
-   `401`: Credentials are missing (`missing_credentials`), the API key is unknown or inactive (`invalid_api_key`), the session expired (`invalid_session`), or both a key and a session were sent (`ambiguous_credentials`).
-   `403`: Called with an API key instead of a session (`credential_not_allowed`), or not an integrator account (`actor_not_allowed`).
-   `409`: You already have 10 active keys (`key_limit_reached`). Revoke one first.
-   `422`: A scope is unknown or not allowed for your account (`scope_not_allowed`, `details.scopes`). Allowed: `quotes:read`, `quotes:write`, `orders:read`, `orders:write`, `orders:read_customer`, `extras:read`, `extras:write`, `wallet:read`, `webhooks:read`.
-   `429`: Too many requests (`rate_limited`): the limit is 500 per minute per API key (or signed-in user). Wait for the number of seconds in the `Retry-After` header, then retry; `details` has `limit`, `window_seconds`, `reset_at` and `retry_after_seconds`.

Errors use [the error object](https://public-api.dapi.digital/docs/guides/errors.md#error-object).

**Request**

```bash
curl -X POST "https://public-api.dapi.digital/v2/api-keys" \
  -H "x-api-key: $DAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Production server",
  "scopes": [
    "quotes:read",
    "quotes:write"
  ]
}'
```

**Response 201**

```json
{
  "id": "key_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
  "object": "api_key",
  "name": "Production server",
  "preview": "sk_3f9a1c2b7...",
  "scopes": [
    "quotes:read",
    "quotes:write"
  ],
  "created_at": "2026-10-20T09:30:00Z",
  "last_used_at": null,
  "secret": "sk_3f9a1c2b7d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e41"
}
```

## Revoke an API key

DELETE `/v2/api-keys/{id}`

- **Credentials**: A signed-in dashboard session only; API keys are refused.

- **For**: Integrators

- **Operation id**: `revoke_api_key`

Revokes a key at once: the next request made with it is refused with `invalid_api_key`. This cannot be undone. Integrators only, and only with a signed-in dashboard session: an API key cannot manage keys (`credential_not_allowed`).

### Path parameters

-   `id` (string, required): Unique identifier of the api key, prefixed with `key_`. Treat it as an opaque string: store it and compare it, never parse it.

### Returns 200 OK

The key was revoked.

Response attributes (ApiKeyDeleted):

-   `id` (string): Unique identifier of the api key, prefixed with `key_`. Treat it as an opaque string: store it and compare it, never parse it.
-   `object` (string): Names the type of this object. Always `api_key`.
-   `deleted` (boolean): Always true: the key is revoked and every request made with it is refused.

### Responses

-   `200`: The key was revoked.
-   `401`: Credentials are missing (`missing_credentials`), the API key is unknown or inactive (`invalid_api_key`), the session expired (`invalid_session`), or both a key and a session were sent (`ambiguous_credentials`).
-   `403`: The credentials are valid but not allowed to do this: a scope is missing (`missing_scope`), the endpoint is for another kind of account (`actor_not_allowed`) or another kind of credential (`credential_not_allowed`), the account may no longer use the API (`account_blacklisted`), or the account must change something first, in which case `details.fix_url` links to the dashboard page that fixes it.
-   `404`: You have no active key with this id (`api_key_not_found`).
-   `429`: Too many requests (`rate_limited`): the limit is 500 per minute per API key (or signed-in user). Wait for the number of seconds in the `Retry-After` header, then retry; `details` has `limit`, `window_seconds`, `reset_at` and `retry_after_seconds`.

Errors use [the error object](https://public-api.dapi.digital/docs/guides/errors.md#error-object).

**Request**

```bash
curl -X DELETE "https://public-api.dapi.digital/v2/api-keys/key_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu" \
  -H "x-api-key: $DAPI_API_KEY"
```

**Response 200**

```json
{
  "id": "key_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
  "object": "api_key",
  "deleted": true
}
```

---

3DAPI API Docs. This page on the web: https://public-api.dapi.digital/docs/reference/api-keys. Index of every page: https://public-api.dapi.digital/docs/llms.txt.
