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.