All API requests authenticated via API key or OAuth token are subject to rate limiting. Limits are enforced per credential and per organization.
| Authentication method | Header | Applies to |
|---|
| API key | x-auth-apikey | Developer and Partner Developer accounts |
| OAuth token | x-auth-access-token | OAuth-authorized applications |
Both methods share the same rate limiting behavior.
Throttled responses
When your request is rate limited, the API returns a 429 status with a Retry-After header:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: text/plain
Too many api requests. Enhance your calm.
| Detail | Value |
|---|
| Status code | 429 |
Retry-After header | Seconds to wait before retrying (e.g., 60) |
| Body | Too many api requests. Enhance your calm. |
Do not immediately retry on a 429. Repeated requests while rate limited continue to be rejected and do not reset your limit window.
Handling rate limits
Read the Retry-After header
The Retry-After header tells you exactly how many seconds to wait. Always prefer this value over hardcoded delays.
Pause requests
Stop sending requests for the duration specified in the header.
Retry your request
After the wait period, retry the original request.
Retry strategy
Use exponential backoff with jitter for the most resilient integration:
delay = min(base_delay × 2^attempt + random_jitter, max_delay)
| Parameter | Recommended value |
|---|
| Base delay | 1 second |
| Max delay | 60 seconds |
| Max retry attempts | 5–10 |
| Jitter | Random 0–1 second |
import time
import random
import requests
def call_api(url, headers, payload, max_retries=5):
for attempt in range(max_retries):
response = requests.post(url, headers=headers, json=payload)
if response.status_code == 200:
return response.json()
if response.status_code == 429:
wait = int(response.headers.get("Retry-After", 60))
time.sleep(wait)
continue
if response.status_code >= 500:
delay = min(1 * (2 ** attempt) + random.random(), 60)
time.sleep(delay)
continue
# 4xx errors (other than 429) are not retryable
response.raise_for_status()
raise Exception("Max retries exceeded")
# Usage
result = call_api(
url="https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList",
headers={
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
},
payload={}
)
async function callApi(url, headers, payload, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json", ...headers },
body: JSON.stringify(payload),
});
if (response.ok) {
return await response.json();
}
if (response.status === 429) {
const wait = parseInt(response.headers.get("Retry-After") || "60", 10);
await new Promise((r) => setTimeout(r, wait * 1000));
continue;
}
if (response.status >= 500) {
const delay = Math.min(1 * 2 ** attempt + Math.random(), 60);
await new Promise((r) => setTimeout(r, delay * 1000));
continue;
}
// 4xx errors (other than 429) are not retryable
throw new Error(`Request failed: ${response.status} ${response.statusText}`);
}
throw new Error("Max retries exceeded");
}
// Usage
const result = await callApi(
"https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList",
{
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
},
{}
);
#!/bin/bash
URL="https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList"
API_KEY="YOUR_API_KEY"
MAX_RETRIES=5
for attempt in $(seq 0 $((MAX_RETRIES - 1))); do
HTTP_CODE=$(curl -s -o /tmp/response.json -w "%{http_code}" \
-X POST "$URL" \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: $API_KEY" \
-d '{}')
if [ "$HTTP_CODE" -eq 200 ]; then
cat /tmp/response.json
exit 0
elif [ "$HTTP_CODE" -eq 429 ]; then
echo "Rate limited. Waiting 60 seconds..." >&2
sleep 60
elif [ "$HTTP_CODE" -ge 500 ]; then
DELAY=$(echo "1 * 2^$attempt" | bc)
[ "$DELAY" -gt 60 ] && DELAY=60
echo "Server error ($HTTP_CODE). Retrying in ${DELAY}s..." >&2
sleep "$DELAY"
else
echo "Client error ($HTTP_CODE). Not retrying." >&2
cat /tmp/response.json >&2
exit 1
fi
done
echo "Max retries exceeded." >&2
exit 1
When to retry
| Response | Action |
|---|
200–299 | Success — no retry needed |
429 | Wait for Retry-After seconds, then retry |
5xx | Transient server error — retry with exponential backoff |
4xx (not 429) | Client error — fix the request, do not retry |
The rate limiting system is fail-open. If the rate limit service itself is unavailable, your request is allowed through. Do not rely on this behavior — always design your integration to respect limits.
Alert notification throttling
Alert notifications (distinct from API rate limits) have a configurable minimum interval between consecutive alerts of the same type for a given device. This prevents alert fatigue from high-frequency events like motion detection.
| Interval | Seconds |
|---|
| 1 minute | 60 |
| 2 minutes | 120 |
| 5 minutes (default) | 300 |
| 10 minutes | 600 |
| 20 minutes | 1200 |
| 30 minutes | 1800 |
| 1 hour | 3600 |
Configure this per policy and per activity type. During the backoff window, duplicate alerts for the same device and activity type are suppressed server-side.
Alerts with new identity information — such as a different recognized face or license plate — bypass the backoff and are delivered immediately, even within the suppression window.