Browse sections

Streaming responses (SSE)

Functions can stream their output instead of returning one final payload. The platform frames each chunk as a Server-Sent Events (SSE) message, so browsers, CLI tools, and orchestrators can render progress — LLM tokens, job status, long computations — while the handler is still running.

Streaming uses plain HTTP: no WebSocket upgrade, no special client library. Anything that can read an HTTP response line by line (fetch with a reader, curl -N, an EventSource) can consume it.

Write a streaming handler

In Node.js, export an async generator (or return one from your handler): every yield becomes one SSE frame. Python handlers stream the same way — yield from a generator or async generator and each value is framed as a data: event.

index.js
// Return an async generator and the platform streams each chunk
// to the client as Server-Sent Events over /invoke/stream.
exports.handler = async function* (event, context) {
  yield { type: 'status', message: 'starting' };

  for (const token of ['Hello', ' from', ' a', ' stream']) {
    // Objects are framed as `data: {...}` SSE events automatically;
    // yield a string to write a raw SSE frame yourself.
    yield { token };
  }

  yield { type: 'done' };
};

Yield an object and the runtime serializes it as JSON inside a data: frame; yield a string to write a raw SSE frame yourself. When a handler returns a single value instead of a generator, the stream ends with one event: done frame carrying the result — so callers can treat both shapes uniformly.

Call the streaming endpoint

Invoke any function in streaming mode through POST /functions/{functionId}/invoke/stream. The response starts immediately and stays open until the handler finishes:

curl
# -N disables buffering so events render as they arrive
curl -N -X POST "https://api.inquir.org/functions/{functionId}/invoke/stream" \
  -H "Authorization: Bearer $INQUIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event": {"prompt": "stream me"}}'

# data: {"type":"status","message":"starting"}
# data: {"token":"Hello"}
# …
# event: log   — console output is interleaved as log events
# event: done  — emitted when the handler returns a value instead of a generator

Streaming through the API gateway

Gateway routes stream too: a route mapped to a streaming handler forwards SSE frames to the public URL as they are produced. This is how you expose a token-streaming LLM endpoint on your own path:

  • The connection stays open for the full function timeout — streaming does not extend the limit, it just delivers output early.
  • Proxy buffering is disabled for streaming paths, so frames reach the client without batching delays.
  • Route-level auth (API key or Bearer) applies to streaming routes exactly as it does to regular ones.

Behavior notes

  • console.log output is interleaved into the stream as event: log frames, so live logs arrive alongside data without a second connection.
  • If the handler throws mid-stream, the stream ends with an event: error frame containing the message — check for it before treating a closed stream as success.
  • Streams work from warm and cold containers alike; the first frame simply arrives later on a cold path.