# Authentication

Bob Go authenticates API traffic with a **long-lived API key** presented as a
bearer token. There is no login call and no token to refresh: the key you
create in the dashboard is the credential you send on every request.

## Getting a key

Create an API key from the Bob Go dashboard under **Settings → API keys**
([Sandbox](https://sandbox.bobgo.co.za/settings?tab=api-keys)). The key is
issued against a dedicated API user on your account, so:

- it is scoped to that one account, so it cannot read or write another account's
  data;
- it inherits that user's role and permissions;
- revoking it in the dashboard takes effect immediately.

Sandbox and Production are separate platforms with separate keys. A Sandbox key
will not authenticate against Production.

## Sending the key

Send it in the `Authorization` header on every request:

```http
POST /v2/shipments HTTP/1.1
Host: api.bobgo.co.za
Authorization: Bearer <your-api-key>
content-type: application/json
```

In this collection that is already wired up: the collection root sets bearer
auth to `{{api_key}}` and every request uses `auth: inherit`. Set `api_key`, on
the collection or on the environment you selected, and all requests are
authenticated.

> Keep keys out of version control. The committed collection ships an empty
> `api_key` on purpose, so fill it in locally.

The key also tells Bob Go which account you are acting on, so no request needs
an `account_id`. If you send one anyway it is replaced with the key's account,
not checked against it.

## Keeping the key safe

The key is equivalent to a password on your account, and it does not expire on
its own:

- Never ship it in client-side code, a mobile app bundle or a public
  repository. Calls to Bob Go belong on your server.
- Always call over HTTPS, so the key is not readable in transit.
- Rotate it if it may have leaked: create the new key, deploy it, then revoke
  the old one. Revocation is immediate, so revoking first causes an outage.

## Channel-scoped keys

Keys created for a **channel** integration (a marketplace or cart connected to
Bob Go) are additionally bound to that channel's identifier. Those requests must
also send:

```http
bobgo-channel-identifier: your-store.example.com
```

Send the identifier exactly as the channel has it. Bob Go ignores a leading
`https://` and a trailing slash, but otherwise the comparison is exact,
including case. Keys not tied to a channel do not need this header.

A channel key fixes `channel_id` the way any key fixes `account_id`: whatever
you send is replaced with the key's channel, and `GET /v2/orders` only lists
that channel's orders.

## Failures

| Status | Message | Cause |
| --- | --- | --- |
| `401` | `Authentication failed, please check your API key.` | The key is not recognised, or has been revoked. |
| `401` | `Authentication failed, please check your API key and headers.` | A channel key without a matching `bobgo-channel-identifier` header. |
| `403` | `You're not logged in. Please log in and try again.` | No `Authorization` header, or one without the `Bearer ` prefix. |
| `403` | `Upgrade to a higher plan to unlock this feature.` | The account's plan does not include API access. |
| `403` | `You do not have access to the requested resource.` | The key's role may not call this endpoint. |
