Sentry API sandbox

Sentry

Point a Sentry API client at https://sentry.sandboxapis.dev. Paths are /api/0/…, exactly like sentry.io. sentry-cli takes --url (or SENTRY_URL); the official sentry-mcp server takes --host / SENTRY_HOST. Auth is a Bearer token (any value is accepted here). This is the org's ERROR TRACKING surface: projects are the services the org deploys, issues are deduplicated error signatures, and an event's stack frames name REAL files at REAL commit shas: take a frame's filename and lineNo here and fetch the same file at the same sha from the git host, and the source lines match. The incident the trackers and chat hosts discuss is the same incident firing here.

REST · 95 endpointsMCP-ready

Coverage badge

Full95/95 · 100%

The share of read rows with a final answer — served and verified, a deviation, retired upstream, or a reviewed empty/refusal. Computed in the coverage manifest, copied here.

Live host
sentry.sandboxapis.dev
Pinned hosts
6 — generation 7, 8, 9, 10, 11, 12
Serving since
2026-09-01
Lifecycle
Live

Served & verified

75 / 79%

Answering with real universe data, each response checked against Sentry's published spec by the conformance suite on this build.

The full read API

95

Every read surface Sentry publishes, deferred long tail included, minus the rows excluded by policy. Writes are out of scope: this universe is read-only.

Not served yet

15

Each returns an explicit, provider-shaped coverage error naming the gap — never invented data. 5 endpoints were retired by Sentry itself and are served only on snapshots pinned before that date — not a gap on our side.

01 / The swap

Point your client at a different base URL.

No SDK of ours, no shim, no recorded fixtures. The same client library you already use, one environment variable different.

shell
curl -H 'Authorization: Bearer anything' "https://sentry.sandboxapis.dev/api/0/organizations/olympus-labs/projects/"

Verified drop-in clients

No client library is version-pinned against Sentry yet, so this page claims none. What is asserted is the wire: every response above is validated against Sentry's own published spec by the conformance suite. Client pins live in coverage/client-pins.yaml and are added as each SDK joins the suite.

02 / Coverage by family

Every read surface, grouped the way Sentry groups it.

All 95 rows the coverage manifest carries for Sentry, deferred long tail included and nothing capped. Open a family, or filter by path to find the exact endpoint your client calls.

Status — what a conformance test found

served & verified
answers with real universe data, and this build checked that response against the vendor's spec.
deviation
served and faithful to the real provider, but failing the vendored spec — usually a bug in the spec.
retired
the vendor removed the endpoint; snapshots pinned before that date still serve it.
planned / deferred
not served yet — an explicit coverage error naming the gap, never invented data.
excluded
out of the claim by policy (writes, and surfaces we refuse); not in any denominator on this page.

Mode — what kind of answer a row gets

derive
the response is computed from artifact rows that already exist
generate
canon does not carry this yet; the generator will produce it, then derive
empty
the true answer for this universe is an empty collection — reason + reviewed date required
refuse
mirror the provider's OWN refusal (e.g. its 403 for a non-admin token) — reason + reviewed date required
read-only
a write named in the manifest because clients probe it; the read-only 403 IS its final response, and it never joins the badge denominator
scratch
a write this replica ACCEPTS, into a per-key 24-hour overlay, answering with the provider's own success shape - reason + reviewed date required. The compiled artifact is unchanged and no other caller ever sees the row; a caller WITHOUT a scratch-enabled key gets the read-only refusal on the identical path. Like read-only it never joins the badge denominator (founder ruling 5, 2026-09-17: the published figure has meant READ operations served since A0.1), and unlike read-only it ANSWERS, so the generation report counts it in its own `scratch` column rather than in (excluded). Scratch never creates a pull request, a branch, a commit or a diff - those are canon structure the overlay cannot invent

A row with no mode shown has not been judged yet. Modes are the manifest's own words, from coverage/MODES.yaml; every empty and refuse carries a written reason and a review date before it counts as final.

Badge — where Full starts

Full
every published read row has a final answer
Deep
60% up to 100%
Partial
25% up to 60%
Preview
under 25%

REST + GraphQL + git rows that are not `excluded`. Write operations are NOT rows (DECISIONS 2026-09-01 decision 9): they are counted in meta.write_operations and never enter this ratio.

95 read surfaces in 13 families

issues17 of 17 served & verified
GET
/api/0/issues/{issue_id}/

