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/projects

Returns 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/issues

Query parameters:

  • statusunresolved | resolved | ignored
  • since — ISO-8601 timestamp; only issues with last_seen after this time
  • q — full-text search over title, stack, and breadcrumbs (FTS5; supports NEAR, 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

StatusWhen
400Malformed query (e.g. bad regex in q, invalid since timestamp).
401Missing or invalid Authorization header.
403Token can't see the requested resource.
404Resource not found, or not in this org.
429Rate limit exceeded.
503Database 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.