# Authentication

Source: https://parasend.com/docs/authentication

Every request carries an API key as a Bearer token:

```bash
curl "https://api.parasend.com/v1/deliveries" \
  -H "Authorization: Bearer $PARASEND_KEY"
```

## Test keys and live keys

| Key | Starts with | What it does |
|---|---|---|
| Test | `ps_test_` | Works in test mode: sends nothing, bills nothing. See [test and live mode](/docs/test-mode). |
| Live | `ps_live_` | Sends real notices to real people, and is billed. |

The key decides the mode. The two modes never see each other's data: a test key asking for a live delivery gets `404`, the same as for one that does not exist.

## Making a key

Keys are made, rolled and deleted only in the portal, by a person signed in with eID: open **API keys**. An API key cannot make or change keys. A live key's secret is shown once, when the key is made or rolled; a test key's can be shown again in the portal. Keep keys in your secret store, never in code or in a URL.

Each key has:

- **Permissions**, per resource: for example `deliveries.create` and `deliveries.read`, `files.create`, `evidence.read`, `webhooks.create`. A request outside them answers `403 permission_denied`, naming the permission it needs in `param`.
- **Who sees what**: a key sees all of the organisation's deliveries, or only its own holder's.
- Optionally an **expiry date**, a **monthly cap** on deliveries, and an **IP allowlist**.

## Rolling a key

Roll a key in the portal when it may have leaked, or on a schedule. The new secret works at once; the old one keeps working for 24 hours, so you can switch without downtime.

## When it fails

| Status | Code | Why |
|---|---|---|
| 401 | `api_key_missing` | No `Authorization: Bearer` header. |
| 401 | `api_key_invalid` | Not a key Parasend issued, or a rolled key's old secret after its 24 hours. |
| 401 | `api_key_expired` | The key has passed its expiry date. |
| 401 | `api_key_revoked` | The key was deleted, or the account is closed. |
| 403 | `api_key_ip_not_allowed` | The request came from an address outside the key's IP allowlist. |
| 403 | `permission_denied` | The key lacks the permission named in `param`. |

Every code is listed at [error codes](/docs/errors).
