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

# Agency authentication

> Authenticate the reseller API with an agency key (dmly_ag_…), sent as the x-api-key header.

Every request carries an **agency API key**. It authenticates the acting agency and scopes every
request to that agency's own sub-accounts; an agency can only ever see and act on its own
workspaces.

An agency key starts `dmly_ag_`, which is what distinguishes it from a workspace key (`dmly_…`). The
two are **not interchangeable**: an agency key is rejected by the workspace API, and a workspace key
is rejected here.

## Sending the key

Send it as the `x-api-key` header:

```bash theme={"dark"}
curl https://dash.dmly.io/api/agency/v1/workspaces \
  -H "x-api-key: dmly_ag_xxxxxxxxxxxx"
```

A bearer token is also accepted:

```bash theme={"dark"}
curl https://dash.dmly.io/api/agency/v1/workspaces \
  -H "Authorization: Bearer dmly_ag_xxxxxxxxxxxx"
```

Both are equivalent. If both are present, `x-api-key` wins.

## Creating a key

<Steps>
  <Step title="Open the agency console">
    In the agency console, go to **Configuration → API**.
  </Step>

  <Step title="Generate a key">
    Select **+ Generate key**. Give it a name describing what will use it, so you can recognise it
    later when rotating or revoking, then select **Generate**.
  </Step>

  <Step title="Copy it now">
    The key is shown **once**, under **Copy your API key now**. DMLY stores only a hash of it, so it
    cannot be retrieved or emailed to you afterwards.
  </Step>
</Steps>

<Warning>
  An agency key can provision workspaces and change subscriptions across every one of your
  sub-accounts. Treat it like a password: keep it server-side, never commit it, and never ship it in
  client-side code.
</Warning>

## Rotating and revoking

Create the replacement key first, deploy it, then revoke the old one. Revocation takes effect
immediately, and any caller still using the old key starts getting `401`. DMLY stamps a last-used
time on every authenticated request, so you can tell whether a key is still in use before retiring
it.

## When authentication fails

| Status | Body                                                                    | Meaning                                                   |
| ------ | ----------------------------------------------------------------------- | --------------------------------------------------------- |
| `401`  | `API key missing. Send it as the "x-api-key" header or a Bearer token.` | No key on the request                                     |
| `401`  | `Invalid API key.`                                                      | Unknown or revoked key                                    |
| `403`  | `This agency is not active.`                                            | Your agency has been suspended; all its keys stop working |
| `429`  | `Too many requests. Retry after N seconds.`                             | You exceeded 120 requests per minute on this key          |
| `503`  | `The reseller API is currently disabled.`                               | The whole surface is switched off fleet-wide              |

<Note>
  A `503` is not about your key; it means DMLY has temporarily disabled the reseller API for
  everyone, typically during an incident. Retry later; your key still works once it is back on.
</Note>

## Rate limit

The reseller API allows **120 requests per minute per agency key**. That is a separate, larger
budget than the workspace REST API's 60 per minute, because one agency key manages many
sub-accounts.

Requests whose key doesn't resolve (missing, mistyped or revoked) fall back to a shared **60
requests per minute per IP address** instead. They still fail with `401`; the shared bucket only
caps how fast you can retry.

On a `429`, wait the number of seconds in `Retry-After` (the message states the same figure) and
retry.
