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

# Authentication

> Bearer tokens, organization API keys, personal access tokens, and the scopes that gate each endpoint

Every endpoint in this reference (except the [PAT exchange endpoint](#how-the-exchange-works) itself) requires an `Authorization: Bearer <token>` header. Two kinds of token are accepted, and the backend tells them apart by prefix:

| Prefix | Token type                     | Minted via                | Scope                                                                |
| ------ | ------------------------------ | ------------------------- | -------------------------------------------------------------------- |
| `ak_`  | **Organization API key**       | `POST /organization-pats` | Fixed to the organization active when the key was created            |
| `pat_` | **User personal access token** | `POST /user-pats`         | Any organization the creating user belongs to — selected per-request |

If you're building an integration or automation, use an **organization API key** — it's the simplest to reason about, since it's bound to one org for its lifetime. Use a **user PAT** if the same credential needs to act across several of your organizations.

## Organization API keys (`ak_`)

Minting the first key requires an already-authenticated session (obtained by signing in through your organization's identity provider) — from there, call this endpoint directly to get a long-lived key you can use for every subsequent request:

```bash theme={null}
curl -X POST https://crm-api.anyreach.ai/organization-pats \
  -H "Authorization: Bearer <your authenticated session token>" \
  -H "Content-Type: application/json" \
  -d '{"name": "zapier-integration"}'
```

The response's `pat_key` (`ak_<key_id>.<secret>`) is shown **exactly once** — the backend stores only an Argon2id hash of the secret, so if you lose it you have to delete the key and mint a new one. See the full request/response shape on the [Create an Organization API Key reference page](/api-reference/pats/create-org-key).

Use it directly as the bearer token on any request:

```bash theme={null}
curl https://crm-api.anyreach.ai/deals \
  -H "Authorization: Bearer ak_xxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

No `X-Anyreach-Org` header is needed or accepted — the key already resolved to one organization the moment it was created, and every request it authenticates runs against that org.

## User personal access tokens (`pat_`)

Personal access tokens are scoped to the *user*, not one org, and are created the same way (`POST /user-pats`). Because the same token can act for any organization you belong to, you must tell the API which one on every request with an `X-Anyreach-Org` header carrying that org's Logto organization ID:

```bash theme={null}
curl https://crm-api.anyreach.ai/deals \
  -H "Authorization: Bearer pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "X-Anyreach-Org: <logto-organization-id>"
```

Omit the header and the request runs with no organization context — endpoints that require one (nearly all of them) reject it with `400 Active organization required`.

## How the exchange works

`ak_…` and `pat_…` aren't JWTs themselves — the backend recognizes the prefix on `Authorization: Bearer <token>` and internally exchanges it for a short-lived Logto access token via `POST /pat/exchange` (the only unauthenticated endpoint on the core CRM surface — it's the bootstrap that mints the token, so it authenticates *with* the PAT/key instead of a prior bearer token) before running the request. You never need to call `/pat/exchange` yourself; passing the raw key or PAT as your bearer token on every request is the intended usage, and the exchange happens transparently on each call.

## Scopes

Every endpoint checks the caller's token for at least one scope from the sets below. A `viewer`-role credential that only carries read scopes gets a `403 Insufficient permissions` on any write — there's no silent downgrade.

<Note>**Manage implies read.** A token with a `*:manage` scope automatically passes a `*:read` check — the reverse is not true. Some Logto roles carry only the `manage` scope for a resource without the paired `read` scope, so read endpoints accept either.</Note>

| Scope group        | Scopes                                                                                                                                                               | Grants                                                                                                                                                                                    |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CRM read           | `api:read`, `data:access`, `contacts:read`, `deals:read`, `companies:read`, `activities:read`, `leads:read`, `users:read`, `organizations:read`, `workflows:read`    | Read contacts, deals, accounts, activities, tags, files, folders, reports                                                                                                                 |
| CRM manage         | `api:manage`, `deals:manage`, `contacts:manage`, `companies:manage`, `activities:manage`, `leads:manage`, `users:manage`, `organizations:manage`, `workflows:manage` | Create/update/delete on the same resources, plus anything gated as a "management action" (e.g. emitting a notification event, emailing a report)                                          |
| Org admin          | `organizations:manage`                                                                                                                                               | Org-level settings specifically — members, pipeline-stage configuration, org-wide sales targets. Narrower than CRM manage: a manager role can carry `deals:manage` without carrying this. |
| Data access        | `data:access`                                                                                                                                                        | Ad-hoc read-only SQL across business tables (the AI analytics assistant)                                                                                                                  |
| Outreach read      | `outreach:read` (or any outreach manage/provision scope)                                                                                                             | View outreach campaigns, domains, mailboxes, enrollments                                                                                                                                  |
| Outreach manage    | `outreach:manage` (or `outreach:provision`)                                                                                                                          | Create/edit campaigns and enrollments                                                                                                                                                     |
| Outreach provision | `outreach:provision`                                                                                                                                                 | Cost-bearing actions — buying domains, provisioning mailboxes                                                                                                                             |

Each endpoint in this reference names the specific check it runs (e.g. "Requires a CRM read scope") — cross-reference this table to know which role/token can call it.

## Error responses

| Status             | Meaning                                                                                                                                            |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401 Unauthorized` | Missing, malformed, or expired bearer token; invalid/revoked PAT                                                                                   |
| `403 Forbidden`    | Token is valid but lacks the required scope, or (for `pat_` tokens) the `X-Anyreach-Org` organization doesn't match a claim on the exchanged token |
| `400 Bad Request`  | No active organization on the token/request (see above)                                                                                            |

See [Errors & Pagination](/errors-and-pagination) for the general error body shape.
