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

# Authentication

> API keys, permission scopes, and how to keep them safe.

Requests authenticate with an API key sent in the `x-api-key` header.

```bash theme={null}
curl https://api.recepta.ai/api/v1/api/calls \
  -H "x-api-key: rcp_your_key_here"
```

Keys are prefixed `rcp_`. Each key belongs to one workspace, and every request it makes is scoped to that workspace.

<Note>
  Dashboard sessions authenticate with a bearer token instead. Endpoints in this reference accept either, but use an API key for anything server-to-server — it's scoped, revocable, and doesn't expire with a login session.
</Note>

## Creating a key

<Steps>
  <Step title="Open API keys">
    In the dashboard, go to **API keys**.
  </Step>

  <Step title="Name it for its use">
    "Zapier booking sync", not "key 2". You'll thank yourself when deciding what's safe to revoke.
  </Step>

  <Step title="Grant only what it needs">
    Pick the narrowest set of permissions that does the job. See the table below.
  </Step>

  <Step title="Copy it now">
    The full key is shown once. Afterwards only a preview — first characters and last four — is visible.
  </Step>
</Steps>

<Warning>
  Keys are stored hashed. If you lose one, it can't be recovered — revoke it and create a new one.
</Warning>

## Permissions

| Permission         | Grants                                          |
| ------------------ | ----------------------------------------------- |
| `calls:read`       | List, search, and retrieve calls                |
| `calls:create`     | Create web, phone, and outbound calls           |
| `calls:trigger`    | Trigger calls                                   |
| `calls:transcript` | Retrieve call transcripts                       |
| `calls:recording`  | Retrieve call recordings                        |
| `calls:delete`     | Delete calls                                    |
| `analytics:read`   | Read call analytics                             |
| `contacts:read`    | List and retrieve contacts                      |
| `contacts:create`  | Create contacts                                 |
| `contacts:update`  | Update contacts                                 |
| `contacts:delete`  | Delete contacts                                 |
| `sms:read`         | Read SMS conversations and messages             |
| `sms:send`         | Send SMS                                        |
| `*`                | Everything — avoid outside trusted internal use |

<Tip>
  Transcript and recording access are separate from `calls:read` on purpose. An analytics integration can read call metadata without ever touching what your customers actually said.
</Tip>

A request with a valid key but insufficient permission returns `403`.

## Expiry

Keys can be given an expiry date. Worth using for anything temporary — a contractor's integration, a one-off migration — so access ends on its own rather than relying on someone remembering.

## Keeping keys safe

<Columns cols={2}>
  <Card title="Do" icon="circle-check">
    Store in environment variables or a secret manager. One key per integration. Rotate on any suspicion, and when someone with access leaves.
  </Card>

  <Card title="Don't" icon="circle-xmark">
    Commit keys to source control. Put them in frontend JavaScript or a mobile app. Share one key across several systems — you then can't revoke one without breaking the rest.
  </Card>
</Columns>

<Warning>
  Never call this API directly from a browser or mobile app. Anything shipped to a user's device is readable by that user. Proxy through your own backend.
</Warning>

## Revoking

Deactivate a key from **API keys**; it stops working immediately. Keys are independent of the user who created them, so removing a team member does **not** revoke keys they made — rotate those separately. See [Team & roles](/account/team-and-roles).

## Scoping to a location

Add `x-location-id` to restrict a request to one [location](/account/locations):

```bash theme={null}
curl https://api.recepta.ai/api/v1/api/calls \
  -H "x-api-key: $RECEPTA_API_KEY" \
  -H "x-location-id: LOCATION_ID"
```
