REST API
Pull issues into your own dashboards, build CI checks, or back up your data.
The public API is JSON over HTTPS, rooted at https://glitchreplay.com/api/v1/. It is read-only at this time — issue actions (resolve, ignore, assign) live in the dashboard. Every endpoint requires a bearer token from API Tokens in the dashboard.
Machine-readable spec: /api/v1/openapi.json (OpenAPI 3.1). Interactive reference: /api/v1/docs.
Authentication
Tokens are grt_… strings (not DSNs). Generate them in API Tokens in the dashboard. Tokens can be scoped to a single project or to your entire org.
curl https://glitchreplay.com/api/v1/projects \
-H "Authorization: Bearer grt_…"If the token is missing or invalid you get a 401 Unauthorized. If the token is valid but doesn't cover the resource you requested (e.g. a project token asking about a different project), you get a 403 Forbidden.
Endpoints
List projects
GET /api/v1/projectsReturns every project the token can see. For org-scoped tokens, that's every project in the org. For project-scoped tokens, just that one.
{
"data": [
{
"id": "prj_…",
"name": "Acme Web",
"slug": "acme-web",
"platform": "nextjs",
"created_at": "2026-04-10T18:42:00Z"
}
],
"meta": { "count": 1 }
}List issues for a project
GET /api/v1/projects/:project_id/issuesQuery parameters:
status—unresolved|resolved|ignoredsince— ISO-8601 timestamp; only issues withlast_seenafter this timeq— full-text search over title, stack, and breadcrumbs (FTS5; supportsNEAR, prefix, etc.)limit— default 50, max 100
curl "https://glitchreplay.com/api/v1/projects/prj_abc/issues?status=unresolved&limit=20" \
-H "Authorization: Bearer grt_…"Without q, results sort by last_seen DESC. With q, results sort by FTS5 BM25 relevance. Each row includes:
{
"id": "a3b1c9d82e4f5a1b",
"display_id": "gr_k9f2qab",
"title": "TypeError: cannot read properties of undefined (reading 'id')",
"error_type": "TypeError",
"total_count": 142,
"first_seen": "2026-04-22T09:14:00Z",
"last_seen": "2026-04-25T11:02:31Z",
"status": "unresolved",
"severity": "error",
"ai_category": null
}Get a single issue
GET /api/v1/issues/:id:id accepts either the human-readable display id (gr_…) or the full canonical fingerprint hash. Returns the full issue record, including counts, fingerprint, environment breakdown, and the latest event ID. Returns 404 if the issue doesn't exist or isn't in the token's org.
Rate limits
Per token: 120 requests per minute. Responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. When you hit the limit you get a 429 Too Many Requests with a Retry-After header in seconds.
Pagination
List endpoints support a limit query parameter (max 100). For very large result sets, filter by since on a rolling window — cursor-based pagination is on the roadmap.
Errors
| Status | When |
|---|---|
400 | Malformed query (e.g. bad regex in q, invalid since timestamp). |
401 | Missing or invalid Authorization header. |
403 | Token can't see the requested resource. |
404 | Resource not found, or not in this org. |
429 | Rate limit exceeded. |
503 | Database unavailable. Retry after a brief backoff. |
Resolving an issue from CI
The bearer-token API is read-only, but every issue carries a separate per-issue resolve token that lets a CI workflow mark that one issue resolved without an OAuth dance. Useful when a PR merges and you want the matching issue to flip to resolved automatically. The token shows up on the issue page under the Resolve from CI panel — copy it, store it as a secret in your CI provider, and POST to:
curl -X POST "https://glitchreplay.com/api/v1/issues/<issue_id>/resolve" \
-H "Authorization: Bearer grw_…"Returns 204 No Content on success. Returns 404 for both wrong token and unknown issue id (intentionally identical, so an outsider can't probe for issue existence by guessing IDs). Idempotent: calling it on an already-resolved issue is still 204. Token can be passed via the Authorization: Bearer <token> header (preferred) or ?token= query parameter for trivial CI hooks where you can't inject headers.
Resolve tokens are per-issue, not per-org — they only authorize that one resolve action, so if a token leaks the damage radius is bounded to one issue. Rotate them from the same panel; the old token becomes invalid immediately.
A minimal GitHub Actions step:
- name: Mark GlitchReplay issue resolved
if: success()
run: |
curl -fsSL -X POST "https://glitchreplay.com/api/v1/issues/${{ vars.GR_ISSUE_ID }}/resolve" \
-H "Authorization: Bearer ${{ secrets.GR_RESOLVE_TOKEN }}"Posting a note from CI
The same resolve token authenticates the per-issue note endpoint, so you can drop a build URL or context line on the issue without resolving it:
curl -X POST "https://glitchreplay.com/api/v1/issues/<issue_id>/note" \
-H "Authorization: Bearer grw_…" \
-H "Content-Type: application/json" \
-d '{"body":"Reproduced in PR #42 — failing test added."}'Roadmap
The following are planned but not yet shipped:
POST /api/v1/issues/:id/ignore,/assign(resolve already shipped — see above)GET /api/v1/issues/:id/events— list raw events in an issue- Cursor-based pagination on all list endpoints
- Stable webhook events for issue state changes
Ingest endpoints (POST /api/{project_id}/envelope/, /sourcemaps, /csp/) authenticate with a project DSN and are documented in SDK setup and Source maps.