GET
Required scope https://app.honeybadger.io/v3/projects/{project_id}/faults
faults:read
Returns a list of faults for the project.
Example request
curl "https://app.honeybadger.io/v3/projects/$PROJECT_ID/faults" \ -H "Authorization: Bearer $HONEYBADGER_API_TOKEN"Parameters
9Path parameters
| Field | Type | Description |
|---|---|---|
project_id required | string | Project ID. |
Query parameters
| Field | Type | Description |
|---|---|---|
page | integer | Page number (1-indexed). Default: 1. Min 1. |
per_page | integer | Items per page. Default: 25. Min 1, max 100. |
q | string | Search query, in the syntax of the web UI's error search, such as environment:production, is:resolved or class:ArgumentError. Prefix a filter with - to negate it. See Error search for the syntax and filters. Filters that need the search index return nothing when it holds no data for the project. |
order | string | recent sorts by last occurrence, frequent by occurrence count. Left out, by creation time. Allowed values: recent, frequent. |
sort | string | Direction for order. Defaults to desc for recent and frequent, asc for creation time. Allowed values: asc, desc. |
created_after | number | Only faults first seen after this Unix timestamp (seconds, not ISO 8601). |
occurred_after | number | Only occurrences after this Unix timestamp (seconds, not ISO 8601). A value before the project's retention window is moved up to it. On the fault list, occurrence counts cover this window. |
occurred_before | number | Only occurrences before this Unix timestamp (seconds, not ISO 8601). |
Responses
1200 Success
Example payload
{ "data": [ { "id": "12345", "project_id": "Xk9mZp", "klass": "NoMethodError", "message": "undefined method 'foo' for nil:NilClass", "component": "UsersController", "action": "show", "environment": "production", "resolved": true, "ignored": true, "created_at": "2026-01-01T00:00:00Z", "last_notice_at": "2026-01-01T00:00:00Z", "notices_count": 214, "comments_count": 2, "tags": [ "critical", "backend" ], "assignee_id": "Uq7rT2", "snoozed": true, "assignee": { "id": "Uz4wKm", "name": "Jane Smith", "email": "jane@example.com" }, "last_notice_deploy": { "id": "Dp2yNk", "project_id": "Xk9mZp", "environment": "production", "revision": "a1b2c3d4", "repository": "acme/app", "local_username": "jane", "created_at": "2026-01-01T00:00:00Z" }, "tickets": [ { "url": "https://github.com/acme/shop/issues/482", "integration_id": "Ch9wLp" } ], "resolve_on_deploy": true, "recording_paused_until": "2026-01-01T00:00:00Z", "notices_count_in_range": 37, "links": { "web": "https://app.honeybadger.io/projects/Xk9mZp" } } ], "pagination": { "page": 1, "per_page": 25 }, "links": { "self": "/v3/projects/Xk9mZp/faults?page=2&per_page=25", "first": "/v3/projects/Xk9mZp/faults?page=1&per_page=25", "prev": "/v3/projects/Xk9mZp/faults?page=1&per_page=25", "next": "/v3/projects/Xk9mZp/faults?page=3&per_page=25" }, "meta": { "request_id": "6f1c2b0e-8d4a-4f6e-9b2a-3c5d7e9f1a2b" }}Response schema47
| Field | Type | Description |
|---|---|---|
data required | array<object> | |
data[].id required | string | |
data[].project_id required | string | ID of the project this fault belongs to. |
data[].klass | string | null | Error class name. |
data[].message required | string | Error message. |
data[].component | string | null | Component where the error occurred. |
data[].action | string | null | Action where the error occurred. |
data[].environment | string | null | Environment name. |
data[].resolved | boolean | Whether the fault is resolved. |
data[].ignored | boolean | Whether the fault is ignored. |
data[].created_at required | date-time | When the fault was first reported. |
data[].last_notice_at | date-time | null | When the last notice was received. |
data[].notices_count | integer | Total number of notices for this fault. |
data[].comments_count | integer | Number of comments on this fault. |
data[].tags | array<string> | Tags assigned to this fault. |
data[].assignee_id | string | null | Same as assignee.id. Written by PATCH or POST …/assign. |
data[].snoozed | boolean | Whether a snooze is in effect now. A new snooze replaces any existing one. |
data[].assignee | object | null | User assigned to this fault. |
data[].assignee.id | string | ID of the assignee. |
data[].assignee.name | string | null | Name of the assignee. |
data[].assignee.email | string | Email of the assignee. |
data[].last_notice_deploy | object | null | The deploy that was live when the error last occurred: the newest deploy in the fault's environment before last_notice_at. A guess from timing, not the deploy that introduced or resolved the error. |
data[].last_notice_deploy.id required | string | |
data[].last_notice_deploy.project_id required | string | ID of the project this deploy belongs to. |
data[].last_notice_deploy.environment required | string | null | Deploy environment; null when the deploy named none. |
data[].last_notice_deploy.revision required | string | null | Source control revision. |
data[].last_notice_deploy.repository required | string | null | Source control repository. |
data[].last_notice_deploy.local_username required | string | null | Username of the person who triggered the deploy. |
data[].last_notice_deploy.created_at required | date-time | When the deploy was recorded. |
data[].tickets | array<object> | Issue tracker tickets linked to this fault. |
data[].tickets[].url | string | URL of the ticket. |
data[].tickets[].integration_id | string | ID of the integration that created the ticket. |
data[].resolve_on_deploy | boolean | Whether this fault is waiting to be resolved by the next recorded deploy. Absent for a fault on an inactive project. |
data[].recording_paused_until | date-time | null | When a recording pause ends; null when recording is not paused. Absent for a fault on an inactive project. |
data[].notices_count_in_range | integer | Notices inside the requested occurrence window. Present only when the request supplied occurred_after or occurred_before. |
data[].links required | object | Links into the Honeybadger web UI. |
data[].links.web required | uri | The resource's page in the Honeybadger web UI, as an absolute URL. Resources without a page, such as outages and deploys, don't have links. For a project provisioned through Heroku, error, notice and comment links go through Heroku's single sign-on. |
pagination | object | Offset-based pagination information. |
pagination.page required | integer | Current page number. Min 1. |
pagination.per_page required | integer | Items per page. Min 1, max 100. |
links | object | Navigation links for a numbered-page collection. Each link is a root-relative path (/v3/...); resolve it against the API host. |
links.self required | uri-reference | This page. |
links.first | uri-reference | First page. |
links.prev | string | null | Previous page, or null on the first page. |
links.next | string | null | Next page, or null on the last page. |
meta | object | |
meta.request_id | string | Unique identifier for the request, for correlating with support. |
Errors
5
400
Bad Request
A query parameter is malformed or outside its allowed values. error.details names the parameter.
Example payload
{ "error": { "code": "invalid_parameter", "message": "unmapped must be true or false", "details": [ { "field": "unmapped", "message": "must be true or false" } ] }, "meta": { "request_id": "abc123" }}Response schema6
| Field | Type | Description |
|---|---|---|
error required | object | |
error.code required | string | Machine-readable code. Branch on this, not the message. Allowed values: unauthorized, unsupported_auth_scheme, credential_in_query, access_denied, insufficient_scope, requires_user_token, project_restricted, account_inactive, account_parked, feature_unavailable, not_found, validation_error, delete_failed, limit_reached, rate_limit_exceeded, concurrent_request, streams_provisioning, ingestion_key_not_accepted, maintenance_mode, invalid_parameter, forbidden_attributes, service_unavailable, ambiguous_account, fault_merged. |
error.message required | string | Human-readable explanation. |
error.details | array<object> | object | A list of {field, message} on validation_error and invalid_parameter, and on feature_unavailable or limit_reached when one field caused the refusal; {required_scope, token_scopes} on insufficient_scope; {merged_into, location} on fault_merged. Absent when there's nothing to add. |
meta | object | |
meta.request_id | string | Unique identifier for the request, for correlating with support. |
401
Unauthorized
The credential is missing, invalid, expired or revoked (unauthorized), or was sent in a way v3 doesn’t accept (see the examples).
Example payload: unauthorized (Missing, malformed, expired or revoked credential)
{ "error": { "code": "unauthorized", "message": "Access denied" }, "meta": { "request_id": "abc123" }}Example payload: unsupported_auth_scheme (Sent as HTTP basic, which v3 does not accept)
{ "error": { "code": "unsupported_auth_scheme", "message": "Send the credential as `Authorization: Bearer <token>`; v3 does not accept HTTP basic" }, "meta": { "request_id": "abc123" }}Example payload: credential_in_query (Sent as the `auth_token` query parameter)
{ "error": { "code": "credential_in_query", "message": "Credentials must be sent in the Authorization header" }, "meta": { "request_id": "abc123" }}Response schema6
| Field | Type | Description |
|---|---|---|
error required | object | |
error.code required | string | Machine-readable code. Branch on this, not the message. Allowed values: unauthorized, unsupported_auth_scheme, credential_in_query, access_denied, insufficient_scope, requires_user_token, project_restricted, account_inactive, account_parked, feature_unavailable, not_found, validation_error, delete_failed, limit_reached, rate_limit_exceeded, concurrent_request, streams_provisioning, ingestion_key_not_accepted, maintenance_mode, invalid_parameter, forbidden_attributes, service_unavailable, ambiguous_account, fault_merged. |
error.message required | string | Human-readable explanation. |
error.details | array<object> | object | A list of {field, message} on validation_error and invalid_parameter, and on feature_unavailable or limit_reached when one field caused the refusal; {required_scope, token_scopes} on insufficient_scope; {merged_into, location} on fault_merged. Absent when there's nothing to add. |
meta | object | |
meta.request_id | string | Unique identifier for the request, for correlating with support. |
403
Forbidden
The credential isn’t allowed to do this. error.code says why. An account or project the credential doesn’t cover is 404 not_found, not 403.
Example payload: access_denied (The credential isn't allowed to do this to this record)
{ "error": { "code": "access_denied", "message": "Access denied" }, "meta": { "request_id": "abc123" }}Example payload: insufficient_scope (The credential lacks the permission this endpoint requires)
{ "error": { "code": "insufficient_scope", "message": "Insufficient scope", "details": { "required_scope": "faults:write", "token_scopes": [ "faults:read", "insights:read" ] } }, "meta": { "request_id": "abc123" }}Example payload: requires_user_token (The endpoint records who acted, and an account token has nobody)
{ "error": { "code": "requires_user_token", "message": "This endpoint records the person who acted, so it requires a user credential rather than an account token" }, "meta": { "request_id": "abc123" }}Example payload: project_restricted (A project-restricted credential cannot create a project)
{ "error": { "code": "project_restricted", "message": "Project-restricted tokens cannot create projects" }, "meta": { "request_id": "abc123" }}Response schema6
| Field | Type | Description |
|---|---|---|
error required | object | |
error.code required | string | Machine-readable code. Branch on this, not the message. Allowed values: unauthorized, unsupported_auth_scheme, credential_in_query, access_denied, insufficient_scope, requires_user_token, project_restricted, account_inactive, account_parked, feature_unavailable, not_found, validation_error, delete_failed, limit_reached, rate_limit_exceeded, concurrent_request, streams_provisioning, ingestion_key_not_accepted, maintenance_mode, invalid_parameter, forbidden_attributes, service_unavailable, ambiguous_account, fault_merged. |
error.message required | string | Human-readable explanation. |
error.details | array<object> | object | A list of {field, message} on validation_error and invalid_parameter, and on feature_unavailable or limit_reached when one field caused the refusal; {required_scope, token_scopes} on insufficient_scope; {merged_into, location} on fault_merged. Absent when there's nothing to add. |
meta | object | |
meta.request_id | string | Unique identifier for the request, for correlating with support. |
404
Not Found
Resource not found
Example payload
{ "error": { "code": "not_found", "message": "Resource not found" }, "meta": { "request_id": "abc123" }}Response schema6
| Field | Type | Description |
|---|---|---|
error required | object | |
error.code required | string | Machine-readable code. Branch on this, not the message. Allowed values: unauthorized, unsupported_auth_scheme, credential_in_query, access_denied, insufficient_scope, requires_user_token, project_restricted, account_inactive, account_parked, feature_unavailable, not_found, validation_error, delete_failed, limit_reached, rate_limit_exceeded, concurrent_request, streams_provisioning, ingestion_key_not_accepted, maintenance_mode, invalid_parameter, forbidden_attributes, service_unavailable, ambiguous_account, fault_merged. |
error.message required | string | Human-readable explanation. |
error.details | array<object> | object | A list of {field, message} on validation_error and invalid_parameter, and on feature_unavailable or limit_reached when one field caused the refusal; {required_scope, token_scopes} on insufficient_scope; {merged_into, location} on fault_merged. Absent when there's nothing to add. |
meta | object | |
meta.request_id | string | Unique identifier for the request, for correlating with support. |
422
Unprocessable Content
No path names the account, so the API token has to. This is returned when the token covers more than one account and the account a request applies to cannot be determined. Use a token bound to a single account.
Example payload
{ "error": { "code": "ambiguous_account", "message": "This credential covers more than one account, so the account a request applies to is ambiguous. Use a token bound to a single account." }, "meta": { "request_id": "abc123" }}Response schema6
| Field | Type | Description |
|---|---|---|
error required | object | |
error.code required | string | Machine-readable code. Branch on this, not the message. Allowed values: unauthorized, unsupported_auth_scheme, credential_in_query, access_denied, insufficient_scope, requires_user_token, project_restricted, account_inactive, account_parked, feature_unavailable, not_found, validation_error, delete_failed, limit_reached, rate_limit_exceeded, concurrent_request, streams_provisioning, ingestion_key_not_accepted, maintenance_mode, invalid_parameter, forbidden_attributes, service_unavailable, ambiguous_account, fault_merged. |
error.message required | string | Human-readable explanation. |
error.details | array<object> | object | A list of {field, message} on validation_error and invalid_parameter, and on feature_unavailable or limit_reached when one field caused the refusal; {required_scope, token_scopes} on insufficient_scope; {merged_into, location} on fault_merged. Absent when there's nothing to add. |
meta | object | |
meta.request_id | string | Unique identifier for the request, for correlating with support. |