Error tracking
Module: errors. See README.md for authentication and pagination.
Endpoints
| Endpoint | Scope | Permission | What it does |
|---|---|---|---|
GET /apps/{app}/errors |
read | errors.read |
List issues |
GET /apps/{app}/errors/overview |
read | errors.read |
Counts and the noisiest issues in a range |
GET /apps/{app}/errors/{issueId} |
read | errors.read |
One issue in full |
PATCH /apps/{app}/errors/{issueId} |
write | errors.write |
Resolve, ignore or reopen |
GET /apps/{app}/errors/{issueId}/events |
read | errors.read |
Occurrences, newest first |
GET /apps/{app}/errors/{issueId}/events/{eventId} |
read | errors.read |
One occurrence in full |
An issue is a group of occurrences sharing a fingerprint: an explicit
fingerprint[] from the SDK, or the error name plus the top three in-app stack
frames with line numbers stripped and the message masked for numbers, UUIDs and
hex. Issues are scoped to one environment.
List
?status=open|regressed|resolved|ignored|all (default open)
?q=&release=&sort=last_seen|count|users|first_seen&limit=50&cursor=&env=
{
"data": [{
"id": "i_1",
"fingerprint": "…",
"title": "TypeError: Cannot read properties of undefined (reading 'total')",
"culprit": "renderSummary (/srv/app/checkout.ts)",
"level": "error",
"status": "open",
"firstSeenAt": "2026-08-30T…",
"lastSeenAt": "2026-09-03T…",
"eventCount": 412,
"userCount": 88,
"releaseFirst": "web@1.3.9",
"releaseLast": "web@1.4.0",
"spark": [3, 9, 22, 40, 91, 130, 117]
}],
"nextCursor": "…"
}
spark is the last seven days, which is what separates a new problem from a
long-standing one at a glance.
One issue
Adds daily (events and users per day), releases, tags and the assignee.
Follow with /events for individual occurrences, and
/events/{eventId} for one of them in full.
One occurrence
GET /apps/{app}/errors/{issueId}/events/{eventId}?env=
/events answers summaries — enough to pick one. This endpoint is the whole
occurrence: what an agent needs to explain a crash without opening the console.
{
"id": "ev_1",
"issueId": "i_1",
"ts": "2026-09-03T09:12:44.117Z",
"level": "error",
"name": "TypeError",
"message": "Cannot read properties of undefined (reading 'total')",
"culprit": "renderSummary (/srv/app/checkout.ts)",
"handled": false,
"mechanism": "onerror",
"release": "web@1.4.0",
"stack": "TypeError: …",
"frames": [
{ "file": "/srv/app/checkout.ts", "function": "renderSummary", "line": 12, "column": 4, "inApp": true }
],
"breadcrumbs": [
{ "timestamp": "2026-09-03T09:12:43.900Z", "category": "navigation", "message": "/checkout" }
],
"tags": { "plan": "pro" },
"extra": { "cartId": "c_9" },
"request": { "method": "GET", "url": "https://app.test/checkout", "status": 500 },
"url": "https://app.test/checkout",
"path": "/checkout",
"referrer": null,
"personId": "p_1",
"sessionId": "s_1",
"distinctId": "user_123",
"anonymousId": "…",
"browser": "Chrome",
"browserVersion": "141",
"os": "macOS",
"device": "desktop",
"country": "FR",
"region": null,
"city": null,
"locale": "fr-FR",
"appVersion": "1.4.0"
}
The event has to belong to the issue in the path: an id that exists under
another issue — or in another application or environment — answers 404, the
same as one that does not exist at all.
Over MCP this is get_error with an eventId argument; without it the same
tool returns the issue summary.
Status changes
PATCH /apps/{app}/errors/{issueId}
{ "status": "resolved", "assigneeId": "u_1" }
Resolving clears the notification cooldown, so the next occurrence is reported as a regression immediately rather than waiting out the window. The response records the transition:
{ "id": "i_1", "title": "…", "previousStatus": "open", "status": "resolved" }
Status changes need a token bound to a user — an organization token minted by a member works, because the member is who the change is attributed to.
Overview
?range=24h|7d|14d|30d|90d (default 7d)
Total events, distinct issues and affected users for the range with the previous window for comparison, a daily series, the count of issues first seen in the range, and the noisiest issues.