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

# Authentication

> Authenticate API requests with a bearer token

The Replyful API uses bearer-token authentication. Every request (except `/health`) must include an `Authorization` header carrying a valid API key.

```http theme={null}
Authorization: Bearer rfl_live_8c1a9f3e6b2d4a7c9e0f1a2b
```

## Create an API key

1. Open the [Replyful dashboard](https://app.replyful.com).
2. Navigate to **Settings → Developers → API keys**.
3. Click **Create key**, give it a descriptive name (e.g. *"Production webhook handler"*), and pick a mode.
4. Copy the token immediately and store it in your secret manager.

<Warning>
  The plaintext token is shown **once** at creation. Replyful only stores a SHA-256 hash, so we cannot recover or display the token after the modal closes. If you lose it, archive the key and create a new one.
</Warning>

## Key modes

Each key is created in one of two modes, identifiable from the prefix:

| Prefix      | Mode | When to use                                                       |
| ----------- | ---- | ----------------------------------------------------------------- |
| `rfl_live_` | Live | Production servers acting on real data.                           |
| `rfl_test_` | Test | Development and CI. Reserved for sandbox isolation in the future. |

Every key belongs to exactly one organization. Cross-organization access is impossible by construction — a key only ever sees data from the org it was created in.

## Use the key

Send the token in the `Authorization` header on every request, prefixed with `Bearer `:

<CodeGroup>
  ```bash curl theme={null}
  curl https://api.replyful.com/v1/tickets \
    -H "Authorization: Bearer rfl_live_..."
  ```

  ```ts Node.js theme={null}
  const res = await fetch("https://api.replyful.com/v1/tickets", {
    headers: {
      Authorization: `Bearer ${process.env.REPLYFUL_API_KEY}`,
    },
  });
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.get(
      "https://api.replyful.com/v1/tickets",
      headers={"Authorization": f"Bearer {os.environ['REPLYFUL_API_KEY']}"},
  )
  ```
</CodeGroup>

## Security best practices

<Warning>
  Never embed an API key in browser code, mobile apps, public repositories, or URL query strings. A leaked key gives full read access to your organization's data until it is archived.
</Warning>

1. **Server-side only.** Call the API from your backend. Never ship a key to a browser or mobile bundle.
2. **Use environment variables.** Read the key from `process.env` (or your secret manager). Never hardcode it.
3. **Header, not URL.** Bearer tokens belong in the `Authorization` header — never in a query string, where they end up in access logs and referrer headers.
4. **Rotate on suspicion.** Keys can be archived from the dashboard. Create a new one, deploy it, then archive the old one.
5. **One key per integration.** Use separate keys for separate consumers so you can rotate or revoke them independently.

## Authentication errors

Authentication failures return HTTP `401` with a consistent envelope:

```json theme={null}
{
  "error": {
    "type": "authentication_error",
    "code": "missing_api_key",
    "message": "Missing Authorization header. Provide `Authorization: Bearer rfl_…`.",
    "docUrl": "https://docs.replyful.com/errors/missing_api_key",
    "requestId": "req_..."
  }
}
```

| Code              | When it fires                                                                                  |
| ----------------- | ---------------------------------------------------------------------------------------------- |
| `missing_api_key` | The `Authorization` header is absent or does not start with `Bearer `.                         |
| `invalid_api_key` | The token is malformed (does not match `rfl_(live\|test)_...`), unknown, or has been archived. |

See [Errors](/api-reference/errors) for the full error envelope reference.
