SSE metadata access

View as Markdown

When your API uses server-sent events, iterating the generated SDK’s streaming response yields parsed data objects. To also read the SSE protocol fields — event ID, event type, and retry interval — TypeScript, Python, and Go SDKs expose metadata-aware iteration, typically used to resume a stream by event ID.

Metadata-aware iteration

Each event exposes the parsed data alongside its protocol fields. Default iteration is unchanged, so opting in is fully backward compatible.

1const stream = await client.plants.stream({ query: "fern" });
2
3for await (const event of stream.withMetadata()) {
4 event.data // parsed response object (same type as default iteration)
5 event.id // SSE event ID (string | undefined)
6 event.event // SSE event type (string | undefined)
7 event.retry // SSE retry interval in ms (number | undefined)
8}

Each stream owns the underlying HTTP response, and releases it differently per language:

  • TypeScript: the body is released when iteration ends and cancelled when you break out of the loop. An abortSignal in the request options stops the stream from outside.
  • Python: the stream is lazy, issuing the request on first iteration, and releases the response when it’s exhausted, when iteration raises, on close(), or on exiting a with block. AsyncStream supports async with and is awaitable.
  • Go: the stream never closes the body on its own, so defer stream.Close() is required.

withMetadata() requires TypeScript SDK generator version 3.73.0+, and RecvEvent() requires Go SDK generator version 1.32.0+. In Python, with_metadata() requires generator version 5.29.0+ with stream_abstraction enabled.

Stream resumption

The event ID is useful for resuming a stream via the standard Last-Event-ID header: store the last received ID as you iterate, then pass it back to the server on reconnection. This requires server-side support for the Last-Event-ID header.

Automatic reconnection

Mark an SSE endpoint resumable in your API definition (x-fern-streaming.resumable: true in OpenAPI, or response-stream.resumable: true in a Fern Definition) to have the SDK handle resumption for you. On a mid-stream drop, the SDK reconnects transparently, resending the last dispatched event ID in the Last-Event-ID header so iteration continues without gaps. No manual event-ID tracking is required.

Reconnection honors the server’s retry: directive for the reconnect delay, falling back to a 1-second default and capped at 30 seconds. The SDK retries up to 5 consecutive times by default; the counter resets whenever an event is received. Configure a terminator on the endpoint so the SDK can tell a completed stream from a dropped connection.

Both the attempt cap and an on/off toggle are configurable per client and per request:

1const stream = await client.plants.stream({ query: "fern" }, {
2 stream: { reconnectionEnabled: true, maxReconnectionAttempts: 3 }
3});

Automatic reconnection requires TypeScript SDK generator version 3.77.0+, Python 5.15.0+, Go 1.42.0+, or C# 2.71.0+.