Shared API behavior
Authentication, errors, retries, and compatibility
These rules apply across /v1 resources. Endpoint-specific fields and non-2xx responses come from the running OpenAPI.
Request IDs
X-Request-ID: req_partner_incident_0182Every response has a request ID. In production, log method, public path, status, latency, and request ID—not bodies containing camera URLs or keys.
Error envelope
{
"error": {
"type": "invalid_request_error",
"code": "source_unreachable",
"message": "The source did not return a decodable frame before the timeout.",
"param": "input.url"
},
"request_id": "req_01..."
}Code against type/code. The human message can improve without an API-version change.
Idempotency
Idempotency-Key: partner-order-0182-sourceRetry a mutation with the same key and semantically identical body. Never reuse one key for different work.
Retries
Safely retry GET/HEAD, documented retryable mutations with the same Idempotency-Key, and 408, 425, 429, or transient 5xx responses. Retry 409 only when its error code explicitly marks a transient conflict; never retry idempotency_key_reused with a different body. Use bounded exponential backoff with jitter and honor Retry-After.
Cursors and time
GET /v1/sources?limit=100&after=<next_cursor>
{
"object": "list",
"data": [],
"has_more": false,
"next_cursor": null
}Source, Monitor, Incident, Webhook Endpoint, and Delivery lists default to limit=100 and cap it at 500. When has_more is true, pass next_cursor unchanged as the next after value; cursors are bound to their collection and filters, so modifying one, crossing collections, or changing filters returns 400 invalid_cursor. Never derive page numbers or sort opaque IDs. JSON timestamps are RFC 3339 UTC, with source video time separate from receipt/Event time.