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

# RevDesk API Authentication & Scopes

> Authorize RevDesk with organization-scoped OAuth grants or API keys and least-privilege permissions.

## Bearer token

All API requests require a Bearer token in the `Authorization` header. Registered OAuth clients
use short-lived access tokens; other integrations may use organization-scoped RevDesk API keys.

```bash theme={null}
curl https://api.revdesk.com/v1/calls \
  -H "Authorization: Bearer rv_your_api_key_here"
```

## Getting your API key

Create a [RevDesk account](https://www.revdesk.com/signup), then create and manage keys in
**Settings → API Keys**. Key creation is self-serve and does not require a sales conversation. Each
key is prefixed with `rv_` and should be kept secret.

## OAuth authorization code

OAuth-capable clients discover RevDesk's authorization server from the API or MCP protected-resource
metadata. RevDesk supports authorization code with PKCE (`S256`) and refresh tokens. During consent,
a person selects an organization and approves named v1 scopes. Every API request re-checks that the
person is unlocked, the registered client still exists, and the person still belongs to that
organization.

<Tip>
  Start with a free trial and a separate development organization. RevDesk reaches real carrier networks
  rather than a simulated public sandbox, so use read-only scopes first and restrict calling or messaging
  credentials to approved test numbers.
</Tip>

<Note>
  API keys are hashed before storage (SHA-256). The plaintext is shown only once, at creation. If you lose it,
  generate a new one.
</Note>

## Key format

| Component | Example |
| - | - |
| Prefix | `rv_` |
| Token | `a1b2c3d4e5f6...` |
| Full key | `rv_a1b2c3d4e5f6...` |

## Scopes

Every key belongs to one organization and carries an explicit list of **scopes** that gate which
endpoints it can call. Each endpoint declares the scope it requires; a request missing that scope is
rejected with `scope_missing`.

| Scope | Grants |
| - | - |
| `account:read` | Read the account and organization the key belongs to (`GET /v1/account`, `GET /v1/me`). |
| `voice:read` / `voice:write` | Read / manage caller IDs and voice configuration. |
| `voice:webrtc` | Issue browser WebRTC calling tokens (`POST /v1/webrtc-token`). Narrow by design: a key with only this scope can do nothing else. |
| `calls:read` / `calls:write` | Read call metadata / place and control calls. `calls:read` covers metadata only. |
| `recordings:read` | Access call **recording audio** (`recording_url`). Sensitive, and separate from `calls:read`. |
| `transcripts:read` | Access call **transcripts** and analysis (`GET /v1/calls/{id}/transcript`). Sensitive, and separate from `calls:read`. |
| `agents:read` / `agents:write` | List and inspect / configure assistants (`/v1/agents`). See the note below on naming. |
| `phone_numbers:read` / `phone_numbers:write` | List / provision and configure phone numbers. |
| `sms:read` / `sms:write` | Read / send SMS. |
| `webhooks:read` / `webhooks:write` | List / create and delete webhook subscriptions (`/v1/webhook_subscriptions`). |
| `caller_trust:read` / `caller_trust:write` | Read / manage caller-ID trust, enterprise registration, and number reputation. |
| `brand:read` / `brand:write` | Read / submit brand registration for branded calling. |
| `sub_entities:read` / `sub_entities:write` | List / create and update managed sub-entities. |
| `compliance:write` | Change HIPAA mode on a sub-entity. Sensitive, and **never granted by default**. Request it explicitly. |
| `usage:read` | Read usage metrics. |
| `tokens:mint` | Mint short-lived client tokens (`POST /v1/client-tokens`) for browser and mobile callers. |
| `jobs:read` / `jobs:write` | Read / create and manage [Tasks](/concepts/tasks). The scope names are retained for credential compatibility. |

A key created without narrowing gets every scope **except** `compliance:write`, which is opt-in only.

<Note>
  `agents:read` and `agents:write` govern `/v1/agents`, which returns **assistants**: the runtime voices
  attached to your numbers and tasks. These are not the same objects as the [agents](/concepts/agents)
  you hire in the product, and the counts will not match. There is no `agents` scope.
</Note>

Keys are **organization-scoped**: every key reads and writes within a single organization, and tenant
isolation is enforced server-side on every endpoint. Grant the **smallest set of scopes** that the
integration needs (e.g. a browser-calling integration only needs `voice:webrtc`).

<Note>
  Lead intake endpoints do not use API keys. Each lead source has a rotatable URL token and source secret so a
  CRM or form provider can deliver leads without receiving access to the rest of your workspace. See [Tasks
  and lead sources](/getting-started/features/tasks-and-lead-sources#generic-webhook). The retired
  `/v1/workflows`, `/v1/workflows/{id}/enroll`, and `/v1/workflow_contacts` endpoints and their workflow-only
  scope are no longer available; use `/v1/tasks` for programmatic work. `/v1/jobs` remains a deprecated
  compatibility alias.
</Note>

## Security best practices

* Store API keys in environment variables, never in source code
* Grant the smallest scope set that works (e.g. `voice:webrtc` only for browser calling)
* Rotate keys periodically: revoke the old key in Settings → API Keys, then issue a new one (plaintext is shown once at creation; we only store the SHA-256 hash)
* Use separate keys for development and production
* Monitor key usage via the account endpoint


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.