Skip to content

Conventions

Behaviors shared by every endpoint in the Public API v2.

Identifiers

All resources are identified by a public_id — a stable, opaque string. Internal numeric IDs are never exposed. When creating relationships between resources (e.g., assigning content to a user), reference them by their public_id.

public_id values are UUIDs in canonical form. Treat them as opaque strings — do not parse or generate them yourself.

Pagination

List endpoints return a paginated envelope:

{
  "data": [ /* up to page_size items */ ],
  "meta": {
    "page": 1,
    "page_size": 25,
    "total_count": 137
  }
}

Control pagination with these query parameters:

Parameter Default Max Description
page 1 — 1-indexed page number.
page_size 25 100 Items per page.

A page below 1, or a page_size below 1 or above 100, returns 422 with a validation_error code. The API does not reduce an out-of-range value to the nearest allowed one.

Every list has a stable order: when two items tie on the sort field, a unique key breaks the tie. If the data does not change while you page, each item appears on exactly one page.

Sorting

List endpoints support ordering with a comma-separated list of fields. Prefix with - for descending order:

GET /users?ordering=-created,last_name

The supported fields per endpoint are listed in the API reference.

Filtering

Most list endpoints accept resource-specific filters as query parameters — for example GET /users?email=jane.doe@acme.com or GET /content-items?content_type=video&is_archived=false. The supported filters are listed in the API reference for each endpoint. See Filtering & sorting for the full syntax, including date-range bounds and the difference from saved-report RQL.

Unknown query parameters are ignored

A query parameter the endpoint does not declare is ignored: the request succeeds and the filter is not applied, so you get more results than you asked for. Copy parameter names from the API reference. For example, filter events by series with event_series_id (the series public_id); there is no event_series_public_id filter. Request bodies are different: an unknown body field returns 422 (see Unknown fields).

Errors

Requests are strict: a body field the endpoint does not accept returns 422 instead of being ignored, with a message that says how to fix the request. See Unknown fields.

All errors follow a consistent envelope:

{
  "error": {
    "code": "not_found",
    "message": "Content item not found.",
    "request_id": "req_a1b2c3d4"
  }
}

Validation errors include field-level details:

{
  "error": {
    "code": "validation_error",
    "message": "Validation failed.",
    "request_id": "req_a1b2c3d4",
    "field_errors": {
      "email": ["A user with this email already exists."]
    },
    "non_field_errors": ["Cannot assign archived content."]
  }
}

Error codes

HTTP status code Meaning
400 bad_request Malformed request.
401 unauthenticated / invalid_token Missing or invalid token.
403 forbidden Authenticated, but the operation is not permitted.
404 not_found Resource does not exist or is not visible to this token.
409 conflict / duplicate The operation conflicts with the current state.
412 precondition_failed If-Match ETag did not match the current resource.
422 validation_error Request body failed validation.
429 rate_limited Too many requests; see Rate limits.
500 internal_error Unexpected server error. Quote the request_id to support.

Always log request_id with every failure — it's the fastest path to a resolution. For which failures are safe to retry and how to avoid duplicate creates, see Errors, retries & idempotency.

Rate limits

All endpoints are rate-limited. Specific per-tier limits are not yet published; the service returns sensible defaults during the preview.

Every response includes rate-limit headers:

Header Description
X-RateLimit-Limit Your rate limit (requests per window).
X-RateLimit-Remaining Requests remaining in the current window.
X-RateLimit-Reset Seconds until the limit resets.

When a request is rate-limited, the response is HTTP 429 with the standard error envelope and a Retry-After header.

ETags and concurrency

Resources that support optimistic concurrency return an ETag header on GET and require If-Match on PATCH. A mismatched ETag returns HTTP 412 precondition_failed — re-fetch the resource and retry.

Bulk endpoints

Bulk endpoints (e.g. POST /content-items/bulk/archive) operate on up to 100 resources per request. Per-item failures are isolated — a partial batch returns HTTP 207 Multi-Status with a per-item result list. Some bulk flows are asynchronous and return a job to poll instead. See Bulk operations & async jobs for both patterns.