Logstreem
Stream results
POST

Stream results

Server-sent events for live tail and for result sets too big to buffer.

Same body as run a query, but the response is text/event-stream. Rows arrive as they are produced. Omit a time bound and the stream stays open, tailing new events as they land.

Node
const res = await fetch("https://api.logstreem.com/v1/query/stream", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.LOGSTREEM_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    apl: "['api-gateway-prod']\n| where level == \"error\"",
    follow: true,
  }),
});

for await (const chunk of res.body!) {
  process.stdout.write(new TextDecoder().decode(chunk));
}

follow ignores aggregation

A streaming query cannot summarize — there is no end of input to aggregate over. Use where and project for tails, and poll run a query for aggregates.
POST/v1/query/stream

Body parameters

aplstringrequired

The LSQL query.

followbooleandefault false

Keep the connection open and emit new matches as they arrive.

curl -X POST https://api.logstreem.com/v1/query/stream \
  -H "Authorization: Bearer $LOGSTREEM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"apl":"['api-gateway-prod']\n| where level == \"error\"","follow":true}'

Responses

200OK (text/event-stream)
event: row
data: {"_time":"2026-09-06T09:41:02.114Z","service":"checkout","status":503}

event: row
data: {"_time":"2026-09-06T09:41:04.882Z","service":"payments","status":500}

event: status
data: {"rows_matched":2,"elapsed_ms":41}
401Unauthorized
{
  "error": {
    "type": "authentication_error",
    "code": "missing_token",
    "message": "No API token provided.",
    "doc_url": "https://logstreem.com/docs/errors#missing_token",
    "request_id": "req_9f3c2a7b41de08c5b2e6"
  }
}