SERVED 2026-10-23 (the Sentry tail): the address the pinned build (sentry-api-schema@9c036700) documents for the issue detail, with no organization in the path. The handler is the one the organization-scoped form has used since B1.1, so the two addresses answer one issue one way, and conformance asserts the bodies byte-identical; the organization is the one this universe has

served & verified
Core
GET
/api/0/issues/{issue_id}/events/

SERVED 2026-10-23 (the Sentry tail): the issue's sampled error events at the pinned build's organization-less address, the same handler and the same Link-header pagination as the organization-scoped list, walked to its last page in conformance

served & verified
Core
GET
/api/0/issues/{issue_id}/events/{event_id}/

SERVED 2026-10-23 (the Sentry tail): `latest` and `oldest` are the events the organization-scoped routes already serve, and an event id is the event the project-scoped read serves. `recommended` is DERIVED, not chosen: Sentry ranks a group's events by replay, profile, processing errors and trace before the timestamp and falls back to the latest (src/sentry/models/group.py at getsentry/sentry@44db45d9, the build's source commit), and no event here carries any of the four, which the project object already states as hasReplays and hasProfiles false. So the recommended event is the latest one, and conformance asserts that premise rather than the conclusion alone

served & verified
Core
GET
/api/0/issues/{issue_id}/hashes/

SERVED 2026-10-23 (the Sentry tail): the one grouping hash of a canonical group and its newest event, the organization-scoped handler at the pinned build's address

served & verified
Core
GET
/api/0/issues/{issue_id}/tags/{key}/

SERVED 2026-10-23 (the Sentry tail): the tag fold over the group's own events (level, server_name, environment and release, each a canonical fact), the organization-scoped handler at the pinned build's address

served & verified
Core
GET
/api/0/issues/{issue_id}/tags/{key}/values/

SERVED 2026-10-23 (the Sentry tail): the de-duplicated values the group's events carry for one key, the organization-scoped handler at the pinned build's address

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/issues/{issue_id}/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/issues/{issue_id}/events/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/issues/{issue_id}/events/latest/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/issues/{issue_id}/events/oldest/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/issues/{issue_id}/hashes/

SERVED 2026-09-12: a grouping hash is a digest of the SIGNATURE events were grouped on, and canon's signature is the pair the generator deduplicated by (the exception type and the culprit path) - so a canonical ErrorGroup has exactly one hash, derived by ids.ts's existing hex derivation. `latestEvent` is the group's newest shaped event, the same one events/latest/ serves

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/issues/{issue_id}/tags/{key}/

SERVED 2026-09-12: eventTags() already computes the whole tag vocabulary per event from canon (level, server_name, environment, release), so `totalValues` is a count over the group's own events. A key no event of the group carries is Sentry's own 404 - a tag key exists because events have it

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/issues/{issue_id}/tags/{key}/values/

SERVED 2026-09-12: the same per-event tag list eventTags() computes, de-duplicated over the group's events and sorted. No field outside eventTags is required

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/events/
served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/events/{event_id}/
served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/events/{event_id}/source-map-debug/

no event in this universe has a minified frame to unminify - the served project object says so (SURFACE_FLAGS.hasMinifiedStackTrace=false, render.ts:166) and every error_frame (51) resolves to a real file in the repository tree at the group's resolved_sha, with the real source lines served as the frame's `context`; Sentry's own answer when it finds no problem is `{errors: []}` at 200; RULED by the founder 2026-09-12

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/issues/
served & verified
Core
projects13 of 14 served & verified
GET
/api/0/projects/
served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/
served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/files/dsyms/

no debug information file is uploaded by any project here - every project is the `node` platform (render.ts:161) and a Node project produces no dSYM or PDB to upload; Sentry's own answer for a project with none is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/hooks/

no service hook is registered on any project in this universe - canon's webhook_subscription rows are the incident-alerting subscriptions (filter_kind account/service/team, delivery_url hooks.olympus-labs.dev), from hello-18's webhookFilters, the repository, organization and namespace hooks a repository host publishes, from hello-20's githubApp, the GitHub App's OWN hook (filter_kind app_reference, reachable only through appWebhook()), and, from hello-23's agentWebhooks, the Antigravity agent's webhook registration (filter_kind agent_reference, reachable only through agentWebhooks()) - and no row of any of the FIVE kinds is a Sentry project hook (clause re-worded at the hello-18 cutover 2026-09-12, again on 2026-09-14 for hello-20's fourth hook family, and on 2026-10-27 for hello-23's fifth: the canon grew three times and the conclusion did not move); Sentry's own answer for a project with none is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/keys/

