---
title: "Authentication"
description: "How API keys are issued, scoped, bound to an organization and revoked, and what each 401 and 403 means."
publishedAt: 2026-09-14
---
The API accepts one credential today: an API key sent as a bearer token. A key
is created by a signed-in person in the dashboard, inherits that person's role,
and can be narrowed with a scope. The key follows its creator: it acts with
that person's current role on every request, so if they change role or leave
the organization, the key changes or stops with them.

## Sending a key

```http
Authorization: Bearer dg_...
```

Keys begin with `dg_`. Requests that carry a key
need no CSRF token.

## Where a key can reach

A key is **bound to exactly one organization** at creation and every request
is evaluated against it. A path that names a different organization is
refused, and an `X-Org-Id` header is ignored: the key's own organization
always applies.

Within the organization, a request must pass two checks that each endpoint in
the reference lists:

1. **Permission.** The key owner's role must hold the endpoint's permission,
   exactly as if that person clicked the equivalent screen.
2. **Scope.** The key's scope must allow the permission's verb.

| Scope                                        | Allows                              | Use it for                                                             |
| -------------------------------------------- | ----------------------------------- | ---------------------------------------------------------------------- |
| `read` (default) | read, export and preview operations | Dashboards, reporting, sync jobs. Everything in the current reference. |
| `full`           | whatever the owner's role allows    | Automation that also writes, such as domain onboarding.                |

A scope only narrows. A `full` key held by a viewer can still only read.

## Lifetime

- **Expiry** is chosen at creation: 1, 7, 30 or 90 days, one year, or never.
  The default is one year.
- **Revocation** is immediate. A revoked key fails with `401` on its next
  request and leaves the key list; the usage endpoint keeps it for the
  history window, flagged revoked, so an audit can still see what it sent.
- **Active keys.** An organization can hold at most 50 active keys; creating
  another returns `409`.
- **Plan** is checked on every request, and a plan change takes effect within
  a minute. API access is a Pro and Enterprise
  capability; if the organization lapses to Hobbyist, every key
  stops working until the plan is restored.
- **Management** is for signed-in people. A request that authenticates with a
  key is refused with `403` on both the create and the revoke endpoint,
  whatever its scope. Listing keys is allowed.

## Reading a rejection

| Status | Meaning                                                                                                                                                                                                                                                                       | What to do                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `401`  | No `Authorization` header, not a bearer token, or the key is unknown, revoked, expired or on an organization without API access.                                                                                                                                              | Check the header, then the key's status in [Settings, Security, API Keys](https://app.dmarcguard.io/settings?tab=security&section=api-keys). |
| `403`  | The key authenticated but its scope or its owner's role does not allow this operation; the body's `required` field names the permission it lacked and `code` is `permission_denied`. A path that names another organization is also refused with `403`, without those fields. | Compare the endpoint's permission and scopes in the reference with the key's.                          |

A `401` never distinguishes an unknown key from a revoked, expired or
unentitled one; the body says only that the token is invalid or expired. A
missing or non-bearer `Authorization` header is named, since that is your own
mistake to fix.

> **Keep keys out of URLs and logs**
>
> Send the key only in the `Authorization` header. Query strings end up in proxy
> and access logs; a header does not.

## Rotating a key

Create the replacement first, deploy it, then revoke the old key. Both work
during the overlap, and the [usage endpoint](/docs/api/v1/api-keys/#getAPIKeyUsage)
shows which key is still sending traffic before you revoke. The key list's
last-used time lags real traffic by about half a minute.