Event stream (SSE)

The API exposes a server-sent event (SSE) stream that delivers validation events in real time. This is the same stream that evctl listen subscribes to internally.

Connecting

GET /api/v1/events
X-Api-Key: ev_your_key
Accept: text/event-stream

The connection stays open and the server pushes events as they occur.

Resuming after a disconnect

Use the Last-Event-ID header (or ?since= query parameter) to request events that occurred after a given event ID. The server replays missed events before resuming the live stream.

GET /api/v1/events?since=evt_3a4b5c6d...
X-Api-Key: ev_your_key
Accept: text/event-stream

Heartbeats

The server sends a periodic : (comment) heartbeat to keep the connection alive through proxies and load balancers. SSE clients ignore comment lines automatically.

Event format

Each SSE event has an id and a data field. The data value is the same JSON envelope used by webhooks:

id: evt_3a4b5c6d...
data: {"id":"evt_3a4b5c6d...","event":"verify.completed","created_at":"2025-06-10T14:02:11.432Z","data":{...}}

See Webhooks for the full envelope and event-type reference.

When to use SSE vs webhooks

SSE Webhooks
Requires public URL No Yes
Works in browser Yes No
At-least-once delivery No (missed if disconnected) Yes (retried)
Good for Dashboards, local dev Production integrations

For local development without a public URL, evctl listen subscribes to the SSE stream and forwards events to your localhost endpoint — already signed — so your real verification code runs against real payloads. See CLI.