SERVED 2026-10-27 (hello-23 sentryKeys, founder ruling F1; decisions/2026-10-27-2306-hello-23-serving-rest.md): the project's one client key from the sentry_project_key table, created with the project. id and public are its 32-hex public half; projectId is the project's id as an integer; name, label, isActive, rateLimit, browserSdkVersion, browserSdk.choices and dynamicSdkLoaderOptions are Sentry's own defaults for a key nobody edited, read off getsentry/sentry@44db45d9 (receivers/core.py, models/projectkey.py, projectoptions/defaults.py, loader/). secret and dsn.secret are a sandbox-issued value derived from the key id that authenticates nothing, and every DSN URL is built on the host the request came in on, so an SDK configured from it reaches this host's read-only refusal and never sentry.io. An artifact before hello-23 answers the generation gap

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/keys/{key_id}/

SERVED 2026-10-27 (hello-23 sentryKeys, founder ruling F1; decisions/2026-10-27-2306-hello-23-serving-rest.md): one client key looked up by its public key within the project, exactly the object the list serves; a key of another project and an unknown id are Sentry's 404. An artifact before hello-23 answers the generation gap

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/members/

SERVED 2026-10-23 (the Sentry tail): the organization members on any team assigned to the project (project_member_index.py at getsentry/sentry@44db45d9). A service has one owning team, so these are that team's people, each the row the organization member list serves for them, sorted by email as the endpoint sorts

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/ownership/

SERVED 2026-09-12: `raw` is the repository's own .github/CODEOWNERS, byte for byte out of the tree, and schema.rules is that text parsed - every principal in it is a team /organizations/{org}/teams/ serves (invariant #5). The four required settings are stated judgments: isActive and codeownersAutoSync are facts about the FILE (it exists and is re-read from the tree on every request), while fallthrough=false and autoAssignment=`Turn off Auto-Assignment` are absences of SENTRY-side configuration - the second corroborated by shapeIssue's assignedTo, which is the incident commander and never an owner. Generation-gated on features.repoOwnership (hello-17)

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/stats/

SERVED 2026-09-12: the response is an array of [timestamp, count] pairs with no required object field, and the counts are real buckets over error_event.t_epoch for the service the project IS. The default grid is the 24 hourly buckets the vendored example carries, ending at the artifact's ANCHOR; `rejected` and `blacklisted` are zero everywhere because this universe records no rejected ingest

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/symbol-sources/

no custom symbol source is configured on any project here - canon carries no symbol server and every project is the `node` platform, which has no native symbols to fetch; Sentry's own answer for a project with none is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/tags/{key}/values/

SERVED 2026-09-12: required `name` only - the project-scoped de-duplication of the same per-event tag list the issue-scoped twin aggregates

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/user-feedback/

nobody has submitted user feedback in this universe - the served project object says so (SURFACE_FLAGS.hasFeedbacks=false and hasNewFeedbacks=false, render.ts:166) and canon's error events are SDK-reported with no attached report; Sentry's own answer for a project with none is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/users/

SERVED 2026-09-12: required username+email only, and eventUser() already shapes exactly those two fields from error_event.person. An event the canon recorded no person for contributes nobody rather than a row of nulls, and every address joins to a canonical person under the org-wide convention every provider in the fleet shares

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/hooks/{hook_id}/

refuse — ENTAILED by the empty beside it: .../hooks/ serves `[]` on this same host, so no hook id can name a service hook and Sentry's own 404 is the whole answer; RULED by the founder 2026-09-12

planned
Core
organizations12 of 12 served & verified
GET
/api/0/organizations/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/eventids/{event_id}/

SERVED 2026-09-12: the ORG-scoped twin of /projects/{org}/{proj}/events/{event_id}/, which has been `derive` since 2026-09-01. Every required field (event/eventId/groupId/organizationSlug/projectSlug) is the same lookup without the project scope, and the embedded event is byte-identical to the project-scoped read of the same id

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/members/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/members/{member_id}/

