Skip to main content
API errors use a consistent JSON shape:
{
  "error": "bad_request",
  "message": "Invalid request body",
  "details": {
    "videoIds": ["videoIds must not contain duplicates"]
  }
}
details is optional and is most commonly present for request validation errors.

Status codes

StatusError codeMeaning
400bad_requestThe JSON body is missing, malformed, or fails field validation.
401unauthorizedThe API key is missing, malformed, revoked, or unknown.
403upgrade_requiredThe key is valid, but the account is not on Pro.
404not_foundThe requested API path does not exist.
405method_not_allowedThe route only accepts POST.
429rate_limitedA request budget was exhausted.
500route_error or server_errorAn unexpected server failure occurred.

Request limits

Authenticated public requests are limited to 20 requests/minute per API key. The public endpoints also currently share a stricter budget of 5 requests/minute per client IP. A client operating from one IP should therefore budget for no more than 5 public requests/minute. Cloudflare rate-limit counters can be eventually consistent. Do not depend on an exact remaining-request count at the edge.

Retry behavior

A 429 response includes a Retry-After header, currently expressed in seconds. Wait for that duration before trying again. For 500 responses, retry only idempotent read requests and use exponential backoff with jitter. For example: 1 second, 2 seconds, 4 seconds, then stop and surface the failure. Do not retry 400, 401, or 403 without first correcting the request or account state.
if (response.status === 429) {
  const retryAfter = Number(response.headers.get("Retry-After") ?? "60");
  await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
}

Health check

POST /api/public/health requires no authentication but does require an empty JSON object body:
curl -H "Content-Type: application/json" \
  -d '{}' \
  "https://monitoryt.com/api/public/health"
Successful response:
{ "status": "ok" }