errors
Covers 51 API operations in the errors category.
| Method | Path | Description |
|---|---|---|
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/error-releases | Observed release HTTP outcomes, adoption and deployment comparisons |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/error-releases/{version}/issues | Investigate recorded new or regressed issues in one release |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors | The issue stream: errors grouped into issues, newest activity first |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/errors-erasure | Erase captured errors for an application user ID (admin) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId} | One issue with its latest event, tag distribution and history |
| PATCH | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId} | Resolve, reopen or archive an issue |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId} | Delete captured issue data (admin) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/insights | What the project's repository says about a stored issue occurrence |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/assignee | Assign an issue to an org member, or clear it |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/comments | An issue's comments, newest first |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/comments | Comment on an issue |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/merge | Merge up to ten issues into this one |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/unmerge | Take a merged issue back out |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/similar | Shared stack hints |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors-fingerprint-rules | The project's fingerprint rules |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/errors-fingerprint-rules | Replace the project's fingerprint rules |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/events | An issue's stored events, newest first |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/events/{eventId} | One stored event in full: stack with source, breadcrumbs, request, user |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/events/{eventId}/related | Other events of this project joined to this one by request ID or browser trace ID |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/history | An issue's hourly occurrences and distinct users over the plan's retention |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/diagnoses | The issue's diagnoses, newest first (at most 20) |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/diagnoses | Ask an AI model what caused this issue (billed to the org's AI credit) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/fix-proposals | The issue's fix proposals, newest first, without their source |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/fix-proposals | Ask an AI model to propose a fix for this issue (billed to the org's AI credit; writes nothing) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/fix-proposals/{proposalId} | One fix proposal with the full proposed source |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/fix-proposals/{proposalId}/apply | Write a ready proposal as one commit on its own runlot/autofix/ branch |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors-ownership | List manual snapshot pins and eligible linked GitHub numeric IDs |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/errors-ownership/pins | Pin an individual handle to an existing linked GitHub ID for one clean snapshot |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/errors-ownership/pins/{deploymentId}/{selector} | Permanently revoke a manual snapshot pin |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors-capture-policy | Read project-admin capture, privacy and route policy |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/errors-capture-policy | Replace capture policy after explicit privacy review |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors-settings | The project's error-tracking cap and settings |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/errors-settings | Change the cap, capture switches or opt-in ownership assignment |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/browser-telemetry | Anonymous browser vital histograms and technical-fuse counters |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/feedback | Unverified feedback attached to this issue's browser errors |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors-replay-settings | The project's masked structural replay switch, cap and this month's count |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/errors-replay-settings | Turn masked structural replay on or off, or set its monthly cap |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/replays | An issue's masked structural replays, newest first (at most 50) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/replays/{replayId} | One masked structural replay and its batches |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts | getErrorAlerts |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/rules/{ruleId} | putErrorAlertRule |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/rules/{ruleId} | deleteErrorAlertRule |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/destinations/{destinationId} | putErrorAlertDestination |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/destinations/{destinationId} | deleteErrorAlertDestination |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/mail | getErrorAlertMail |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/mail | putErrorAlertMail |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/deliveries | listErrorAlertDeliveries |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/uptime-checks | List uptime checks |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/uptime-checks/{checkId} | Create or replace an uptime check |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/uptime-checks/{checkId} | Delete an uptime check |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/uptime-checks/{checkId}/runs | List an uptime check's runs |
GET /v1/orgs/{orgSlug}/projects/{projectName}/error-releases
Viewer and errors:read. Counts completed front-proxy HTTP attempts, including assets, proxy failures and closed upgrades, not native invocations, cron, DOs or in-flight work. Rates are observed-only; crash-free native request/user fields are null. Unknown, dropped or unjoined observations suppress rates. Verified organization-access subjects alone can enter the known-user subset; no event/header user claims. Receipts retain 24 hours; anonymous minute counters retain 32 days. Last 50 deployments, 24-hour view. Fifteen complete minutes after an observed switch compare with the actual predecessor at the same UTC time a day earlier. At least 200 requests/window and complete observed source coverage are required. Insight is not causal proof and never triggers rollback.
operationId getReleaseHealth
| Status code | Description | Response body |
|---|---|---|
| 200 | Observed release outcomes with explicit population and coverage | ReleaseHealthSummary |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/error-releases/{version}/issues
Viewer and errors:read. One row per recorded issue and kind, choosing its earliest transition in the closed window (event ID breaks timestamp ties), ordered by that timestamp then issue ID descending. Pass the release summary's windowStart/windowEnd to investigate its distinct-issue counts. Current status is not a historical filter: an issue resolved later remains in its recorded release. Browser events are excluded. Pages contain at most 50 issues. Cursor is bound to project, version, kind and window. A fixed window is not a frozen database snapshot: late delivery, erasure and the existing 32-day transition retention can change membership between reads. Refresh to reconcile. Retained transitions survive missing issue/event bodies. Labels describe only surviving current issues; issueAvailable=false omits them. eventAvailable requires a surviving issue and the exact event still belonging to that issue with a stored body. Missing, moved or bodyless events never fall back to latest, another issue or release. This read does not capture events, change settings or extend retention.
operationId listReleaseIssues
| Parameter | Location | Required | Type | Description |
|---|---|---|---|---|
undefined | undefined | No | — | — |
undefined | undefined | No | — | — |
undefined | undefined | No | — | — |
undefined | undefined | No | — | — |
| Status code | Description | Response body |
|---|---|---|
| 200 | Historical transition rows with explicit target availability | ReleaseIssuePage |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors
Issues group error events by fingerprint (docs/customer-error-tracking.md §6). Events
come from three origins: platform (out of memory, crashes, boot and build failures,
failed cron runs, requests the platform answered because the app could not), app
(what the project's code threw or reported), and browser.
Event bodies are kept for keepDays; issues and their counts outlive them.
operationId listErrorIssues
| Parameter | Location | Required | Type | Description |
|---|---|---|---|---|
status | query | No | string | — |
query | query | No | string | Free text (a case-insensitive substring of the title or culprit, or a short ID such as ERR-1A) with up to 20 filters: is:unresolved|resolved|archived|new|regressed|escalating, release:latest|<n>, origin:platform|app|browser, route:<glob> (* matches any run), tag.<key>:<value>, has:replay, and user.email:<pattern>. A token whose key is not one of these is text, so a pasted TypeError: x searches for that text. When the query names a state and status is omitted, the default unresolved is not added. Replay presence and email predicates require a current admin role and errors:pii; ordinary issue fields remain redacted. Email patterns are case-insensitive, at most 320 UTF-8 bytes, with only * as a wildcard. Email search returns 400 while structured email retention is off. Combined email, route, tag, release and replay conditions must match the same stored occurrence. Sensitive email query values are redacted from operator request telemetry. Merged sources are left out unless searched by their short ID. |
cursor | query | No | string | — |
limit | query | No | integer | — |
| Status code | Description | Response body |
|---|---|---|
| 200 | One page of issues | ErrorIssuePage |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/errors-erasure
The user ID is exact and project-scoped, in the body so it stays out of URL logs. Removes their event bodies and linked replays, and conservatively clears all AI outputs in this project because their user attribution can outlive an event. Anonymous occurrence, trend and billing counters remain; affected summaries are cleared. Queued old reports cannot restore the data. Future occurrences after the erasure cut-off can be captured. Does not rewrite repository history or recall data already sent to an explicitly requested AI provider. A token needs org:admin.
operationId eraseErrorUser
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | Erasure completed; aggregate counts preserved | ErrorErasureResult |
| 400 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}
One issue with its latest event, tag distribution and history
operationId getErrorIssue
| Parameter | Location | Required | Type | Description |
|---|---|---|---|---|
includePII | query | No | boolean | Explicit sensitive read. Requires current admin role and errors:pii. Ordinary reads always redact retained structured email. |
| Status code | Description | Response body |
|---|---|---|
| 200 | The issue | ErrorIssueDetail |
| 403 | — | — |
| 404 | — | — |
PATCH /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}
resolved with resolveIn: next_release resolves the issue when the next deployment
goes live; an event from an older release does not reopen it. archived with
archiveUntil: escalating (the default) brings the issue back when its hourly count
rises well above its baseline; a duration such as 24h brings it back after that.
Needs the member role.
operationId updateErrorIssue
Request body: application/json · ErrorIssueUpdate
| Status code | Description | Response body |
|---|---|---|
| 200 | The issue after the change | ErrorIssue |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}
Deletes the issue, events, linked replay blobs and derived AI outputs. Requires admin; a token needs org:admin. Unmerge the issue and its merged sources first (409 unmerge_required); no merged source is silently cascaded. Anonymous monthly usage remains. Retries are idempotent; old queued occurrences cannot restore erased data, while a new occurrence after deletion may create a new issue.
operationId deleteErrorIssue
| Status code | Description | Response body |
|---|---|---|
| 200 | Erasure completed | ErrorErasureResult |
| 403 | — | — |
| 404 | — | — |
| 409 | Unmerge required; no data deleted | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/insights
Source lines, suspect commits and CODEOWNERS read at the stored event's deployment commit (docs/customer-error-tracking.md §8–§9). Without eventId, selects the newest stored event body for backward compatibility. An explicit eventId selects only a currently matching project/issue row with a stored body; missing, foreign, erased, bodyless or moved events return 404, never latest. Release, commit and repository come from stored platform records, not query hints. A readable event without usable Git returns 200 with available=false and a reason. The response eventId echoes the actual row even for unavailable Git answers; clients using explicit selection must verify it matches, including on older CPs. Commit authors are unverified claims; email is returned only for one verified org member. CODEOWNERS handles grant nothing. Viewer/errors:read is unchanged.
operationId getErrorInsights
| Parameter | Location | Required | Type | Description |
|---|---|---|---|---|
eventId | query | No | string | One exact stored event ID, with the same opaque-string semantics as the event read. Empty or duplicate values are invalid; omission alone means newest. |
| Status code | Description | Response body |
|---|---|---|
| 200 | The selected insight, or why that event has no usable Git context | ErrorInsights |
| 400 | Invalid or duplicate eventId | — |
| 403 | — | — |
| 404 | — | — |
| 503 | Current core does not confirm the requested occurrence; no latest result substituted | — |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/assignee
Member. userId must be a member of the project's org (422 not_a_member otherwise); null clears.
An assignment is a label for triage and grants nothing. A merged source is 409 issue_merged.
operationId assignErrorIssue
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | OK | ErrorIssue |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 409 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/comments
Viewer.
operationId listErrorComments
| Status code | Description | Response body |
|---|---|---|
| 200 | OK | ErrorCommentPage |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/comments
Member. Plain text, at most 4000 characters, scrubbed of secrets (tokens, keys, card numbers, email addresses) before it is stored. The author is the session's user; a body field naming another is refused.
operationId addErrorComment
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 201 | OK | ErrorComment |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 409 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/merge
Member. Sources must be unmerged issues of this project with the same origin as the target
(409 origin_mismatch / issue_merged). Their events move to the target with their own
fingerprint and weight, their future events route to the target, and the target's counts,
trend, user count and newest event are recomputed. Each source keeps its row, state, comments
and activity with mergedInto set, and leaves the default stream. Monthly usage is not touched.
operationId mergeErrorIssues
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | OK | ErrorIssue |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 409 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/unmerge
Member. The issue in the path must be a merged source. Its fingerprints (and those of issues merged into it earlier) route to it again; their events, including ones that arrived after the merge, move back; both issues are recomputed. The source's own state was never changed by the merge.
operationId unmergeErrorIssue
| Status code | Description | Response body |
|---|---|---|
| 200 | OK | ErrorIssue |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 409 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/similar
Viewer. Issues among the project's 200 most recently seen whose newest stored stack shares in-app frames with this one's (Jaccard over module|function, a small bonus for the same type). A hint for a person deciding whether to merge: nothing is merged, no model is called, and the score is not a claim that the issues share a cause.
operationId similarErrorIssues
| Status code | Description | Response body |
|---|---|---|
| 200 | OK | ErrorSimilar |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors-fingerprint-rules
The project's fingerprint rules
operationId getErrorFingerprintRules
| Status code | Description | Response body |
|---|---|---|
| 200 | OK | ErrorFingerprintRules |
| 403 | — | — |
| 404 | — | — |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/errors-fingerprint-rules
Member. At most 100 rules; matchers are RE2 patterns of at most 1000 bytes. The first rule
whose matchers all match an app or browser event sets its fingerprint (and optionally the
issue's title, shown as titleCustom). Platform events are never matched and an event's
origin never changes. Applies to events received from now on.
operationId putErrorFingerprintRules
Request body: application/json · ErrorFingerprintRules
| Status code | Description | Response body |
|---|---|---|
| 200 | OK | ErrorFingerprintRules |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/events
An issue's stored events, newest first
operationId listErrorEvents
| Parameter | Location | Required | Type | Description |
|---|---|---|---|---|
cursor | query | No | string | — |
limit | query | No | integer | — |
| Status code | Description | Response body |
|---|---|---|
| 200 | One page of events | ErrorEventPage |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/events/{eventId}
One stored event in full: stack with source, breadcrumbs, request, user
operationId getErrorEvent
| Parameter | Location | Required | Type | Description |
|---|---|---|---|---|
includePII | query | No | boolean | Explicit sensitive read. Requires current admin role and errors:pii. Ordinary reads always redact retained structured email. |
| Status code | Description | Response body |
|---|---|---|
| 200 | The event | ErrorEvent |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/events/{eventId}/related
The browser agent puts a W3C traceparent on same-origin fetch/XHR and records the
trace ID on that call's breadcrumb; the server event of the request that carried it
is tagged trace_id. Front's request ID joins a browser event to the server request
that rendered its page. Both are correlation keys only: issues are never merged and
no identity moves between events. At most 50, within 24 hours of the event.
operationId getRelatedErrorEvents
| Status code | Description | Response body |
|---|---|---|
| 200 | Joined events, oldest first | RelatedErrorEvents |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/history
Read from the ClickHouse event history (docs/customer-error-tracking.md §18).
Where no history store is configured (on-prem without ClickHouse) the answer is
available: false with no points; the issue's 24-hour trend still comes from the issue.
operationId getErrorHistory
| Parameter | Location | Required | Type | Description |
|---|---|---|---|---|
days | query | No | integer | Window in days, at most the plan's event retention (the default). |
| Status code | Description | Response body |
|---|---|---|
| 200 | The history | ErrorHistory |
| 403 | — | — |
| 404 | — | — |
| 503 | history_unavailable — the history store did not answer | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/diagnoses
The issue's diagnoses, newest first (at most 20)
operationId listErrorDiagnoses
| Status code | Description | Response body |
|---|---|---|
| 200 | The diagnoses | object |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/diagnoses
Runs one diagnosis of the issue on the model you name: the newest stored event, its stack with source lines, the same request's breadcrumbs and the release it came from are given to the model as data, and the answer lists likely causes, each with the frames or breadcrumbs it rests on, a suggested fix and a confidence. You cannot add your own prompt.
It runs only when you ask — nothing diagnoses an issue on its own. It is charged to the
organization's AI credit like a call from runlot dev and appears in the AI ledger under the
development lane. Request headers and the user are not sent to the model.
idempotencyKey (or the Idempotency-Key header) is required: sending the same key again returns
the stored answer and is not charged again. A key whose first request is still running answers
409 diagnosis_in_progress. Requires member or higher; a token needs org:admin.
operationId diagnoseErrorIssue
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | The diagnosis, or the stored one for a repeated key (replayed: true) | ErrorDiagnosis |
| 400 | — | — |
| 402 | no_credit or insufficient_credit — the organization's AI credit does not cover the call | Error |
| 403 | — | — |
| 404 | — | — |
| 409 | diagnosis_in_progress — a request with this key is still running; idempotency_key_reused — the key belongs to another issue | Error |
| 429 | rate_limited or too_many_concurrent — the project's development lane allows 30 calls a minute and two at a time | Error |
| 503 | ai_unavailable or model_unavailable — this installation cannot call that model | Error |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/fix-proposals
Requires member or higher; a token needs org:admin — a proposal is repository content.
operationId listErrorFixProposals
| Status code | Description | Response body |
|---|---|---|
| 200 | The proposals | object |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/fix-proposals
One model call that reads the source files the issue's newest stored event actually ran through — its symbolicated in-app frames, at most three existing source files — at the commit of the deployment it came from, and returns whole new contents for some of them. Nothing is written: the proposal is stored and can be applied separately.
You choose only the model. The repository (the one the deployment was built from, or the project's
only one), the base commit and the files are chosen by Runlot, and the model may only rewrite those
files — a proposal that names any other path, a configuration file or a new file fails. The
deployment must be the one serving now and come from a clean, full commit. A file that looks like it
contains a credential or personal data is refused rather than sent to the model (422 source_has_secrets). Request headers and the user are not sent.
A truncated or malformed answer is a failed proposal whose usage and charge are still shown.
idempotencyKey (or the Idempotency-Key header) is required; the same key returns the stored
proposal and is not charged again. Requires member or higher; a token needs org:admin.
operationId proposeErrorFix
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | The proposal — ready, or failed with errorCode after a paid call | ErrorFixProposal |
| 400 | — | — |
| 402 | no_credit / insufficient_credit | Error |
| 403 | — | — |
| 404 | — | — |
| 409 | Nothing to propose against: stale_source (the deployment serving now is not the event's), no_event, no_release, no_commit, commit_not_full, dirty_tree, no_repo, ambiguous_repo, no_eligible_files, repo_empty; or proposal_in_progress. | Error |
| 422 | source_has_secrets, or a frame's file is not an editable text source | Error |
| 503 | ai_unavailable / model_unavailable / git_unavailable | Error |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/fix-proposals/{proposalId}
Requires member or higher; a token needs org:admin.
operationId getErrorFixProposal
| Status code | Description | Response body |
|---|---|---|
| 200 | The proposal | ErrorFixProposal |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/fix-proposals/{proposalId}/apply
Writes the proposal's exact change as one commit on runlot/autofix/<proposal>, parented on its base
commit. It does not build, preview, deploy, merge, push anywhere or touch the default branch; the
branch is for you to review. proposalSha must be the proposal's exactly and
acknowledgeUnreviewedCode true. The deployment serving now must still be the base commit and every
file must still have the bytes the proposal was made from, or it is 409 stale_source — propose
again. A proposal can be applied for 7 days. Sending it again returns the same branch and commit.
Requires member or higher; a token needs org:admin.
operationId applyErrorFix
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | The branch and commit | ErrorFixApplyResult |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 409 | proposal_mismatch, proposal_not_ready, proposal_expired, stale_source, branch_conflict | Error |
| 503 | git_unavailable | Error |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors-ownership
Project admin and org:admin only, private/no-store. No emails or provider calls. Labels are not identity evidence. At most 200 linked identities, 50 clean exact snapshots and 500 pins; explicit truncation flags indicate incomplete lists. This is manual policy, not verified current GitHub handle discovery.
operationId getErrorOwnership
| Status code | Description | Response body |
|---|---|---|
| 200 | Bounded admin-only ownership policy inventory | ErrorOwnershipPolicy |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/errors-ownership/pins
Project admin and org:admin only. 8 KiB body. Explicit manual acknowledgement required. Never creates or links identities. One immutable pin per deployment and normalized individual selector; team selectors unsupported. Identical active pins are idempotent, conflicts and revoked pins return 409. Technical limit: 500 pin slots/project including revoked or removed mappings, not a plan quota. No access, membership, quota or delivery rights are granted; automatic assignment stays off.
operationId createErrorOwnershipPin
Request body: application/json · ErrorOwnershipPinInput
| Status code | Description | Response body |
|---|---|---|
| 201 | Immutable manual pin, including an identical active existing pin | ErrorOwnershipPin |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 409 | ownership_pin_conflict, ownership_pin_ineligible or ownership_pin_limit | — |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/errors-ownership/pins/{deploymentId}/{selector}
Project admin and org:admin only. Cannot restore or retarget it. Does not reroute existing issues or alerts.
operationId revokeErrorOwnershipPin
| Status code | Description | Response body |
|---|---|---|
| 204 | Revoked (idempotent) | — |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors-capture-policy
Admin/org:admin only. Filtered attempts contain no event content, count retries, and do not consume event quotas.
operationId getErrorCapturePolicy
| Status code | Description | Response body |
|---|---|---|
| 200 | Current policy and preceding 24-hour filtered attempt counts | ErrorCapturePolicyView |
| 403 | — | — |
| 404 | — | — |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/errors-capture-policy
Admin/org:admin only. This replaces the entire policy; omitted retainFeedbackEmail defaults to false. RE2 patterns are bounded to 20 per kind, 512 bytes each. Route globs are absolute paths, with only * special (50 max, 256 bytes each). Changes reach collectors without app wake or redeployment. Platform events bypass inbound filters, regardless of exception names. retainUserEmail and retainFeedbackEmail are independent, default-off retention options. Either enabled option requires acknowledgePII true. retainUserEmail stores structured event user.email only; retainFeedbackEmail stores the optional unverified email explicitly supplied with browser feedback, not an account identity. Ordinary reads omit feedback email and redact event email. Explicit sensitive reads need admin plus errors:pii. Disabling either option deletes that kind of retained email. Emails are not used for authentication, AI prompts, ownership, metrics or health; Runlot does not send mail to feedback addresses.
operationId putErrorCapturePolicy
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | Stored policy | ErrorCapturePolicyView |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors-settings
The project's error-tracking cap and settings
operationId getErrorSettings
| Status code | Description | Response body |
|---|---|---|
| 200 | The settings | ErrorSettings |
| 403 | — | — |
| 404 | — | — |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/errors-settings
Omitted fields preserve existing settings. autoAssign defaults to false and
only assigns newly created, unassigned issues from the exact clean Git snapshot.
It never overwrites manual assignment or grants membership or alert privileges.
monthlyCap null returns to the plan's included amount; a number sets a cap; -1
removes it. browserEnabled is optional: absent leaves the browser switch as it
is, false turns the browser agent off on any plan, true needs Pro. Raising the cap above the included amount or removing it needs Pro
(403 plan_required). Lowering it is allowed on every plan. Platform events
(out of memory, crashes, boot and build failures) are never capped. Needs the admin
role.
operationId putErrorSettings
Request body: application/json · ErrorSettingsUpdate
| Status code | Description | Response body |
|---|---|---|
| 200 | The settings after the change | ErrorSettings |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/browser-telemetry
Viewer/errors:read. Browser values are untrusted claims, not platform measurements, request counts, session health or billing. Four fixed histograms/hour, no URLs or DOM attribution. Percentiles are bucket ranges only. Technical limits are not a commercial allowance; nothing is charged. droppedAttempts counts CP refusals and may include retries; front queue/rate refusals are separate operator metrics. At most one vital report/page token.
operationId getBrowserTelemetry
| Status code | Description | Response body |
|---|---|---|
| 200 | Current UTC hour and preceding 167 histogram buckets; seven UTC calendar-day counters | BrowserTelemetrySummary |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/feedback
Viewer/errors:read for ordinary replies, which omit email. Feedback messages are scrubbed and never an org-member comment. includePII=true additionally requires admin plus errors:pii; only then may email appear when retainFeedbackEmail is enabled and an email was explicitly supplied. The optional feedback email is unverified, not an account identity, and Runlot sends no mail to it. verified remains false. Only the same project, rendering request and release may attach feedback to a browser error. Pending anchors are invisible, expire after ten minutes and have a 64/project fuse. Event erasure cascades attached feedback; erasure clears all pending messages for the project.
operationId listBrowserFeedback
| Parameter | Location | Required | Type | Description |
|---|---|---|---|---|
includePII | query | No | boolean | Explicit sensitive read; requires admin plus errors:pii. Ordinary replies omit email. |
| Status code | Description | Response body |
|---|---|---|
| 200 | Up to 100 attached messages, newest first | BrowserFeedbackList |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors-replay-settings
Session replay here is a masked structural replay, not a pixel recording: on a Pro
project's pages the browser agent keeps the last 20 seconds of the page's structure —
element boxes, a few layout and colour numbers, and the constant [masked] in place of
every text and form value — and sends it only when a browser error is captured. Nothing
is recorded on pages without an error, under Global Privacy Control, or after the site
denies consent.
effective is whether the recorder is offered now: the plan supports it, the browser
agent (errors-settings browserEnabled) and replay are on, and the cap is not 0.
usedMonth counts complete replays this month; billableMonth counts those past the
included amount. No price is set (pricing: open) and nothing is charged. Requires
viewer or higher.
operationId getErrorReplaySettings
| Status code | Description | Response body |
|---|---|---|
| 200 | The settings | ErrorReplaySettings |
| 403 | — | — |
| 404 | — | — |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/errors-replay-settings
Both fields are required. monthlyCap null is the plan's included amount (Pro: 5,000 a
month), 0 stops collection, a lower number is allowed on every plan, and -1 (no cap)
or a number above the included amount needs Pro (403 plan_required). enabled: true
needs Pro. Turning the browser agent off in errors-settings turns replay off as well.
A change reaches pages at the next routing-map refresh, with no deploy. Needs the admin
role.
operationId putErrorReplaySettings
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | The settings after the change | ErrorReplaySettings |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/replays
Only complete replays are listed: every batch stored and re-validated, and anchored on
a stored browser error event of this issue from the same page view and release. A replay
is kept for the plan's event retention (Pro: 90 days). Needs the admin role until a
granular personal-data scope exists; a token needs org:admin.
operationId listErrorReplays
| Status code | Description | Response body |
|---|---|---|
| 200 | The replays | object |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/errors/{issueId}/replays/{replayId}
The batches are re-read from storage and re-validated on every request; a replay that
does not pass is answered 404 replay_unavailable rather than shown. Each batch is data
for the replay player (tags from a fixed list, rectangles, style numbers, [masked]
text) and never markup. Needs the admin role; a token needs org:admin.
operationId getErrorReplay
| Status code | Description | Response body |
|---|---|---|
| 200 | The replay | object |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts
Viewer reads; admin configuration writes. External destinations are disabled until explicitly enabled with disclosure acknowledgement. Secret values are write-only. Enabling custom rules replaces this project's default issue mail routing; no enabled rules preserves the default. Counts are prospective received-time minute buckets; deliveries are at-least-once externally.
operationId getErrorAlerts
| Status code | Description | Response body |
|---|---|---|
| 200 | Result | ErrorAlertConfig |
| 400 | Request refused | — |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/rules/{ruleId}
Viewer reads; admin configuration writes. External destinations are disabled until explicitly enabled with disclosure acknowledgement. Secret values are write-only. Enabling custom rules replaces this project's default issue mail routing; no enabled rules preserves the default. Counts are prospective received-time minute buckets; deliveries are at-least-once externally.
operationId putErrorAlertRule
Request body: application/json · ErrorAlertRule
| Status code | Description | Response body |
|---|---|---|
| 200 | Result | ErrorAlertRule |
| 400 | Request refused | — |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/rules/{ruleId}
Viewer reads; admin configuration writes. External destinations are disabled until explicitly enabled with disclosure acknowledgement. Secret values are write-only. Enabling custom rules replaces this project's default issue mail routing; no enabled rules preserves the default. Counts are prospective received-time minute buckets; deliveries are at-least-once externally.
operationId deleteErrorAlertRule
| Status code | Description | Response body |
|---|---|---|
| 204 | Removed | — |
| 400 | Request refused | — |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/destinations/{destinationId}
Viewer reads; admin configuration writes. External destinations are disabled until explicitly enabled with disclosure acknowledgement. Secret values are write-only. Enabling custom rules replaces this project's default issue mail routing; no enabled rules preserves the default. Counts are prospective received-time minute buckets; deliveries are at-least-once externally.
operationId putErrorAlertDestination
Request body: application/json · ErrorAlertDestinationInput
| Status code | Description | Response body |
|---|---|---|
| 200 | Result | ErrorAlertDestination |
| 400 | Request refused | — |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/destinations/{destinationId}
Viewer reads; admin configuration writes. External destinations are disabled until explicitly enabled with disclosure acknowledgement. Secret values are write-only. Enabling custom rules replaces this project's default issue mail routing; no enabled rules preserves the default. Counts are prospective received-time minute buckets; deliveries are at-least-once externally.
operationId deleteErrorAlertDestination
| Status code | Description | Response body |
|---|---|---|
| 204 | Removed | — |
| 400 | Request refused | — |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/mail
Viewer reads; admin configuration writes. External destinations are disabled until explicitly enabled with disclosure acknowledgement. Secret values are write-only. Enabling custom rules replaces this project's default issue mail routing; no enabled rules preserves the default. Counts are prospective received-time minute buckets; deliveries are at-least-once externally.
operationId getErrorAlertMail
| Status code | Description | Response body |
|---|---|---|
| 200 | Result | ErrorAlertMailPreference |
| 400 | Request refused | — |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/mail
Viewer reads; admin configuration writes. External destinations are disabled until explicitly enabled with disclosure acknowledgement. Secret values are write-only. Enabling custom rules replaces this project's default issue mail routing; no enabled rules preserves the default. Counts are prospective received-time minute buckets; deliveries are at-least-once externally.
operationId putErrorAlertMail
Request body: application/json · ErrorAlertMailPreference
| Status code | Description | Response body |
|---|---|---|
| 200 | Result | ErrorAlertMailPreference |
| 400 | Request refused | — |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/error-alerts/deliveries
Viewer reads; admin configuration writes. External destinations are disabled until explicitly enabled with disclosure acknowledgement. Secret values are write-only. Enabling custom rules replaces this project's default issue mail routing; no enabled rules preserves the default. Counts are prospective received-time minute buckets; deliveries are at-least-once externally.
operationId listErrorAlertDeliveries
| Status code | Description | Response body |
|---|---|---|
| 200 | Result | ErrorAlertDeliveryList |
| 400 | Request refused | — |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/uptime-checks
The project's synthetic HTTP checks with their current state and last run. Each check calls one of the project's own addresses from the control plane every 1, 5 or 15 minutes and wakes the app. Two failures in a row open one CheckFailed issue; the next success resolves it. Viewer.
operationId listUptimeChecks
| Status code | Description | Response body |
|---|---|---|
| 200 | Checks | UptimeCheckList |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/uptime-checks/{checkId}
The URL must be https on port 443 and its host one of this project's active addresses. Free allows 1 check per project, Pro 20 (402 uptime_check_limit past it). Admin.
operationId putUptimeCheck
Request body: application/json · UptimeCheckInput
| Status code | Description | Response body |
|---|---|---|
| 200 | The stored check | UptimeCheck |
| 400 | Request refused | — |
| 401 | Request refused | — |
| 402 | The plan's uptime check limit is reached | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
| 409 | The check ID belongs to another project | — |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/uptime-checks/{checkId}
Removes the check and its run history. An open CheckFailed issue stays as it is. Admin.
operationId deleteUptimeCheck
| Status code | Description | Response body |
|---|---|---|
| 204 | Deleted | — |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/uptime-checks/{checkId}/runs
Newest first, the last seven days. Viewer.
operationId listUptimeRuns
| Status code | Description | Response body |
|---|---|---|
| 200 | Runs | UptimeRunList |
| 401 | Request refused | — |
| 403 | Request refused | — |
| 404 | Request refused | — |