SERVED 2026-09-12 (the unclassified sweep): the roster's own row, by the id the roster publishes. The operation's 200 IS the component OrganizationMemberWithRoles, which is the list item plus six required fields, and every one of them was already a fact this host holds - `teams` and `teamRoles` are reader.teamMembers(), the same edge /teams/{org}/{team}/members/ has paged since M2 and which the suite now walks in BOTH directions; `isOnlyOwner` is computed off the roster rather than asserted (nobody holds `owner`, so nobody is the only one who does, and the day canon grows an owner the answer moves); `invite_link` is null, the same fact the green list row states as `inviterName: null`. The two ROLE CATALOGS are the only values here that are not an artifact row: they are Sentry's own vocabulary, copied verbatim out of the vendored description's worked example (openapi-derefed.json, the UpdateAnOrganization example), and the conformance case reads that example back out of the document and reds the row if the served bytes differ by so much as a scope string - so the copy is evidence rather than invention and cannot rot. teamRoles[].role is the catalog's own `minimumTeamRole` for the org role the member holds, looked up rather than chosen, because canon assigns nobody an explicit team role and the schema types `role` as a required non-nullable string

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/projects/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/relay_usage/

no Sentry Relay is deployed in this organization - every error event is recorded directly against a project (error_event.service, 85 rows) and canon carries no relay entity at all; Sentry's own answer for an organization with no registered relay is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/repos/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/repos/{repo_id}/commits/

SERVED 2026-09-12: required id/message/dateCreated IS the object shapeReleaseCommit already returns for /releases/{version}/commits/, over reader.listCommits(repo) rather than one release's range. The {repo_id} resolves against the ids /organizations/{org}/repos/ already publishes

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/shortids/{short_id}/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/stats_v2/

SERVED 2026-09-12: every canonical error_event is one accepted `error` outcome at a real instant, so the series is a bucket count over error_event.t_epoch grouped by project/category/outcome. The window ends at the artifact's ANCHOR, never at a wall clock (invariant #1), and a caller who names no period gets the artifact's own window - the only default this host can claim provenance for. A category or outcome this universe never ingested selects nothing

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/stats-summary/

SERVED 2026-09-12: the same bucket count over error_event.t_epoch, rolled up per project rather than per interval. The five drop columns (filtered, rate_limited, invalid, abuse, client_discard, cardinality_limited) are zero because this universe records no rejected ingest at all - there is no ingest, the events were generated - and saying so is what stops a caller reading a drop rate off a number nothing supports

served & verified
Core
releases10 of 12 served & verified
GET
/api/0/organizations/{organization_id_or_slug}/release-threshold-statuses/

no release threshold is configured on any project in this universe - canon's Release (3) carries a tag, a commit, an author and a body and no threshold rule; Sentry's own answer for an organization with none is an empty object at 200; RULED by the founder 2026-09-12

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/releases/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/releases/{version}/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/releases/{version}/commitfiles/

SERVED 2026-10-23 (the Sentry tail): every file each of the release's commits changed against its first parent, read off the git trees canon already holds, one row per change, ordered by filename and paginated, with the commit's message and its author as the member list embeds them. THE SHAPE IS SENTRY'S OWN DOCUMENT, not a recollection of the live API: the pinned build declares this 200 as a bare 'Success', and the CommitFile object is published in the same repository at the build's source commit (getsentry/sentry@44db45d9 api-docs/components/schemas/releases/commit-file.json, emitted key for key by src/sentry/api/serializers/models/filechange.py). Conformance holds every row to that object and to an independent content diff of the same trees, which is the 2026-09-12 proposal's own 'what would change it' met by a vendor document rather than by a capture

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/releases/{version}/commits/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/releases/{version}/deploys/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/releases/{version}/files/

no release in this universe uploads release artifacts - every project is the `node` platform (render.ts:161, read off the file model) deployed from the git repository, and nothing here runs `sentry-cli releases files upload`; Sentry's own answer for a release with no files is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/sessions/

no SDK in this universe reports release-health sessions - the served project object already says so (SURFACE_FLAGS.hasSessions=false, render.ts:166) and canon carries no session counter; Sentry's own answer for an organization with no session data is a 200 whose `groups` is `[]` over real intervals; RULED by the founder 2026-09-12

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/releases/{version}/commits/

SERVED 2026-09-12: the project-scoped twin of /organizations/{org}/releases/{version}/commits/, which has been `derive` since 2026-09-01 - same rows, same shaper, narrower scope (the release must be one this project ships)

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/releases/{version}/files/

the project-scoped half of the same fact: no release in this universe uploads release artifacts (every project is `node`, deployed from git, and nothing runs `sentry-cli releases files upload`); Sentry's own answer is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/releases/{version}/files/{file_id}/

