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

# Authentication

> Get an API key from the console and send it with each request.

Every request carries your API key. Keys are issued on the console's account page and belong to your account: they inherit its plan.

## Get a key

**1. Open your account page**

Sign in to the console and click the account icon at the right of the top bar to reach [console.periphery.exposed/account](https://console.periphery.exposed/account). API access needs the Plus plan; on Free the API section is locked and links to the pricing page. The page also shows when the key was last used; that date is updated at most once an hour.

**2. Generate the key**

Click **Generate API key**. The key is shown once, on that page only. Copy it into your secret store now; Periphery keeps only a hash and cannot show it again.

## Send the key

Either header works. When both are present, `Authorization` is used. Send it over HTTPS only.

```bash Authorization header theme={null}
curl "https://api.periphery.exposed/v1/apps?q=acme.com" \
  -H "Authorization: Bearer $PERIPHERY_API_KEY"
```

```bash X-API-Key header theme={null}
curl "https://api.periphery.exposed/v1/apps?q=acme.com" \
  -H "X-API-Key: $PERIPHERY_API_KEY"
```

## Plain HTTP is refused

`http://api.periphery.exposed` is not redirected to HTTPS: it answers `403 https_required`, so a client sending its key in clear text finds out. If a key was ever sent over plain HTTP, [rotate it](#rotate-a-key).

## Rotate a key

Click **Rotate key** on the account page, then **Rotate now** to confirm. A new key is issued and shown once, and the previous one stops working at once: there is no overlap period. Update every client right after rotating; until you do, they get `401 api_key_invalid`.

## Errors

| Status | Body | Cause |
| - | - | - |
| `401` | `{"error": "missing API key", "code": "api_key_missing"}` | No `Authorization: Bearer` or `X-API-Key` header. |
| `401` | `{"error": "invalid API key", "code": "api_key_invalid"}` | The key is unknown, or was rotated. |
| `403` | `{"error": "API access requires the Plus plan", "code": "plan_required"}` | The account is on the Free plan. |
| `403` | `{"error": "HTTPS required: use https://api.periphery.exposed. A key sent over plain HTTP travelled in clear text: rotate it.", "code": "https_required"}` | The request used plain `http://`. |

A `401` carries a `WWW-Authenticate` header: `Bearer realm="api.periphery.exposed"` when the key is missing, with `error="invalid_token"` added when it is unknown. See [Limits and errors](https://docs.periphery.exposed/api/limits-and-errors.md#error-codes) for every code.

## Keep it secret

A key gives whoever holds it your plan's access, including email addresses and masked credential values. Do not commit it, put it in a URL, or share it between people; the terms forbid sharing keys. If a key leaks, rotate it.


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