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

# Authentication

> Distribution API keys: who issues them, how to send them, the scopes they carry and how to rotate them.

<Warning>
  **Preview: nothing is served yet.** This describes the Distribution API contract (version `1.0.0`). No key is issued yet; the first test key opens the sandbox.
</Warning>

## Keys

A key belongs to your channel and to one environment. It is issued to you by the Gridbeds team, not by each property: hosts choose which of their properties to publish to your channel, and your key reads what they published.

* A production key starts with `gbd_live_`, a sandbox key with `gbd_test_`. A key is 63 characters long.
* A key ends in a CRC32 checksum of its secret part, so a mistyped or truncated key is refused before any lookup, and so is a key used in the other environment.
* Gridbeds stores only a hash of each key. Keep yours in a secret store, never in code.
* The prefixes are registered with public secret scanners (GitHub secret scanning, TruffleHog, GitGuardian). A key found in a public repository is revoked at once, and your technical contact is told.

Send the key as a bearer token on every request:

```http theme={null}
GET /api/v1/distribution/channel HTTP/1.1
Host: api.gridbeds.com
Authorization: Bearer gbd_live_…
```

## Rotation

Your channel may hold two keys per environment while it rotates: put the new key into service, check that requests with it succeed, then the old one can be revoked. `GET /channel` shows which key a request used (`key.last4`), when it was created and when it expires (`key.expires_at`, `null` for a key issued without an expiry).

## Scopes

Each operation names the scopes it needs. A key holds one or more of them:

| Scope | Gives |
| - | - |
| `read:catalog` | Locations, owners, properties, the amenity catalogue, and the events about them. |
| `read:ari` | Availability, prices and restrictions, and `availability.updated` events. |
| `manage:webhooks` | Your webhook endpoints, their secrets and their deliveries. |

`GET /channel` needs no scope. `write:bookings` is reserved for a later stage and is not granted. The scopes are OAuth 2.0 scope tokens, so short-lived access tokens from a client-credentials grant can be offered later beside keys, with the same scopes and no change to any operation.

## When a key is refused

A refused key answers `401` with `WWW-Authenticate` (RFC 6750) and a problem whose `code` says why:

| `code` | Meaning |
| - | - |
| `missing_api_key` | No `Authorization: Bearer` header. |
| `invalid_api_key` | The key is malformed or unknown: the two are answered identically. |
| `api_key_wrong_environment` | A `gbd_test_` key in production, or a `gbd_live_` key on the sandbox. |
| `api_key_expired` | The key has expired. |
| `api_key_revoked` | The key was revoked. |

`api_key_expired` and `api_key_revoked` are told apart only for a key whose secret matched. A key without the scope an operation needs answers `403` with `insufficient_scope` and the scopes it lacks in `required_scopes`; a suspended channel answers `403` with `partner_suspended`. Repeated failed authentication from one address is answered `429` (`too_many_failed_authentications`). See [Errors and rate limits](/en/distribution-api/errors-and-limits).


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