Authentication
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.
On this page
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 |
| A backend whose security policy requires mutual TLS | Certificate API key (mTLS) | API keys and certificates |
| An app that other Rhombus customers sign in to and authorize | OAuth access token ("Sign in with Rhombus") | Sign in with Rhombus |
| A tool for an MSP or reseller that manages many client organizations | Partner API key or partner OAuth token | Partner API |
| 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 |
| A link anyone can open to watch one camera | Shared stream link | Media and streams |
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 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.
Hosts per destination (US & EU 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 returns |
| Event WebSocket | wss://ws.rhombussystems.com:8443/ |
| 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: | — |
| Federated token | federated-token | x-auth-ft | Both may be query parameters instead: ?x-auth-scheme=federated-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: (see Partner credentials) |
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 '{}'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-tokenworks;Api-Tokendoes not. Authorization: Bearercarries an OAuth access token only, on the REST API, the media hosts and the event WebSocket. A Bearer header with nox-auth-schemeis read as an OAuth access token. API keys never go inAuthorization.- Only federated tokens go in a URL.
x-auth-schemeandx-auth-ftmay be query parameters; API keys, OAuth access tokens andx-auth-orgare 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.
- 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 thedurationSecyou 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/jsonon 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-orgis 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 sendx-auth-org. A partner request without it still works, but the response carriesDeprecation: trueandSunset: Tue, 05 Jan 2027 00:00:00 GMT, and after that date the request fails. The event WebSocket refuses a partner handshake withoutx-auth-orgwith 403PERMISSION_REQUIRED. - A malformed value returns 400
INVALID_AUTH_ORG; a client organization your partner account doesn't manage returns 403PARTNER_CLIENT_ACCESS_DENIED.
See Partner API 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:
{
"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 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 : 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). For an OAuth token, also its scopes: a missing scope adds WWW-Authenticate: |
| 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) |
| 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) |
| 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 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 and WebSocket authentication.
Next steps
Create a key, choose its role, use mTLS, rotate, renew and revoke
Short-lived tokens for browsers, mobile apps and cameras on your LAN
Snapshots, live and recorded video, clips, audio and shared links
Roles, OAuth scopes, rotation without downtime, and the audit trail