# Authentication

Bob Box integrations use an API key as a bearer token. Every request carries the same header:

```http
Authorization: Bearer <api_key>
```

| Credential | Who it's for | How you get it | Expires |
| --- | --- | --- | --- |
| **API key** | Server-to-server integrations (courier and delivery platforms) | Created under **Settings → API keys**, or issued with an API user. | No |

API keys resolve to the account and permissions assigned to them.

An unknown or revoked token returns `401`, with the body `Authentication error: authentication failed, please check your API key`.

Sending no `Authorization` header returns `403`, with `You're not logged in. Please log in and try again.` A valid API key whose role lacks the endpoint's permission also returns `403`, with `You do not have access to the requested resource`.

All three are plain text, not the JSON `{ "message": ... }` envelope the rest of the API uses — they are returned before the handler runs.

## API keys

### Getting a key

You can create your own key. Sign in to the dashboard as the Bob Box account owner, open **Settings → API keys**, and create one. The same page deletes keys you no longer want.

Your Bob Box contact can also create an **API user** for you instead.

Either way, the key is shown once, in full, at that moment.

**Copy it then and store it somewhere safe.** Afterwards it is only ever displayed masked, as `abc***xyz`. If it is lost, create a new key and delete the old one.

### Using it

Send it as a bearer token on every request:

```bash
curl -G "https://api.bobbox.co.za/v2/account/locations" \
  -H "Authorization: Bearer 4f3c9b1a72e04d5fa9c8e6b0d1a2f3c4"
```

That is the whole authentication flow.

### What the key can do

The API user carries a role, and that role decides which endpoints the key may call. A key issued for your account reads and writes your own account's locations and reservations.

### Keeping it safe

- **Treat it as a password.** It grants full access to your account's data and never expires.
- **Server-side only.** Never put it in a mobile app, browser JavaScript, or a public repository — there is no way to scope or time-limit it.
- **HTTPS only.** The API is HTTPS-only; do not build anything that would send the key in the clear.
- **Rotating means replacing.** A key cannot be rotated in place. Create a second key under **Settings → API keys**, cut your integration over to it, then delete the old one from the same page.
