Sentry
Package o11y is your logs, metrics and traces: ship them in, query them, chart them.
Package o11y is your logs, metrics and traces: ship them in, query them, chart them.
| Base URL | https://api.hanzo.ai |
| Operations | 23 |
| Auth | Authorization: Bearer $HANZO_API_KEY |
sentry
POST /v1/sentry/{project}/envelope/
Receive a Sentry envelope on the clean root
The same envelope ingest as the DSN path, spelled the way this platform names things: one /v1/, the product, the project. Point an SDK's DSN here and the wire is identical.
AUTHENTICATED BY THE DSN PUBLIC KEY and exempt from the principal gate for the same reason — a Sentry SDK has no Hanzo session to present. The project segment is a UUID enforced by the route, and the exemption matches method plus prefix plus suffix, so every Sentry READ (issues, discover, events, logs, traces, stats) stays gated.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project | path | string | yes |
POST /v1/sentry/{project}/store/
Receive a single Sentry event on the clean root
The legacy single-event ingest on the clean /v1/sentry root — one JSON event rather than a framed batch. Same DSN-key authentication, same gate exemption, same UUID-enforced project segment as the envelope route beside it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project | path | string | yes |
GET /v1/sentry/{wildcard1}
Read the caller org's errors on the Sentry surface
Serves the Sentry-compatible read surface — projects, error issues and one issue's occurrences, a single event, error logs, error-correlated traces and one trace's waterfall, and the event-rate stats — so a Sentry client or the error console reads its errors at the paths it already speaks.
It is the SAME runtime the observability surface serves, reached under a second path family, and there is NO rewrite: the runtime carries these routes literally. That is what makes this a product face rather than a translation layer. One runtime, two path families.
A validated principal is required and the read is scoped to that principal's own org. Errors are a tenant's OWN data, so org membership is the whole admission test and there is deliberately no admin term on it — gating the product on platform sudo would make the only way to see your own errors a scope that shows you everyone's. Before the runtime is initialized, 503.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
wildcard1 | path | string | yes |
POST /v1/sentry/{wildcard1}
Send events to the Sentry surface, or write on it
Carries every write on the Sentry-compatible surface: the SDK's error ingest, and the authenticated writes the console makes — creating a project, rotating a project's DSN key, and running a discover query over the events plane.
THE TWO ARE AUTHENTICATED DIFFERENTLY, and that is the rule to get right. An envelope or store submission presents a DSN public key, never a Hanzo session, so it is exempt from the principal gate and verified by the ingest key check instead — which derives the org from the DSN and fails closed. A keyless submission is a 401 from that verifier, not a 403 from the gate, and telling those two apart is how you tell the hops apart. Every other write here needs a validated, org-scoped principal, and creating or rotating requires an editor rather than a viewer.
The ingest exemption is matched by method plus prefix plus suffix, never a bare prefix, and the project segment must be a UUID — so no read is reachable through it. Before the runtime is initialized, 503.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
wildcard1 | path | string | yes |
PUT /v1/sentry/{wildcard1}
Move an error issue through its lifecycle
The one replace on the Sentry surface: updating an error ISSUE — resolving it, ignoring it, or assigning it — and answering the updated issue.
Nothing else here takes a replace. A project is created and deleted but never replaced, and the event and trace planes are append-only telemetry, so an issue's lifecycle is the only mutable state this face exposes.
Requires a validated, org-scoped principal with edit rights; a viewer is refused. The write is confined to the org minted from that principal's claim, so an issue id belonging to another tenant is simply not found. Before the runtime is initialized, 503.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
wildcard1 | path | string | yes |
PATCH /v1/sentry/{wildcard1}
Not served — the Sentry surface has no partial update
The Sentry face carries NO route for a partial update. The wildcard admits every method, so this operation exists as an address, but nothing behind it answers and a request lands on the runtime as an unrouted path.
It is documented rather than silently omitted because the useful thing to say is where to go instead: an issue's lifecycle — resolve, ignore, assign — is a REPLACE on that issue, not a patch, and it is the only mutable state on this surface. A client that reaches for a partial update here is looking for that call.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
wildcard1 | path | string | yes |
DELETE /v1/sentry/{wildcard1}
Delete a Sentry project
The one delete on the Sentry surface: removing a PROJECT, answering 204. Error issues, events and traces are not individually deletable — they are append-only telemetry, and their lifetime is retention's business, not an API call's.
Requires a validated, org-scoped principal with edit rights; a viewer is refused. The delete is confined to the org minted from that principal's claim, so a project id belonging to another tenant is not found rather than removed. Deleting a project retires the DSN that fed it, so any SDK still pointed at that key stops being accepted. Before the runtime is initialized, 503.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
wildcard1 | path | string | yes |
OPTIONS /v1/sentry/{wildcard1}
Not served by the Sentry face
Published because this address accepts every method, but the Sentry face routes nothing here: the request reaches the runtime as an unrouted path and no issue, event or trace is touched.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
wildcard1 | path | string | yes |
POST /v1/sentry/discover
Aggregates a project's captured errors into a table — the caller names the filters, the groupings and the aggregations, and gets back the columns and rows they asked for.
The project is mandatory and is checked against the caller's own org before it scopes anything, so a project id belonging to someone else reads as absent rather than as data.
Request body — application/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
aggregations | string[] | — | Aggregations are the measures to compute per group. |
filters | o11y.O11yFilter[] | — | Filters narrow the scan; each is a field, an operator (eq, neq, like) and a value, and they combine with AND. |
groupBy | string[] | — | GroupBy are the columns to group the rows by. |
limit | integer | — | Limit caps how many rows come back. |
orderBy | string | — | OrderBy is the column or aggregation to sort the rows on. |
orderDir | string | — | OrderDir is asc or desc. |
period | string | — | Period is the window to read, relative to now — 1h, 24h, 7d, 14d, 30d. |
project | string | yes | Project is the project to read, as its id. |
GET /v1/sentry/events/{id}
Returns one captured error event of a project, by its id.
Callers need the viewer role; the runtime's own gate enforces it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | ID is the event id. |
project | query | string | yes | Project is the project the event belongs to, by its id. |
GET /v1/sentry/issues/{id}/events
Lists one issue's captured occurrences, scoped to a project — a project is an isolation unit, so the caller declares which project's occurrences to read.
Callers need the viewer role; the runtime's own gate enforces it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | ID is the issue id. |
project | query | string | yes | Project is the project whose occurrences to read, by its id. |
limit | query | integer | — | Limit caps how many occurrences come back. |
GET /v1/sentry/issues/{id}
Returns one grouped issue of the caller's org with its latest occurrence sample.
Callers need the viewer role; the runtime's own gate enforces it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | ID is the issue id. |
PUT /v1/sentry/issues/{id}
Changes an issue's lifecycle — resolve, ignore, reopen or assign — and returns the updated issue. Fields left unset are left unchanged.
Callers need the editor role; the runtime's own gate enforces it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | ID is the issue id. |
Request body — application/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
assignee | string | — | Assignee is who the issue is assigned to. |
id | string | yes | ID is the issue id. |
status | string | — | Status is the new lifecycle state: unresolved, resolved or ignored. |
GET /v1/sentry/issues
Lists the caller's org's grouped error issues, optionally narrowed to one project and one time window, and filtered by status, level, environment, service, a free-text query and a sort.
Callers need the viewer role; the runtime's own gate enforces it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
status | query | string | — | Status narrows to one lifecycle state: unresolved, resolved or ignored. |
level | query | string | — | Level narrows to one severity, e.g. |
environment | query | string | — | Environment narrows to one deployment environment. |
serviceName | query | string | — | ServiceName narrows to one reporting service. |
query | query | string | — | Query narrows to issues whose text contains it. |
sort | query | string | — | Sort orders the page, e.g. |
offset | query | integer | — | Offset is how many issues to skip. |
limit | query | integer | — | Limit caps how many issues come back. |
project | query | string | — | Project narrows the org's issues to one project, by its id. |
period | query | string | — | Period is the window to read, relative to now — 1h, 24h, 7d, 14d, 30d. |
GET /v1/sentry/logs
Lists a project's captured error events, newest first, optionally narrowed to those whose message or exception text contains a search string.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project | query | string | yes | Project is the project to read, as its id. |
query | query | string | — | Query narrows the page to events whose text contains it. |
period | query | string | — | Period is the window to read, relative to now — 1h, 24h, 7d, 14d, 30d. |
limit | query | integer | — | Limit caps how many events come back. |
POST /v1/sentry/projects/{id}/keys/rotate
Rotates a project's DSN key — bumping its rotation watermark so keys below it stop verifying — and returns the project with its new DSN.
Callers need the editor role; the runtime's own gate enforces it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | ID is the project id. |
GET /v1/sentry/projects/{id}
Returns one Sentry project of the caller's org, DSN included.
Callers need the viewer role; the runtime's own gate enforces it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | ID is the project id. |
DELETE /v1/sentry/projects/{id}
Deletes one Sentry project of the caller's org. Its DSN stops resolving immediately, so ingest for that id fails closed exactly as an unknown project does; retained events are not touched. Answers 204.
Callers need the editor role; the runtime's own gate enforces it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | ID is the project id. |
GET /v1/sentry/projects
Lists the caller's org's Sentry projects, each with its freshly-derived DSN.
Callers need the viewer role; the runtime's own gate enforces it.
POST /v1/sentry/projects
Creates a Sentry project under the caller's org and returns it, DSN included. Only the name, and optionally a slug and platform, are the caller's to set; the org, id and key are server-assigned.
Callers need the editor role; the runtime's own gate enforces it.
Request body — application/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Name is the project's display name. |
platform | string | — | Platform is the reporting runtime, e.g. |
slug | string | — | Slug is the project's short name. |
GET /v1/sentry/stats
Returns a project's event-rate timeseries: one bucket per interval over the requested period, counting the events in it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project | query | string | yes | Project is the project to read, as its id. |
field | query | string | — | Field is the dimension to count over. |
period | query | string | — | Period is the window to read, relative to now — 1h, 24h, 7d, 14d, 30d. |
GET /v1/sentry/traces/{id}
Returns one trace's captured errors for a project — every error event that carried the trace id, in the order the events plane holds them.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | ID is the trace id. |
project | query | string | yes | Project is the project the trace's errors belong to. |
GET /v1/sentry/traces
Lists the traces a project's captured errors reference, each with how many errors landed on it, when they started and stopped, and the latest message seen — the entry point for "which requests are failing".
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project | query | string | yes | Project is the project to read, as its id. |
period | query | string | — | Period is the window to read, relative to now — 1h, 24h, 7d, 14d, 30d. |
limit | query | integer | — | Limit caps how many traces come back. |
How is this guide?