refuse — ENTAILED by the empty beside it: .../releases/{version}/files/ serves `[]` on this same host, so no file id can name a release artifact and Sentry's own 404 for this operation is the whole answer (the agents/{id} precedent, MODES.yaml 2026-09-06); RULED by the founder 2026-09-12

planned
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/releases/{version}/files/{file_id}/

refuse — ENTAILED by the empty beside it: the project-scoped file list serves `[]`, so no file id resolves and Sentry's own 404 is the whole answer; RULED by the founder 2026-09-12

planned
Core
replays3 of 8 served & verified
GET
/api/0/organizations/{organization_id_or_slug}/replay-count/

Session Replay is not enabled for any project in this universe - the served project object says so (SURFACE_FLAGS.hasReplays=false, render.ts:166) and canon carries no replay, click or recording-segment row; Sentry's own answer for a count query with no replays is an object of zeros at 200; RULED by the founder 2026-09-12

served & verified
Long tail
GET
/api/0/organizations/{organization_id_or_slug}/replay-selectors/

the same fact: no replay exists, so no DOM selector was ever recorded (SURFACE_FLAGS.hasReplays=false); Sentry's own answer is `{data: []}` at 200; RULED by the founder 2026-09-12

served & verified
Long tail
GET
/api/0/organizations/{organization_id_or_slug}/replays/

no replay exists in this universe - the served project object already asserts hasReplays=false (render.ts:166) and no canonical entity records a session recording; Sentry's own answer for an organization with none is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Long tail
GET
/api/0/organizations/{organization_id_or_slug}/replays/{replay_id}/

refuse — ENTAILED by the empty beside it: .../replays/ serves `[]`, so no replay id resolves and Sentry's own 404 is the whole answer; RULED by the founder 2026-09-12

deferred
Long tail
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/replays/{replay_id}/clicks/

refuse — ENTAILED by the replay empty: no replay id resolves on this host, so Sentry's own 404 is the whole answer; RULED by the founder 2026-09-12

deferred
Long tail
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/replays/{replay_id}/recording-segments/

refuse — ENTAILED by the replay empty: no replay id resolves, so there is no recording to segment; RULED by the founder 2026-09-12

deferred
Long tail
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/replays/{replay_id}/recording-segments/{segment_id}/

refuse — ENTAILED by the replay empty: neither the replay id nor a segment index inside it resolves; RULED by the founder 2026-09-12

deferred
Long tail
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/replays/{replay_id}/viewed-by/

refuse — ENTAILED by the replay empty: no replay id resolves, so nobody can have viewed one; RULED by the founder 2026-09-12

deferred
Long tail
alerts1 of 7 served & verified
GET
/api/0/organizations/{organization_id_or_slug}/notifications/actions/

nobody configured a spike protection notification in this Sentry organization: a NotificationAction is a row an owner or manager creates, this universe records no such act and accepts no writes, and canon carries no notification-action entity of any kind. Sentry's own answer for an organization with none is a paginated `[]` at 200 (src/sentry/api/endpoints/notifications/notification_actions_index.py at getsentry/sentry@44db45d9, the build's source commit). The pinned build declares this GET's responses as 201/400/403 with no 200, an upstream spec bug; the endpoint's source is what says the GET is a list

served & verified
Next
GET
/api/0/organizations/{organization_id_or_slug}/alert-rules/

