# Streaming - returns Iterator[ChatStream]
stream = sdk.chat.create(prompt="Hello", stream=True)
for event in stream:
    print(event.data)
```

<Callout title="Note" type="info">
  Across all of these examples, the schema for the events only ever specifies
  one or more of the four recognized fields. Adding other fields will trigger a
  validation error when generating an SDK with the Speakeasy CLI or GitHub
  action.
</Callout>

## Sentinel events

Some SSE APIs will terminate the stream by sending a final, special event. This sentinel event is only used to signal that there are no more events and is not intended for application code to handle.

In the example below, the final `data: [DONE]` event is the sentinel event:

```
HTTP/1.1 200 OK
Content-Type: text/event-stream; charset=utf-8
Date: Fri, 12 Jul 2024 14:29:22 GMT
Keep-Alive: timeout=5, max=1000
Connection: Keep-Alive

data: {"content": "there"}

data: {"content": "are 7"}

data: {"content": "continents in the world"}

data: [DONE]
```

To hide this final event in generated SDK methods, use the `x-speakeasy-sse-sentinel: <string>` extension on a `text/event-stream` media object:

```diff
paths:
  /chat:
    post:
      summary: Create a chat completion from a prompt
      operationId: create
      tags: [chat]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChatRequest'
      responses:
        '200':
          description: Chat completion created
          content:
            text/event-stream:
+             x-speakeasy-sse-sentinel: '[DONE]'
              schema:
                $ref: '#/components/schemas/ChatEvent'

components:
  schemas:
    ChatEvent:
      description: A server-sent event containing chat completion content
      type: object
      required: [data]
      properties:
        data:
          type: object
          required: [content]
          properties:
            content:
              type: string
```

Application code like the following TypeScript sample will behave as expected. The async iteration loop will finish when the sentinel event is encountered:

```ts
const llm = new LLM();

const stream = await llm.chat.create({
  prompt: "How many continents are there?",
});

for await (const event of stream) {
//               ^? ChatEvent
  process.stdout.write(event.data.content);
}
```