Skip to content
Core API
Esc
↑↓navigate↵open⌘Jpreview
On this page

Responses and errors

Understand JSON:API responses, status codes, and rate limits.

Collection response

{
  "data": [
    {
      "id": "3898",
      "type": "lead",
      "attributes": {
        "event-id": 319986,
        "sponsor-ids": [103705],
        "notes": "Requested a product demo"
      },
      "relationships": {
        "registrant": {
          "data": { "id": "77881", "type": "event-registrant" }
        }
      }
    }
  ],
  "meta": {
    "total_count": 1,
    "total_pages": 1,
    "current_page": 1
  }
}

Individual response with an included relationship

{
  "data": {
    "id": "3898",
    "type": "lead",
    "attributes": {
      "event-id": 319986,
      "created-by-registrant-id": null
    },
    "relationships": {
      "created-by-registrant": {
        "data": null
      }
    }
  }
}

If the relationship is non-null and requested through include, its resource appears in included:

{
  "included": [
    {
      "id": "77882",
      "type": "event-registrant",
      "attributes": {
        "external-id": "CRM-42",
        "first-name": "Avery",
        "last-name": "Lee",
        "email": "avery@example.com"
      }
    }
  ]
}

JSON:API type values are normally singular resource names. Analytics, statistics, and benchmarks retain their collective resource name as their type.

Error response

Core errors use an errors array. For example, a disabled scope or a missing permission returns 403 Forbidden:

{
  "errors": [
    {
      "title": "Permission denied."
    }
  ]
}

A missing, expired, or invalid Core token also returns 403, with the existing authentication code user_not_found. Despite the wording of its message, this response means you should check the API token, not create a personal user account:

{
  "errors": [
    {
      "title": "User not found. You may have an account with a different email address, or you may want to sign up for a new Brella account.",
      "code": "user_not_found"
    }
  ]
}

The code property is optional. Ordinary scope-denied and not-found responses do not contain a separate machine code; use the HTTP status to classify them. Treat title as a human-readable explanation, not a stable error identifier.

These examples show other Core error titles:

HTTP status Example errors[0].title Next step
400 Invalid value for parameter: notes Send notes as text or null, not a JSON object or array.
404 Oh no, that record or page does not exist or cannot be accessed. It might have been deleted. Check the resource ID, event access, and row restrictions.
422 Validation failed: Name can't be blank Supply the required value. Validation messages depend on the resource and rejected data.

For a permitted collection read with no matching records, expect 200 with an empty data array. An individual record outside the scope’s restrictions returns 404.

Status Meaning
400 Bad Request Wrong URL level, conflicting event/organization ID, malformed scalar/array value, invalid date, or missing required filter.
403 Forbidden Missing, expired, wrong-context, or unknown token; disabled scope; missing permission; or disallowed action.
404 Not Found Unknown resource, missing scope, event/record outside scope, restricted record, or foreign/missing related record.
422 Unprocessable Content A model or business rule rejected the write, or an analytics request exceeded a protected dataset limit.
429 Too Many Requests Rate limit exceeded. Respect the Retry-After header.

Rate limiting

The Core API allows 500 requests per token per minute and 500 requests per IP address per minute. Both limits apply. See Rate limits and retries for Retry-After handling, shared request queues, and safe retry practices. A throttled response can have a plain-text body; do not require an errors array to recognize HTTP 429.

Last updated on September 9, 2026