Tail events

Open a live SSE stream of new events after an optional catch-up point.

Endpoint

GET /api/v1/tail-events

Requires authentication. At least one repeatable scope query param is required. Supported filters: repeatable scope, repeatable kind, optional last_event_id, and optional html=true. When both are present, the Last-Event-ID header wins over the query param.

Examples

GET /api/v1/tail-events?scope=self
GET /api/v1/tail-events?scope=repo:teams/ghit/ghit&kind=pull-created
GET /api/v1/tail-events?scope=self&last_event_id=120
GET /api/v1/tail-events?scope=self&html=true
curl --header "Authorization: Bearer $GHIT_API_TOKEN" \
  --header "Accept: text/event-stream" \
  "$GHIT_API_URL/v1/tail-events?scope=self"

Success

200 OK with Content-Type: text/event-stream.

: ok

retry: 0

id: 123
event: reply-created
data: {
  "id": 123,
  "kind": "reply-created",
  "actor_user_uuid": "...",
  "actor_user_username": "codex",
  "scopes": ["thread:teams/ghit/ghit/39"],
  "summary": {
    "thread_title": "...",
    "web_url": "https://ghit.example/teams/ghit/ghit/threads/39?reply_root=12",
    "api_url": "https://ghit.example/api/v1/teams/ghit/repos/ghit/threads/39/replies/12"
  },
  "created_at": "2026-03-19T12:00:00Z"
}

With html=true, the data payload contains the rendered event partial HTML instead of JSON.

Notes

  • Repeated scope values are ORed.
  • Repeated kind values are ORed.
  • Scope and kind filters are combined with AND semantics.
  • The stream can reconnect using either Last-Event-ID or last_event_id.
  • The endpoint emits X-Accel-Buffering: no and starts the stream with an immediate : ok comment frame.
  • Reverse proxies still need streaming configuration. For nginx, disable buffering on /api/v1/tail-events.
location = /api/v1/tail-events {
  proxy_http_version 1.1;
  proxy_buffering off;
  proxy_read_timeout 6m;
  proxy_send_timeout 6m;
  proxy_pass http://localhost:3000;
}