refuse — RETIRED UPSTREAM: Sentry deleted the legacy metric alert-rules API on 2026-09-24 (getsentry/sentry#121879, after a default-off 410 from 2026-09-15), naming the workflow and detector APIs as its replacement. No pin ever served it - every sentry pin answered the coverage 404 here - so the six pins keep the coverage 404 they always answered while live hosts answer Sentry's own unrouted 404, an empty text/html with Allow: OPTIONS (meta.retired_meaning). The one-column `monitor` author widening priced 2026-09-13 for this row and its two siblings is DROPPED: there is no longer an upstream endpoint for it to serve. Found by the 2026-10-17 API audit (#647); record in coverage/reviews/2026-10-17-sentry-retirements.md

retired
Next
GET
/api/0/organizations/{organization_id_or_slug}/alert-rules/{alert_rule_id}/

refuse — RETIRED UPSTREAM: the same rule by id, deleted with the list on 2026-09-24 (getsentry/sentry#121879). No pin ever served it - every sentry pin answered the coverage 404 here - so the six pins keep the coverage 404 they always answered while live hosts answer Sentry's own unrouted 404, an empty text/html with Allow: OPTIONS (meta.retired_meaning). The one-column `monitor` author widening priced 2026-09-13 for this row and its two siblings is DROPPED: there is no longer an upstream endpoint for it to serve. Found by the 2026-10-17 API audit (#647); record in coverage/reviews/2026-10-17-sentry-retirements.md

retired
Next
GET
/api/0/organizations/{organization_id_or_slug}/alert-rules/{alert_rule_id}/activations/

refuse — RETIRED UPSTREAM: Sentry deleted the activations list on 2025-01-06 (getsentry/sentry#82955), long before the rest of the legacy alerts API. Sentry removed it twenty months before the first sentry pin was frozen, so NO pin is entitled to it either: every host, live and pinned, answers Sentry's own unrouted 404, an empty text/html with Allow: OPTIONS (meta.retired_meaning). The one-column `monitor` author widening priced 2026-09-13 for this row and its two siblings is DROPPED: there is no longer an upstream endpoint for it to serve. Found by the 2026-10-17 API audit (#647); record in coverage/reviews/2026-10-17-sentry-retirements.md

retired
Next
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/rules/

empty — no issue-alert rule was ever created on any project here - canon's `monitor` is a METRIC threshold (series, comparison, threshold, for_sec) and not an issue rule, and every required field of Sentry's `Rule` but `id` and `projects` is configuration this universe never made: `conditions`, `filters` and `actions` carry Sentry's own internal class paths; Sentry's own answer for a project with none is `[]` at 200. RULED by the founder 2026-09-12 on the unclassified sweep's proposal, as proposed - and Sentry deleted the route on 2026-09-24 (getsentry/sentry#121879), after every sentry pin was frozen, so the six pins keep this empty while live hosts answer Sentry's own unrouted 404 (meta.retired_meaning)

retired
Next
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/rules/{rule_id}/

refuse — ENTAILED by the empty beside it: the project's rule list serves `[]` on this same host, so no rule id resolves and Sentry's own 404 is the whole answer. RULED by the founder 2026-09-12 on the unclassified sweep's proposal, as proposed - and Sentry deleted the route on 2026-09-24 (getsentry/sentry#121879) together with the list, after every sentry pin was frozen, so the six pins keep this refusal while live hosts answer Sentry's own unrouted 404 (meta.retired_meaning)

retired
Next
GET
/api/0/organizations/{organization_id_or_slug}/notifications/actions/{action_id}/

refuse — ENTAILED by the empty beside it: .../notifications/actions/ serves `[]` on this same host, so no action id resolves, and the endpoint's own lookup raises DRF's ResourceDoesNotExist for an id the organization does not have (notification_actions_details.py at getsentry/sentry@44db45d9), which is Sentry's 404 and the whole answer

deferred
Next
teams7 of 7 served & verified
GET
/api/0/organizations/{organization_id_or_slug}/teams/
served & verified
Core
GET
/api/0/organizations/{organization_id_or_slug}/user-teams/

SERVED 2026-10-23 (the Sentry tail): the teams the CALLER is on. The caller is the fleet's one sandbox persona (SENTRY_VIEWER_LOGIN, the person gh. answers GET /user with), so this is that person's team membership off reader.teamMembers, the edge /teams/{org}/{team}/members/ already pages. Each team is the row /teams/{org}/{team}/ serves, plus its projects (the services service.team assigns it) and an empty externalTeams, because no team is linked to an external team through a Sentry integration (the ruled integrations/ empty). Ordered by slug and unpaginated, as the endpoint answers

served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/teams/
served & verified
Core
GET
/api/0/teams/{organization_id_or_slug}/{team_id_or_slug}/
served & verified
Core
GET
/api/0/teams/{organization_id_or_slug}/{team_id_or_slug}/members/
served & verified
Core
GET
/api/0/teams/{organization_id_or_slug}/{team_id_or_slug}/projects/
served & verified
Core
GET
/api/0/teams/{organization_id_or_slug}/{team_id_or_slug}/stats/

SERVED 2026-09-12: the same [timestamp, count] array as the project stats, summed over the services the team owns (service.team) - the set /teams/{org}/{team}/projects/ already resolves

served & verified
Core
crons1 of 5 served & verified
GET
/api/0/organizations/{organization_id_or_slug}/monitors/

no cron monitor is configured in this Sentry organization - the served project object says so (SURFACE_FLAGS.hasMonitors=false, render.ts:166); canon's `monitor` table (14) is a METRIC threshold monitor (series/comparison/threshold/for_sec) with no schedule, and the one scheduled job in the universe (workflow_schedule, a nightly on repo-01) belongs to no service and so has no Sentry project to be monitored in; Sentry's own answer for an organization with none is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Next
GET
/api/0/organizations/{organization_id_or_slug}/monitors/{monitor_id_or_slug}/

refuse — ENTAILED by the empty beside it: .../monitors/ serves `[]` on this same host, so no id or slug can name a cron monitor and Sentry's own 404 is the whole answer; RULED by the founder 2026-09-12

deferred
Next
GET
/api/0/organizations/{organization_id_or_slug}/monitors/{monitor_id_or_slug}/checkins/

refuse — ENTAILED by the same empty: with no cron monitor, no monitor id resolves and there is nothing to check in against; RULED by the founder 2026-09-12

deferred
Next
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/monitors/{monitor_id_or_slug}/

refuse — the project-scoped route to the same non-existent monitor; entailed by the org-scoped `[]`; RULED by the founder 2026-09-12

deferred
Next
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/monitors/{monitor_id_or_slug}/checkins/

refuse — the project-scoped route to the same non-existent monitor's check-ins; entailed by the org-scoped `[]`; RULED by the founder 2026-09-12

deferred
Next
scim4 of 4 served & verified
GET
/api/0/organizations/{organization_id_or_slug}/scim/v2/Groups

SERVED 2026-09-12: the `SCIM is not enabled, so 403` reading is FALSIFIED by the artifact - identity_provider_config carries protocol=saml with scim_enabled=1 from hello-15 on. A SCIM Group IS a Sentry team (the sibling path parameter is literally {team_id}) and `displayName` is the team SLUG, which is what the vendored example's own slug-shaped value carries. Generation-gated: an artifact predating features.ciConfig names hello-15 rather than serving an empty directory

served & verified
Long tail
GET
/api/0/organizations/{organization_id_or_slug}/scim/v2/Groups/{team_id}

SERVED 2026-09-12: one group by the same team id /organizations/{org}/teams/ already serves; displayName is the team slug and members are the real team members. Generation-gated on features.ciConfig (hello-15), like the list beside it

served & verified
Long tail
GET
/api/0/organizations/{organization_id_or_slug}/scim/v2/Users

SERVED 2026-09-12: a SCIM User is an org member addressed by the MEMBER id the path parameter names, which /organizations/{org}/members/ has served as a `derive` row since 2026-09-01. `sentryOrgRole` is orgRoleFor(), the one mapping this renderer already makes, so the directory and the member list cannot disagree. Generation-gated on features.ciConfig (hello-15)

served & verified
Long tail
GET
/api/0/organizations/{organization_id_or_slug}/scim/v2/Users/{member_id}

SERVED 2026-09-12: the same resource by member id. `name` splits the canonical name on its first space; a persona with one name has an EMPTY familyName, which is the absence expressed in the field's own type rather than Sentry's own `N/A` placeholder (invariant #4). Generation-gated on features.ciConfig (hello-15)

served & verified
Long tail
discover2 of 3 served & verified
GET
/api/0/organizations/{organization_id_or_slug}/discover/saved/

nobody in this organization has saved a Discover query - canon's saved queries are the Zendesk ticket views in saved_search (record_kind=ticket, owned by crm-user rows) and, from hello-18's savedFilters, the Jira-shaped rows in saved_filter - and neither table carries a Sentry-scoped Discover query (clause re-worded at the hello-18 cutover 2026-09-12: the canon grew, the conclusion did not move); Sentry's own answer for an organization with none is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Next
GET
/api/0/organizations/{organization_id_or_slug}/events/

SERVED 2026-09-12: Discover over the real event store (error_event, every row a real error at a real instant). The covered field set is closed and named - id, issue, issue.id, project, project.name, title, timestamp, level, release, environment, server_name, the three user columns, and count() as the one aggregate - and a field outside it answers an explicit 400 with the coverage pointer rather than a silent null (invariant #4). Sentry's structured search grammar is not parsed, so a non-empty `query` is refused rather than ignored

served & verified
Next
GET
/api/0/organizations/{organization_id_or_slug}/discover/saved/{query_id}/

refuse — ENTAILED by the empty beside it: the saved-query list serves `[]`, so no query id resolves and Sentry's own 404 is the whole answer; RULED by the founder 2026-09-12

deferred
Next
dashboards1 of 2 served & verified
GET
/api/0/organizations/{organization_id_or_slug}/dashboards/

nobody in this organization has built a dashboard - verbatim the fact `/discover/saved/` beside it was already ruled on, one entity further on: there is no Dashboard row and no widget row anywhere in the artifact, and listStatusDashboards() is a Statuspage entity in a different domain; Sentry's own answer for an organization with none is `[]` at 200. RULED by the founder 2026-09-12 on the unclassified sweep's proposal, as proposed.

served & verified
Next
GET
/api/0/organizations/{organization_id_or_slug}/dashboards/{dashboard_id}/

refuse — ENTAILED by the empty beside it: the dashboard list serves `[]` on this same host, so no dashboard id resolves and Sentry's own 404 is the whole answer. RULED by the founder 2026-09-12 on the unclassified sweep's proposal, as proposed.

deferred
Next
environments2 of 2 served & verified
GET
/api/0/organizations/{organization_id_or_slug}/environments/
served & verified
Core
GET
/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/environments/

SERVED 2026-10-23 (the Sentry tail): the project's EnvironmentProject rows. Sentry links an environment to a project when a deploy of one of its releases names it (release_deploys.py: env.add_project) and when one of its events reports it, and every event here reports the environment its release was deployed to, so the deployments of the releases this project ships are the whole set. Sorted by name; `visibility` filters exactly, and nothing is hidden

served & verified
Core
integrations2 of 2 served & verified
GET
/api/0/organizations/{organization_id_or_slug}/integrations/

verbatim the fact `sentry-app-installations/` was already ruled on, at the other of the two addresses Sentry publishes it from: canon carries no SENTRY-SCOPED app or integration install row, and integrationsFor() is PagerDuty's inbound alert route over a deliberately fictional vendor catalogue - a different provider's entity in a different domain (clause replaced 2026-09-14 for the reason its twin was: hello-20's `githubApp` mints `app`/`app_installation` on the GITHUB organization and its `glDelivery` mints GitLab `project_integration` rows, so 'of ANY kind' is false and the PROVIDER SCOPE is what carries the conclusion); Sentry's own answer for an organization with none installed is `[]` at 200. RULED by the founder 2026-09-12 on the unclassified sweep's proposal, as proposed.

served & verified
Long tail
GET
/api/0/organizations/{organization_id_or_slug}/sentry-app-installations/

no Sentry app is installed in this organization - canon carries no SENTRY-SCOPED app or integration install row and this replica serves no /sentry-apps/ surface for one to be installed from (clause replaced 2026-09-14: it read 'no app or integration install row of ANY kind', and hello-20 falsified that twice - `githubApp` mints an `app`/`app_installation` pair, the GitHub App this organization's CI bot authenticates as and its installation on the GitHub organization, and `glDelivery` mints `project_integration` rows, which are GitLab's integrations with the Jira and the Slack this same fleet renders. Both are a different provider's entity in a different domain, which is the leg the `integrations/` row beside this one already rested on, so the canon grew and the conclusion did not move); Sentry's own answer for an organization with none is `[]` at 200; RULED by the founder 2026-09-12

served & verified
Long tail

03 / What's simulated

One data set, rendered in Sentry's dialect.

What another provider has to agree with, and the test that makes it

Each line below is one assertion in the conformance suite named beside it — run on every build, over one artifact, through the real renderers. Nothing is claimed here that no expect checks.

05 / Pinned snapshots

Universes that never change, on their own hostnames.

Each pin regenerates byte-identically on every request, so a test written against one never drifts. Generations are DIFFERENT universes, not versions of one — never swap a suffix expecting the same data.

PinHostUniverse generationSentry API versionRepository files
sentry-v0sentry-v0.snap.sandboxapis.devgeneration 7v0served
sentry-v0-g10sentry-v0-g10.snap.sandboxapis.devgeneration 10v0served
sentry-v0-g11sentry-v0-g11.snap.sandboxapis.devgeneration 11v0served
sentry-v0-g12sentry-v0-g12.snap.sandboxapis.devgeneration 12v0served
sentry-v0-g8sentry-v0-g8.snap.sandboxapis.devgeneration 8v0served
sentry-v0-g9sentry-v0-g9.snap.sandboxapis.devgeneration 9v0served

Need an endpoint that is not served yet?

Every row Sentry's manifest carries is on this page, so “not here” is an answer rather than a gap in the rendering. Tell us which path and which client, and it moves up the queue — the order is set by what people ask for.

Request coverage