Skip to content

Error handling

All error responses return JSON with three fields:

{
"title": "not_found",
"detail": "Not found.",
"status": 404
}
FieldTypeDescription
titlestringMachine-readable error code — use this for programmatic handling
detailstring | arrayHuman-readable description, or field-level validation errors (see below)
statusintegerHTTP status code (mirrors the response status)

When input validation fails, detail is an array of objects — one per invalid field. Each object maps the field name to a list of error messages:

{
"title": "invalid",
"detail": [
{
"refresh_rate": [
"A valid number is required.",
"Ensure this value is greater than 0."
]
},
{
"max_width": [
"Ensure this value is greater than or equal to 1."
]
}
],
"status": 400
}

Non-field errors (e.g. a malformed request body) return detail as a plain string:

{
"title": "invalid",
"detail": "Invalid hash.",
"status": 400
}
StatustitleWhen it occurs
400invalidRequest validation failed — field errors in detail
401not_authenticatedMissing or invalid authorization credentials
403permission_deniedAuthenticated but not allowed to access this resource
404not_foundResource does not exist, or a required service is not active on the camera
405method_not_allowedHTTP method not supported on this endpoint
429throttledRate limit exceeded — see Rate limiting
502bad_gatewayAngelcam could not reach an upstream service (e.g. camera or Arrow client offline)
503bad_gatewayService temporarily unavailable — retry after a short wait

Full schema definitions are available in the API Reference.

All API calls count toward per-account rate limits tracked across all authentication methods:

  • 20 requests per minute
  • 1 000 requests per day

When the limit is exceeded, the API returns 429 with a JSON body indicating how long to wait:

{
"title": "throttled",
"status": 429,
"detail": "Request was throttled. Expected available in 7 seconds."
}

Parse the wait time from the detail string, or simply retry after a fixed delay. Implement exponential backoff if you receive multiple consecutive 429 responses.

To raise your limits, contact support. Higher limits are available on the Business and Flex plans — see plans and pricing.

401 on a seemingly valid token OAuth2 access tokens expire after 10 hours. Refresh the access token using the refresh token before retrying. See Authentication.

404 on a recording or timeline endpoint Recording endpoints return 404 when the Cloud Recording service is not active on that camera — not only when the camera doesn’t exist. Activate the service first or check that it’s assigned to the correct camera.

404 on a valid-looking URL All endpoint URLs require a trailing slash. /cameras/123/recording returns 404; the correct URL is /cameras/123/recording/. See API conventions.

403 due to missing scope Each endpoint requires a specific scope (e.g. camera_access, recording_access). Scopes are configured when creating an OAuth2 token and also when creating a Personal Access Token in the MyAngelcam Dashboard. If the token was issued without the required scope, the API returns 403 even though the credentials are valid. Check the token’s scopes against the scopes listed in the API Reference for that endpoint.

403 in another user’s space A user can be a member of multiple spaces with different permission levels. When the active space belongs to another user, the current user may not have permission to perform certain actions. Use the Get space permissions endpoint to inspect what the current user can do in the active space.