Server-sent events and streaming APIs

Use the x-fern-streaming extension to model streaming endpoints

View as Markdown

The x-fern-streaming extension allows you to represent endpoints that are streaming.

JSON streaming

If your API returns a series of JSON chunks as seen below

1{ "text": "Hi, I am a" }
2{ "text": "chatbot. Do you have any"}
3{ "text": "questions for me"}

then simply add the x-fern-streaming: true to your OpenAPI operation.

openapi.yml
1paths:
2 /logs:
3 post:
4 x-fern-streaming: true
5 responses:
6 "200":
7 content:
8 application/json:
9 schema:
10 $ref: "#/components/schemas/Chat"
11components:
12 schemas:
13 Chat:
14 type: object
15 properties:
16 text:
17 type: string

Server-sent events

Team and Enterprise feature

This feature is available only for the Team and Enterprise plans. To get started, reach out to support@buildwithfern.com.

If your API returns server-sent-events (SSE), with the data and event keys as seen below

1data: { "text": "Hi, I am a" }
2data: { "text": "chatbot. Do you have any"}
3data: { "text": "questions for me"}

then make sure to include format: sse.

openapi.yml
1paths:
2 /logs:
3 post:
4 x-fern-streaming:
5 format: sse
6 responses:
7 "200":
8 content:
9 application/json:
10 schema:
11 $ref: "#/components/schemas/Chat"
12components:
13 schemas:
14 Chat:
15 type: object
16 properties:
17 text:
18 type: string

Generated SDKs expose each event’s metadata — event ID, event type, and retry interval to your end users.

If your SSE endpoint uses the event field to discriminate between different event types in a oneOf, Fern auto-infers that the discriminator is at the protocol level. Use x-fern-discriminator-context to override the inferred value when needed.

Terminator message

Some SSE APIs send a standalone terminator message to signal that the stream is complete. For example, OpenAI’s API sends [DONE] as a final message. You can specify this with the terminator field:

openapi.yml
1paths:
2 /logs:
3 post:
4 x-fern-streaming:
5 format: sse
6 terminator: "[DONE]"
7# ... responses and schemas

Resumable streams

Set resumable: true to opt an SSE endpoint into automatic reconnection. When the connection drops mid-stream, the generated SDK reconnects and resends the last event ID in the Last-Event-ID header, so a server that supports that header resumes where the stream left off.

openapi.yml
1paths:
2 /logs:
3 post:
4 x-fern-streaming:
5 format: sse
6 terminator: "[DONE]"
7 resumable: true
8# ... responses and schemas

Configure a terminator alongside resumable. The terminator marks a stream as complete, letting the SDK distinguish a finished stream from a dropped connection so it reconnects only on genuine drops.

resumable is inheritable. Set it at the document level to apply to every SSE endpoint, and override it on individual operations:

openapi.yml
1x-fern-streaming:
2 resumable: true # applies to all SSE endpoints
3
4paths:
5 /logs:
6 post:
7 x-fern-streaming:
8 format: sse
9 resumable: false # overrides the document default
10# ... responses and schemas

Stream parameter

It has become common practice for endpoints to have a stream parameter that controls whether the response is streamed or not. Fern supports this pattern in a first class way.

Simply specify the stream-condition as well as the ordinary response and the streaming response:

openapi.yml
1paths:
2 /logs:
3 post:
4 x-fern-streaming:
5 format: sse
6 terminator: "[DONE]"
7 stream-condition: $request.stream
8 response:
9 $ref: '#/components/schemas/Chat'
10 response-stream:
11 $ref: '#/components/schemas/ChatChunk'
12components:
13 schemas:
14 Chat:
15 type: object
16 properties:
17 text:
18 type: string
19 tokens:
20 type: number
21 ChatChunk:
22 type: object
23 properties:
24 text:
25 type: string