Authentication
API Keys and Certificates
Create a Rhombus API key, choose its role, call the API with it, and use a certificate (mTLS) key: expiry, creating, rotating and renewing keys with the API, the CSR, and revocation.
On this page
An API key is the credential for code you run on your own servers. It belongs to one organization, acts with the role you give it, and works until you delete it or until its expiry (expiresAtMs), if it has one. A key can be a plain API token, sent in a header, or a certificate key that also needs a TLS client certificate (mTLS).
Create an API key
- In the Rhombus Console, go to Settings → Integrations & Developer Resources → API Tokens and click Add API Key. EU organizations use console.eu.rhombussystems.com.
- Enter a Name that says what uses the key (
warehouse-door-sync). It shows in the audit log. - Choose an Auth Type: Api Token, or Certificate for mTLS (see Certificate keys).
- Choose a Role. The key can do exactly what the role allows, so pick the narrowest role that covers the job. See Permissions and key rotation.
- Copy the key. It's shown once.
Creating keys needs a role with API administration, and you can only give a key a role you're allowed to assign. To create keys from code, see Manage keys with the API.
Call the API with a key
Send the scheme and the key as headers on every request:
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 '{}'import os
import requests
session = requests.Session()
session.headers.update({
"x-auth-scheme": "api-token",
"x-auth-apikey": os.environ["RHOMBUS_API_KEY"],
"Content-Type": "application/json",
})
cameras = session.post(
"https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList", json={}
).json()const res = await fetch(
"https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList",
{
method: "POST",
headers: {
"x-auth-scheme": "api-token",
"x-auth-apikey": process.env.RHOMBUS_API_KEY,
"Content-Type": "application/json",
},
body: "{}",
},
);
const cameras = await res.json();The same headers work on the media hosts and the event WebSocket handshake. Partner keys use them too, plus x-auth-org to act in a client organization (see Partner API). The key is never accepted as a query parameter, so it can't authenticate an <img>, a <video> or a browser WebSocket; use a federated token there. Cameras on your local network accept only federated tokens.
Lifetime and revocation
- Expiry. A key can have an expiry time,
expiresAtMs(Unix epoch milliseconds). A key created by another API key always has one. After it passes, requests with the key get 401CREDENTIAL_EXPIRED; the key still appears in key lists (getApiTokens) until you delete it. A key withoutexpiresAtMsworks until you delete it. - Revocation takes effect within 60 seconds on every host. That applies to deleting a key (in the console or with
revokeApiToken) and to changing its role. Open event WebSocket connections that used the key get a STOMPERRORframe and close with code1008; open media sockets (live video, talk, robot, PTZ) close with1008within the same 60 seconds. - Deleting a key ends what it created: keys it created are deleted with it, and federated tokens it minted stop working.
- Keys are region-bound. A key from a US organization returns 401
INVALID_CREDENTIALon EU hosts, and the reverse. - No per-key network or rate settings. Keys have no IP allow-list and no rate limit of their own; every key draws on your organization's rate limit.
To replace a key without downtime, see Rotate an API key.
Manage keys with the API
Keys can be created, rotated and, for certificate keys, renewed with the API. All are POST:
| Action | Organization keys | Partner keys |
|---|---|---|
| Create | /api/ | /api/ |
| Rotate | /api/ | /api/ |
| Renew a certificate | /api/ | /api/ |
| Who can call | A console or mobile app session, an OAuth access token, or an API key, whose role includes API administration | A partner console or mobile app session, a partner OAuth access token, or a partner key, whose partner role includes API administration |
When the caller is an API key:
expiresAtMsis required: at most 365 days from now, and no later than the calling key's own expiry.- A key creates and rotates keys only in its own organization. A partner key that sends
x-auth-orggets 403. - A key it creates is deleted when the calling key is deleted.
- Federated tokens can't call these endpoints, and neither can the keys Rhombus's own devices and apps use (TV, keypad, kiosk, door station, executable and chatbot keys): they get 403.
An OAuth access token needs all three scopes (read, write and physical) to create, rotate or renew keys (OAuth scopes). The deprecated submitApiTokenApplication that predates the /org/ path doesn't accept API credentials; use the endpoints above.
Create a key
The key's name, shown in the console and the audit log.
The role the key acts with: one you're allowed to assign. List roles with getPermissionGroups.
API_TOKEN for a plain key, or CERT for a certificate key.
Required with CERT: the PEM certificate signing request for the key's client certificate.
When the key stops working, in Unix epoch milliseconds. Required when the caller is an API key.
EXPIRES_AT_MS=$(( ($(date +%s) + 90 * 86400) * 1000 )) # 90 days from now
curl -X POST "https://api2.rhombussystems.com/api/integrations/org/submitApiTokenApplication" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: $RHOMBUS_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"displayName\": \"warehouse-door-sync\", \"permissionGroupUuid\": \"$ROLE_UUID\", \"authType\": \"API_TOKEN\", \"expiresAtMs\": $EXPIRES_AT_MS}"import os
import time
import requests
res = requests.post(
"https://api2.rhombussystems.com/api/integrations/org/submitApiTokenApplication",
headers={
"x-auth-scheme": "api-token",
"x-auth-apikey": os.environ["RHOMBUS_API_KEY"],
"Content-Type": "application/json",
},
json={
"displayName": "warehouse-door-sync",
"permissionGroupUuid": os.environ["ROLE_UUID"],
"authType": "API_TOKEN",
"expiresAtMs": int((time.time() + 90 * 86400) * 1000), # 90 days from now
},
)
res.raise_for_status()
data = res.json()
if data.get("error"):
raise RuntimeError(data.get("errorMsg"))
api_key = data["apiKey"] # shown once: store it like a passwordThe response holds the new key:
The key. It's returned once; store it securely.
The key's ID, used to rotate, renew or delete it.
When the key expires, if it has an expiry.
Certificate keys only: the signed client certificate (PEM).
Certificate keys only: when the certificate expires.
A refused request can return HTTP 200 with "error": true and an errorMsg, so check the body as well as the status.
Rotate a key
rotateApiToken issues a replacement key with the same role and keeps the old key working for an overlap, so you can deploy the new key without downtime.
The key to replace.
How long the old key keeps working, in seconds: one day by default, at most 2592000 (30 days).
Required when rotating a certificate key: a CSR for the new key's certificate.
The new key's expiry, in Unix epoch milliseconds. Required when the caller is an API key, with the same limits as creating a key.
curl -X POST "https://api2.rhombussystems.com/api/integrations/org/rotateApiToken" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: $RHOMBUS_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"tokenUuid\": \"$OLD_TOKEN_UUID\", \"overlapSec\": 172800, \"expiresAtMs\": $(( ($(date +%s) + 90 * 86400) * 1000 ))}"The response has the new key's apiKey, tokenUuid, expiresAtMs and, for certificate keys, cert and certNotAfterMs, plus previousKeyExpiresAtMs: when the old key stops working. Deploy the new key before then. The full procedure is in Rotate an API key.
Certificate keys (mTLS)
A certificate key adds a TLS client certificate to the API key. Requests are refused unless they present both the key and the certificate issued for it, so a leaked key alone isn't enough. Use it when your security policy requires mutual TLS for service credentials.
Where it works: only the REST API hosts api2.rhombussystems.com and api2.eu.rhombussystems.com, which pass TLS through to Rhombus so the client certificate can be checked. Media hosts, the event WebSocket and cameras on your LAN don't accept certificate keys; use a separate API key or a federated token for those.
1. Make a private key and a CSR
Generate the key on the machine that will use it, and keep it there:
openssl req -new -newkey rsa:2048 -nodes \
-keyout rhombus-client.key \
-out rhombus-client.csr \
-subj "/CN=warehouse-door-sync"RSA 2048-bit or ECDSA P-256 keys both work. Rhombus sets the certificate's subject itself, so the CN you choose doesn't matter. Rhombus verifies the CSR's signature, which proves you hold its private key; a CSR whose signature doesn't verify is rejected. openssl req signs it for you.
2. Create the key
In Add API Key, choose Auth Type: Certificate, choose a role, and paste the contents of rhombus-client.csr. With the API, send "authType": "CERT" and the CSR in csr (Create a key). Rhombus returns the API key and a signed client certificate. Save the certificate as rhombus-client.crt.
3. Call the API
Use the scheme api, send the key in x-auth-apikey as usual, and present the certificate in the TLS handshake:
curl -X POST "https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList" \
--cert rhombus-client.crt --key rhombus-client.key \
-H "x-auth-scheme: api" \
-H "x-auth-apikey: $RHOMBUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
res = requests.post(
"https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList",
cert=("rhombus-client.crt", "rhombus-client.key"),
headers={
"x-auth-scheme": "api",
"x-auth-apikey": os.environ["RHOMBUS_API_KEY"],
"Content-Type": "application/json",
},
json={},
)import { readFileSync } from "node:fs";
import https from "node:https";
const agent = new https.Agent({
cert: readFileSync("rhombus-client.crt"),
key: readFileSync("rhombus-client.key"),
});
const req = https.request(
"https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList",
{
method: "POST",
agent,
headers: {
"x-auth-scheme": "api",
"x-auth-apikey": process.env.RHOMBUS_API_KEY,
"Content-Type": "application/json",
},
},
(res) => res.pipe(process.stdout),
);
req.end("{}");Partner certificate keys work the same way, with the scheme api (or its alias partner-api). See Partner API.
Renew a certificate
Certificates last 365 days. Before certNotAfterMs, get a new certificate for the same key with renewApiTokenCert (partner keys: /api/partner/renewApiTokenCert):
The certificate key to renew. Leave it out when a certificate key renews its own certificate.
A CSR for the new certificate, made as in step 1.
openssl req -new -newkey rsa:2048 -nodes \
-keyout rhombus-client-new.key -out rhombus-client-new.csr -subj "/CN=warehouse-door-sync"
curl -X POST "https://api2.rhombussystems.com/api/integrations/org/renewApiTokenCert" \
--cert rhombus-client.crt --key rhombus-client.key \
-H "x-auth-scheme: api" \
-H "x-auth-apikey: $RHOMBUS_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile csr rhombus-client-new.csr '{csr: $csr}')" \
| jq -r .cert > rhombus-client-new.crtThe response has cert and certNotAfterMs. The API key stays the same and there's no overlap, so switch the client to the new certificate and private key as soon as you receive them. To change the key as well, rotate it with a new CSR instead.
Certificate facts
- Validity: developer and partner certificates last 365 days (
certNotAfterMs). Renew them in place, or rotate the key. - TLS: TLS 1.2. If your network inspects TLS, exempt the
api2hosts, or the proxy strips the client certificate. - Revocation: deleting the key revokes its certificate within 60 seconds.
- Failures: a certificate Rhombus didn't issue fails the TLS handshake itself (no HTTP status). A certificate key sent without its certificate (for example with
x-auth-scheme: api-token), or with a certificate issued for a different key, returns 401CERTIFICATE_MISMATCH(Client certificate does not match the api key).
Keys for other kinds of access
- Customers authorize your app: use Sign in with Rhombus. An OAuth app can also create an API key for background work; the key is deleted when the user revokes the app's access.
- MSPs and resellers: a partner API key reaches every client organization you manage.
- Browsers, mobile apps and cameras on your LAN: mint a short-lived federated token from your backend.