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

# Authentication

> OAuth 2.0 client_credentials, opaque Bearer tokens, and scopes.

## OAuth 2.0 — client\_credentials

The API uses OAuth 2.0 with the **`client_credentials`** grant: your backend consumes your own
workspace. There's no user flow (authorization\_code) for now.

```bash theme={null}
curl -X POST https://api.apyconnect.io/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=client_credentials
```

Credentials can go in **Basic auth** (recommended) or in the body (`client_id`/`client_secret`).

## Opaque tokens

The `access_token` (`at_live_…` / `at_test_…`) is **opaque**: it's not a JWT and carries no data.
Verification is O(1) in the common case (cache) with **immediate revocation**. It lives \~1 h — when
it expires, request another. Send it on every request:

```
Authorization: Bearer at_live_…
```

## Test vs live mode

Each Application is `test` or `live`. Identifiers reflect it (`ec_test_` / `ec_live_`,
`at_test_` / `at_live_`). Use it to separate integration from production.

## Scopes

Permissions live **on the Application**, not on the token (the token inherits them as a snapshot).
Check yours with `GET /v1/me`:

```json theme={null}
{ "object": "api_client_context", "workspace_id": "ws_…", "mode": "live",
  "scopes": ["contacts:read", "contacts:write", "messages:write"] }
```

| Scope                                        | Allows                                                     |
| -------------------------------------------- | ---------------------------------------------------------- |
| `contacts:read` / `contacts:write`           | Read / write contacts, tags, identifiers, custom fields    |
| `conversations:read` / `conversations:write` | Read / manage conversations (status, assignment, priority) |
| `messages:read` / `messages:write`           | Read / send messages                                       |
| `channels:read` · `inboxes:read`             | Read channels (with capabilities) and inboxes              |
| `campaigns:read` / `campaigns:write`         | Read / manage campaigns and their runs                     |
| `analytics:read`                             | Read the `/v1/analytics/*` reports                         |
| `webhooks:manage`                            | Manage webhook endpoints                                   |

If a token lacks the scope for an operation, the API responds **403** `permission_error`
(`insufficient_scope`).

## Rotation and revocation

Rotate the `client_secret` from the Application (the previous one stays valid for a grace period).
Revoking the Application **immediately** invalidates all its live tokens.
