> ## Documentation Index
> Fetch the complete documentation index at: https://docs.skills.video/llms.txt
> Use this file to discover all available pages before exploring further.

# SSE Streaming

> Stream generation status updates from skills.video in a single HTTP connection

This page explains how to use Server-Sent Events (SSE) endpoints in skills.video to receive generation progress updates over one long-lived HTTP response.

## Purpose

Use SSE when your integration needs near real-time task state updates without repeated polling requests.

## Endpoint

SSE endpoints follow the same provider and model naming as standard generation endpoints, with an `/sse/` segment in the path.

```bash theme={null}
POST /api/v1/generation/sse/{provider}/{model}
```

Example:

```bash theme={null}
POST /api/v1/generation/sse/google/veo-3.1
```

## Request parameters

The SSE request body is the same as the matching non-SSE generation endpoint, so you can reuse the same model-specific payload.

### Path parameters

| Name       | Type     | Required | Description                                                           |
| ---------- | -------- | -------- | --------------------------------------------------------------------- |
| `provider` | `string` | Yes      | Model provider slug, for example `google`, `openai`, or `kling-ai`.   |
| `model`    | `string` | Yes      | Model slug under the provider, for example `veo-3.1` or `sora-2-pro`. |

### Headers

| Name                                   | Required    | Description                               |
| -------------------------------------- | ----------- | ----------------------------------------- |
| `Authorization: Bearer <YOUR_API_KEY>` | Yes         | API authentication header.                |
| `Content-Type: application/json`       | Yes         | Indicates JSON request body format.       |
| `Accept: text/event-stream`            | Recommended | Explicitly requests SSE stream responses. |

### Request body example

```json theme={null}
{
  "prompt": "sunrise over mountains in watercolor style"
}
```

## Response example

A successful SSE request returns `200 OK` with `Content-Type: text/event-stream`. The stream sends incremental status updates and ends when the task reaches a terminal state.

Each `data:` frame is a generation object with `id`, `status`, `input`, `data`, and `usage`. Failed terminal frames also include sanitized `code` and `message` fields.

```text theme={null}
data: {"id":"<GENERATION_ID>","status":"IN_QUEUE","input":{"prompt":"sunrise over mountains in watercolor style"},"data":null,"usage":{"total":0,"subscription":0,"permanent":0}}

data: {"id":"<GENERATION_ID>","status":"IN_PROGRESS","input":{"prompt":"sunrise over mountains in watercolor style"},"data":null,"usage":{"total":0,"subscription":0,"permanent":0}}

data: {"id":"<GENERATION_ID>","status":"COMPLETED","input":{"prompt":"sunrise over mountains in watercolor style"},"data":{"<OUTPUT_FIELD>":"<OUTPUT_VALUE>"},"usage":{"total":<NUMBER>,"subscription":<NUMBER>,"permanent":<NUMBER>}}
```

The stream ends when the task reaches a terminal status: `COMPLETED`, `FAILED`, or `CANCELED`. For `FAILED`, use `code` for client branching and `message` for a safe user-facing explanation.

```text theme={null}
data: {"id":"<GENERATION_ID>","status":"FAILED","input":{"prompt":"sunrise over mountains in watercolor style"},"data":null,"usage":{"total":0,"subscription":0,"permanent":0},"code":"VIDEO_GENERATION_FAILED","message":"Generation failed."}
```

## Error handling notes

When the request fails before the stream is established, the API returns standard JSON error responses with `code` and `message`. The legacy `error` field is also present for backward compatibility. Once the stream is established, handle a terminal `FAILED` or `CANCELED` frame as the generation result.

| Status        | Meaning                                         |
| ------------- | ----------------------------------------------- |
| `400`         | Invalid request body or missing required fields |
| `401`         | Missing or invalid API key                      |
| `404`         | Provider or model route not found               |
| `422`         | Validation error                                |
| `429`         | Rate limited                                    |
| `500` / `503` | Transient server-side error                     |

```json theme={null}
{
  "error": "UNAUTHORIZED",
  "code": "UNAUTHORIZED",
  "message": "Unauthorized"
}
```

```json theme={null}
{
  "error": "VIDEO_GENERATION_INVALID_INPUT",
  "code": "VIDEO_GENERATION_INVALID_INPUT",
  "message": "'prompt' parameter is required"
}
```

## Operational behavior

Design client logic for streaming workloads and transient network failure.

* The stream closes after `COMPLETED`, `FAILED`, or `CANCELED`.
* If the connection drops after you receive a generation id, reconcile with `GET /api/v1/generation/{id}`.
* Retry transient HTTP `429` and `5xx` responses with exponential backoff before the stream is established.

## Retry guidance

Retrying a `POST` can create duplicate generation jobs if the first request was accepted but the client disconnected. Use idempotency controls if your backend provides them, or reconcile task IDs before retrying create calls.
