> ## Documentation index
> Fetch the complete documentation index at: https://developer.rhombus.com/llms.txt
> Use it to discover all available pages before exploring further.

# Authentication

> How to authenticate every kind of Rhombus request: which credential to use for REST, media and video, the event WebSocket and cameras on your network, where each one goes, partner credentials, and how to read 401, 403 and 429 responses.

Every request to Rhombus carries a credential. Which credentials a request can use, and where they go, depends on **where the request goes**: the REST API, the media and video hosts, the event WebSocket, or a camera on your local network. This page maps each credential to each destination and explains the authentication errors; the pages after it cover each credential in detail.

## Choose a credential

| You're building                                                                                           | Use                                             | Details                                                                                                  |
| --------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| A backend service, script or scheduled job in one organization                                            | **API key**                                     | [API keys and certificates](https://developer.rhombus.com/authentication/api-keys)                       |
| A backend whose security policy requires mutual TLS                                                       | **Certificate API key** (mTLS)                  | [API keys and certificates](https://developer.rhombus.com/authentication/api-keys#certificate-keys-mtls) |
| An app that other Rhombus customers sign in to and authorize                                              | **OAuth access token** ("Sign in with Rhombus") | [Sign in with Rhombus](https://developer.rhombus.com/oauth-authentication)                               |
| A tool for an MSP or reseller that manages many client organizations                                      | **Partner API key** or partner OAuth token      | [Partner API](https://developer.rhombus.com/partner-api-calls)                                           |
| Video, images, audio or live events in a browser or a mobile app, or anything on a camera's local network | **Federated token**, minted by your backend     | [Federated tokens](https://developer.rhombus.com/authentication/federated-tokens)                        |
| A link anyone can open to watch one camera                                                                | **Shared stream link**                          | [Media and streams](https://developer.rhombus.com/authentication/media#shared-stream-links)              |

> **Warning**: API keys and partner keys are server-side credentials. Never put one in a web page, a mobile app or any code a user can read. Anything that runs on a user's device gets a short-lived [federated token](https://developer.rhombus.com/authentication/federated-tokens) from your backend instead.

## Where each credential works

| Credential                                  | REST API (`api2`)                                      | Media and video                                   | Event WebSocket (`ws`)             | Cameras on your LAN         |
| ------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------- | ---------------------------------- | --------------------------- |
| **API key**                                 | Headers                                                | Headers                                           | Handshake headers                  | Not accepted                |
| **Certificate API key**                     | Client certificate plus headers (`api2` hosts only)    | Not accepted; use an API key or a federated token | Not accepted                       | Not accepted                |
| **OAuth access token**                      | Headers                                                | Headers                                           | Handshake headers                  | Not accepted                |
| **Partner key, certificate or OAuth token** | Same as the organization credential, plus `x-auth-org` | Same, plus `x-auth-org`                           | Same, plus `x-auth-org` (required) | Not accepted                |
| **Federated token**                         | Headers or query parameters                            | Headers or query parameters                       | Headers or query parameters        | Headers or query parameters |

Cameras on your local network accept **federated tokens only**. That's deliberate: on the local network, every request carries a short-lived token that you can limit to the one camera it needs, never a long-lived key. See [Streaming over LAN](https://developer.rhombus.com/implementations/lan-streaming).

Hosts per destination ([US & EU Regions](https://developer.rhombus.com/api-regions) lists the EU variants):

| Destination         | US host                                                                                                                                                                                    |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| REST API            | `https://api2.rhombussystems.com`                                                                                                                                                          |
| Media and video     | `https://media.rhombussystems.com`, plus the per-camera streaming hosts that [`getMediaUris`](https://developer.rhombus.com/api-reference/camera-webservice/get-camera-media-uris) returns |
| Event WebSocket     | `wss://ws.rhombussystems.com:8443/websocket`                                                                                                                                               |
| Cameras on your LAN | `https://<camera>.lan.rhombussystems.com:8000`, returned by `getMediaUris`                                                                                                                 |

## Request headers

A request names its **scheme** in `x-auth-scheme` and carries the credential in the header that scheme reads:

| Credential                              | `x-auth-scheme`                                                                                                  | Credential header                                         | Extra                                                                                                                         |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| API key                                 | `api-token`                                                                                                      | `x-auth-apikey`                                           | —                                                                                                                             |
| Certificate API key                     | `api`                                                                                                            | `x-auth-apikey`                                           | TLS client certificate                                                                                                        |
| OAuth access token                      | `api-oauth-token`, or leave it out                                                                               | `x-auth-access-token`, or `Authorization: Bearer <token>` | —                                                                                                                             |
| Federated token                         | `federated-token`                                                                                                | `x-auth-ft`                                               | Both may be query parameters instead: `?x-auth-scheme=federated-token&x-auth-ft=<token>`                                      |
| Partner key, certificate or OAuth token | The same three schemes; `partner-api-token`, `partner-api` and `partner-api-oauth-token` are accepted as aliases | The same headers                                          | `x-auth-org: <client org UUID>` (see [Partner credentials](https://developer.rhombus.com/authentication#partner-credentials)) |

```bash API key
curl -X POST "https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList" \
  -H "x-auth-scheme: api-token" \
  -H "x-auth-apikey: $RHOMBUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

```bash OAuth access token
curl -X POST "https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

Rules that apply everywhere:

- **Header names and the scheme value are exact.** `x-auth-scheme: api-token` works; `Api-Token` does not.
- **`Authorization: Bearer` carries an OAuth access token only**, on the REST API, the media hosts and the event WebSocket. A Bearer header with no `x-auth-scheme` is read as an OAuth access token. API keys never go in `Authorization`.
- **Only federated tokens go in a URL.** `x-auth-scheme` and `x-auth-ft` may be query parameters; API keys, OAuth access tokens and `x-auth-org` are read from headers only.
- **Credentials are region-bound.** A key or token from a US organization doesn't work on EU hosts, and the reverse. The error doesn't mention the region. See [US & EU Regions](https://developer.rhombus.com/api-regions).
- **Lifetimes:** an API key works until you delete it or until its expiry (`expiresAtMs`), if it has one. OAuth access tokens last one hour. Federated tokens last the `durationSec` you ask for when you mint them: one hour by default, at most 24 hours.
- **Revocation takes effect within 60 seconds on every host.** Deleting a key, changing its role or revoking an OAuth grant ends its access, and open WebSocket connections that used it are closed.
- **Send `Content-Type: application/json`** on every POST to the REST API, even with an empty body (`{}`).

## Partner credentials

Partner keys, partner certificate keys and partner OAuth tokens use the same schemes as the organization credentials. To act in a client organization, send that organization's UUID in `x-auth-org`:

- `x-auth-org` is a **header only**; it's never read from a query parameter. It means the same for partner keys, certificates and OAuth tokens, and an empty value counts as absent.
- Outside the `/api/partner/` endpoints, **always send `x-auth-org`**. A partner request without it still works, but the response carries `Deprecation: true` and `Sunset: Tue, 05 Jan 2027 00:00:00 GMT`, and after that date the request fails. The event WebSocket refuses a partner handshake without `x-auth-org` with 403 `PERMISSION_REQUIRED`.
- A malformed value returns 400 `INVALID_AUTH_ORG`; a client organization your partner account doesn't manage returns 403 `PARTNER_CLIENT_ACCESS_DENIED`.

See [Partner API](https://developer.rhombus.com/partner-api-calls) for listing clients and calling into them.

## Reading authentication errors

Every error response from the REST API, the media hosts and the WebSocket handshakes has the same JSON body, and carries the request ID in the `x-rhombus-txid` header too:

```json
{
  "msg": "Unauthorized",
  "error": true,
  "errorCode": "CREDENTIAL_EXPIRED",
  "errorMsg": "The supplied credential has expired.",
  "status": 401,
  "timestamp": 1792371600000,
  "txid": "yJ2kQw8LTaO1xX4hVd7mPA"
}
```

Branch on the status and `errorCode`, show or log `errorMsg`, and quote `txid` when you contact support. The status says which part of the request to fix:

- **401**: Rhombus couldn't establish who is calling. The credential is missing, malformed, unknown, expired or revoked. Fix or replace the credential.
- **403**: the credential is valid but isn't allowed to do this. Change the role, the OAuth scopes, the organization or the token's limits; a new credential of the same kind won't help.

| Status  | `errorCode`                    | What to check                                                                                                                                                                                                                                                              |
| ------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **401** | `UNAUTHENTICATED`              | No credential was presented: `x-auth-scheme` or the credential header is missing or misspelled, or an API key was sent as a query parameter                                                                                                                                |
| **401** | `INVALID_CREDENTIAL`           | The value is damaged (copy and paste, whitespace), belongs to the other region, or was sent with the wrong scheme; or it no longer exists: a deleted key, a revoked federated token or one whose minting credential is gone, an access token already replaced by a refresh |
| **401** | `CREDENTIAL_EXPIRED`           | Refresh the OAuth access token, mint a new federated token, or [rotate](https://developer.rhombus.com/authentication/permissions#rotate-an-api-key) a key that reached its `expiresAtMs`                                                                                   |
| **401** | `CREDENTIAL_REVOKED`           | The OAuth grant was revoked, by the user, an administrator, or automatically after a replaced refresh token was reused. Sign in again                                                                                                                                      |
| **401** | `CERTIFICATE_MISMATCH`         | `Client certificate does not match the api key`: present the certificate issued for this key, with the scheme `api` (certificate keys work on api2 only)                                                                                                                   |
| **403** | `PERMISSION_REQUIRED`          | The key's role ([Permissions](https://developer.rhombus.com/authentication/permissions)). For an OAuth token, also its scopes: a missing scope adds `WWW-Authenticate: Bearer error="insufficient_scope", scope="<required>"`                                              |
| **403** | `PARTNER_CLIENT_ACCESS_DENIED` | Your partner account doesn't manage the `x-auth-org` organization                                                                                                                                                                                                          |
| **403** | `DOMAIN_NOT_ALLOWED`           | A federated token minted with a `domain` was used from another origin, or from a client that sends no `Origin` or `Referer` ([The domain field](https://developer.rhombus.com/authentication/federated-tokens#the-domain-field))                                           |
| **403** | `DEVICE_SCOPE_MISMATCH`        | A device-scoped federated token was used for a different device                                                                                                                                                                                                            |
| **400** | `INVALID_AUTH_ORG`             | `x-auth-org` isn't a valid organization UUID                                                                                                                                                                                                                               |
| **404** | `NOT_FOUND`                    | The `/api` path doesn't exist. Paths are case-sensitive, so a wrong capital letter gets 404 too                                                                                                                                                                            |
| **429** | `RATE_LIMITED`                 | Your organization's rate limit, or a per-camera limit on clips and frames. Wait `Retry-After` seconds ([Rate Limits](https://developer.rhombus.com/rate-limits))                                                                                                           |
| **503** | `SERVICE_UNAVAILABLE`          | Authentication couldn't be checked. Retry with backoff                                                                                                                                                                                                                     |

Some operations report a refused action with HTTP `200` and `"error": true` in the body, so check the body as well as the status. The [Errors](https://developer.rhombus.com/errors) page has the full catalog of codes and the retry rules.

Media hosts and the event WebSocket have their own failure cases; see [Media and streams](https://developer.rhombus.com/authentication/media#troubleshooting) and [WebSocket authentication](https://developer.rhombus.com/websocket/authentication#troubleshooting).

## Next steps

- **[API keys and certificates](https://developer.rhombus.com/authentication/api-keys)**: Create a key, choose its role, use mTLS, rotate, renew and revoke
- **[Federated tokens](https://developer.rhombus.com/authentication/federated-tokens)**: Short-lived tokens for browsers, mobile apps and cameras on your LAN
- **[Media and streams](https://developer.rhombus.com/authentication/media)**: Snapshots, live and recorded video, clips, audio and shared links
- **[Permissions and key rotation](https://developer.rhombus.com/authentication/permissions)**: Roles, OAuth scopes, rotation without downtime, and the audit trail
