# Streaming

> Recibe los tokens a medida que se generan con server-sent events, en todos los formatos de la API.


Define `stream: true`. La respuesta es `text/event-stream`. Los eventos se envían uno por uno, sin buffer.

```bash test
curl -N https://api.notholy.com/v1/chat/completions \
  -H "Authorization: Bearer $NOTHOLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "notholy-specter", "stream": true, "stream_options": {"include_usage": true}, "messages": [{"role": "user", "content": "Define XSS."}]}'
```

```python test
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.notholy.com/v1", api_key=os.environ["NOTHOLY_API_KEY"])

stream = client.chat.completions.create(
    model="notholy-specter",
    stream=True,
    stream_options={"include_usage": True},
    messages=[{"role": "user", "content": "Define CSRF."}],
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")
    if chunk.usage:
        print("\n", chunk.usage.total_tokens, "tokens")
```

```js test
import OpenAI from 'openai';

const client = new OpenAI({ baseURL: 'https://api.notholy.com/v1', apiKey: process.env.NOTHOLY_API_KEY });

const stream = await client.chat.completions.create({
  model: 'notholy-specter',
  stream: true,
  messages: [{ role: 'user', content: 'Define RCE.' }],
});
for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
console.log();
```

## Qué esperar

- Chat completions y completions de texto terminan con `data: [DONE]`. El chunk anterior siempre trae `usage`, con o sin `include_usage`.
- Responses termina con `response.completed` (o `response.incomplete` al llegar al límite de salida). Messages termina con `message_delta` y `message_stop`. Ninguno de los dos envía `[DONE]`.
- En las pausas largas llegan comentarios de keep-alive (formatos de OpenAI) o eventos `ping` (Messages).
- Si el stream se corta, solo pagas los tokens generados antes del corte.
- Los errores detectados antes de que empiece el stream (clave, créditos, límites) vuelven como un error JSON normal con su estado HTTP. Un fallo después de que empezó el stream llega como evento de error en el mismo formato: `data: {"error": ...}`, `response.failed` o un evento `error`.

## Siguientes pasos

- [Errores](/es/guides/errors)
