Skip to main content

Live request-log tail

GET /api/v1/logs/tail opens a Server-Sent Events (SSE) connection that streams every API request handled for your tenant, sub-second after each response completes. It is the data source behind the Live tail toggle on the developer Request Logs page, and you can consume it directly from your own tooling. The stream excludes health, readiness, and metrics probes, as well as the tail endpoint itself. Base path: /api/v1/logs/tail Authentication: API key (X-API-Key) or session JWT. The caller must hold the owner, admin, or developer role.

Connect

Browsers use EventSource, which cannot set request headers, so pass your credential as the token query parameter instead. A dv_-prefixed value is promoted to X-API-Key; any other value is treated as a bearer JWT. When you call from a server you can send the X-API-Key or Authorization header directly and omit token.

Frames

After connecting, the server sends, in order:
  1. An event: connected handshake frame with data: {"type":"connected", ...}.
  2. A backfill of up to the most recent ~100 request rows.
  3. New rows live, as each request completes.
Comment lines (: heartbeat) are sent every 30 seconds to keep the connection open. Each request row arrives as a named log frame — listen with addEventListener("log", …), not onmessage, because EventSource only routes named frames to a matching listener. Each log frame’s data: line is one JSON object:
Adding fields is backwards-compatible — ignore keys you don’t recognize, and drop any row missing a required field.

Resume after a disconnect

Every frame carries an id (a stream cursor). To resume without losing rows, reconnect with the Last-Event-ID request header set to the last id you received — browser EventSource does this automatically. From a client that can’t set the header, pass the same value as the lastEventId query parameter:
On resume the server replays the rows newer than that cursor before continuing the live tail.

Limits and errors

This is a live tail, not durable history. It carries only recent rows and the live stream — use it for observability, not as a system of record.