Issues
Deduplicated, grouped error and crash issues with occurrence history and a status workflow.
Issues group repeated crashes/errors (by fingerprint) into a single record with a status workflow (open → acknowledged/muted/resolved/ignored). These endpoints have no plain /api/issues path — they’re only mounted org/project-scoped, at /api/orgs/:orgSlug/projects/:projectSlug/issues.
Auth: session cookie (or API key, resolved to your account’s org/project membership) — see Authentication
GET /api/orgs/:orgSlug/projects/:projectSlug/issues
List issues for the project, with optional filtering and sorting.
Query params
| param | type | description |
|---|---|---|
| status | string | Exact match on status. Omit, or pass all, for no filter |
| type | string | Exact match on type. Omit, or pass all, for no filter |
| environment | string | Exact match on environment |
| service | string | Exact match on service |
| sort | string | occurrences (by occurrence_count) | affected_users (by affected_user_count) | anything else / omitted (by last_seen_at, default). Always descending |
| limit | number | Max results. Default 50, capped at 100 |
| offset | number | Pagination offset. Default 0 |
Response 200
{
"issues": [
{
"id": "iss_01hxyz",
"project_id": "proj_01abc",
"org_id": "org_01abc",
"fingerprint": "fp_01hxyz",
"type": "crash",
"title": "Unhandled exception in checkout flow",
"status": "open",
"occurrence_count": 42,
"affected_user_count": 17,
"first_seen_at": 1720392000000,
"last_seen_at": 1720478390000,
"environment": "production",
"service": "checkout-api",
"created_at": 1720392000000,
"notification_count": 1
}
]
}
type is crash | error | custom. status is open | acknowledged | resolved | ignored | muted. Depending on lifecycle, an issue may also carry resolved_at/resolved_by, acknowledged_at/acknowledged_by, muted_until, notification_sent_at, and AI-generated fields (title_ai, summary_ai, ai_generated_at, ai_provider, sample_event_id, correlation_json) once populated.
GET /api/orgs/:orgSlug/projects/:projectSlug/issues/:id
Fetch a single issue by ID, scoped to the project.
Response 200 — a single issue object, same shape as one item in issues above (returned directly, not wrapped).
Errors: 404 — { "error": "Not found" }
PATCH /api/orgs/:orgSlug/projects/:projectSlug/issues/:id
Update an issue’s status.
Request body
| field | type | required | description |
|---|---|---|---|
| status | string | yes | open | acknowledged | resolved | ignored | muted |
| muted_until | number | only if status: "muted" | Epoch ms; must be in the future |
Setting status: "acknowledged" stamps acknowledged_at/acknowledged_by (from the session/API key user) and does not touch resolved_at/resolved_by. Setting status: "resolved" stamps resolved_at/resolved_by; transitioning to open or ignored clears them. Setting status: "muted" requires muted_until and stores it — the issue is automatically flipped back to open once it passes (unmute-expired cron) — and also leaves resolved_at/resolved_by untouched.
Response 200 — the updated issue object (same shape as GET .../issues/:id, returned directly).
Errors:
400—{ "error": "invalid status" }ifstatusis missing or not one of the five valid values400—{ "error": "muted_until must be a future timestamp" }ifstatus: "muted"andmuted_untilis missing or not in the future404—{ "error": "Not found" }if the issue doesn’t exist in this project
POST /api/orgs/:orgSlug/projects/:projectSlug/issues/bulk-status
Apply a status change to multiple issues at once.
Request body
| field | type | required | description |
|---|---|---|---|
| ids | string[] | yes | 1–200 issue IDs |
| status | string | yes | resolved | ignored | acknowledged |
Response 200
{ "requested": 3, "updated": 3 }
updated counts the issues that existed in the project and were changed.
Errors: 400 — { "error": "ids required" } if ids is missing or empty, { "error": "too many ids" } if more than 200, { "error": "invalid status" } if status is missing or not one of the three valid values
GET /api/orgs/:orgSlug/projects/:projectSlug/issues/:id/occurrences
List individual occurrences (raw events) that contributed to an issue.
Query params
| param | type | description |
|---|---|---|
| limit | number | Max results. Default 50, capped at 200 |
| offset | number | Pagination offset. Default 0 |
Response 200
{
"occurrences": [
{
"id": "occ_01hxyz",
"issue_id": "iss_01hxyz",
"event_id": "evt_01hxyz",
"project_id": "proj_01abc",
"user_id": "user_42",
"session_id": "sess_abc123",
"timestamp": 1720478390000,
"created_at": 1720478391000
}
]
}
Ordered by timestamp descending. Note: this endpoint does not verify the issue exists first — an unknown or mismatched :id returns 200 with an empty occurrences array rather than a 404.
Common responses (401; 402 and 429 don’t apply to these endpoints) — see Authentication.