# Streaming summaries

<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

Streaming summaries combine file transcription and summarization in a multipart HTTP request. The response contains Server-Sent Events (SSE), including the completed transcript and summary text as it is generated.

## Submit a recording

Use this endpoint:

**`POST /aiservices/speech-summarization/summarize`**

Authenticate with your [Zoom AI Services credentials](/docs/ai-services/auth/). The examples on this page send a token in the `Authorization: Bearer` header.

| Form field | Required | Description                                                                        |
| ---------- | -------- | ---------------------------------------------------------------------------------- |
| `file`     | Yes      | One audio or video file uploaded as binary data.                                   |
| `config`   | No       | JSON string containing `transcribe` and `summary` settings. Send it before `file`. |

This example uploads a project-update recording and selects the corresponding static summary template:

```shell
curl --no-buffer --fail-with-body \
  https://api.zoom.us/v2/aiservices/speech-summarization/summarize \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: text/event-stream" \
  -F 'config={"transcribe":{"language":"en-US","diarization":false,"profanity_filter":false},"summary":{"language":"en-US","template_id":"project_update","enable_dynamic_template":false,"citations":true,"should_remove_sentiment":false}}' \
  -F 'file=@project-update.wav;type=audio/wav'
```

Add the `config` part before the `file` part.

Let your HTTP client set the multipart `Content-Type` header and boundary. In cURL, `-F` does this automatically. `--no-buffer` displays events as they arrive.

Keep credentials on a trusted backend. Read the POST response as a stream with your HTTP client; a browser's native `EventSource` cannot submit this multipart POST request.

## Configure transcription

Put recognition settings in `config.transcribe`. The recognition model is selected automatically and can't be changed.

| Field              | Type    | Default | Description                                                                                                                                                               |
| ------------------ | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `language`         | string  | `en-US` | Input speech locale. Supports the ten languages listed under [Multilingual model languages](/docs/ai-services/scribe/speech-understanding/#multilingual-model-languages). |
| `diarization`      | boolean | `false` | Identify different speakers in the recording.                                                                                                                             |
| `profanity_filter` | boolean | `false` | Filter profanity in the transcript.                                                                                                                                       |

For accepted media formats and upload limits, see [Recording requirements](/docs/ai-services/speech-summarization/#recording-requirements).

## Configure summarization

Put summary settings in `config.summary`. The summary language can differ from the transcription language.

| Field                     | Type    | Default | Description                                                                                               |
| ------------------------- | ------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `language`                | string  | `en-US` | Summary output language.                                                                                  |
| `template_id`             | string  | None    | Predefined summary template. See [Static templates](#static-templates).                                   |
| `custom_template`         | string  | None    | A Markdown template. The summary follows its headings, structure, and formatting.                         |
| `summary_length`          | string  | `short` | `short` or `long`.                                                                                        |
| `citations`               | boolean | `true`  | Include references to transcript evidence in the summary.                                                 |
| `should_remove_sentiment` | boolean | `false` | Remove most sentiment and emotion expressions from the summary. Removal isn't guaranteed to be complete.  |
| `enable_dynamic_template` | boolean | `true`  | Automatically select a template based on the meeting type when no static or custom template is specified. |

### Automatic template

Omit `template_id` and `custom_template` and set `enable_dynamic_template` to `true`, or leave it at its default. The API detects the meeting type and selects a template.

```json
{
    "summary": {
        "language": "en-US",
        "enable_dynamic_template": true,
        "citations": true
    }
}
```

### Static templates

Set `template_id` to one of these values. Selecting a static template disables automatic template selection. You can also set `enable_dynamic_template` to `false` explicitly.

| Template ID        | Purpose                     |
| ------------------ | --------------------------- |
| `one_on_one`       | One-on-one meeting          |
| `stand_up`         | Stand-up meeting            |
| `brainstorm`       | Brainstorming session       |
| `project_update`   | Project update              |
| `discussion`       | General discussion          |
| `q_a`              | Question-and-answer session |
| `customer_success` | Customer success call       |
| `user_feedback`    | User feedback session       |
| `lecture_summary`  | Lecture summary             |
| `next_steps`       | Next steps and action items |

### Custom template

Set `custom_template` to a Markdown template. The summary follows the template's headings, structure, and formatting. A custom template overrides automatic template selection. Choose one template mode per request.

```json
{
    "summary": {
        "language": "en-US",
        "custom_template": "## Decisions\n- \n\n## Owners\n| Person | Task |\n| --- | --- |\n",
        "enable_dynamic_template": false,
        "citations": false
    }
}
```

## Handle the event stream

A successful streaming response uses `Content-Type: text/event-stream`. Each event has an `event:` name and JSON in its `data:` field. A blank line separates events.

HTTP response chunks do not necessarily align with SSE event boundaries. Buffer incomplete events before parsing their JSON.

| Event                 | Meaning                               | Client action                                                                |
| --------------------- | ------------------------------------- | ---------------------------------------------------------------------------- |
| `transcribe_started`  | Transcription has started.            | Show transcription progress.                                                 |
| `transcribe_complete` | The complete transcript is available. | Save `transcript` for display or downstream use.                             |
| `summary_updated`     | The summary has been updated.         | Replace the displayed summary with `summary_result`. Check `response_state`. |
| `done`                | Processing completed.                 | Save the last summary and mark the request complete.                         |
| `error`               | A processing stage failed.            | Handle the error and retain any completed transcript.                        |

### Transcription events

```text
event: transcribe_started
data: {"status":"transcribing"}

event: transcribe_complete
data: {"transcript":{"request_id":"3f2b8c1e-7a4d-4e9b-b6f0-1c5d8a2e9b47","duration_sec":5.2,"result":{"text_display":"We agreed to release the documentation on October fifteenth.","segments":[{"id":"utt_0000","start":0.0,"end":5.2,"channel":0,"speaker":"","text":"We agreed to release the documentation on October fifteenth.","words":[]}]}},"latency_ms":5234,"body_bytes":12456,"status_code":200}

```

`transcribe_complete` includes the transcription result in `transcript`, the transcription latency in `latency_ms`, the size of the transcription result in `body_bytes`, and the transcription status in `status_code`. The example shows a shortened transcript; it is not a complete list of response fields.

### Summary updates

Each `summary_updated` event contains the full summary so far in `summary_result`. Replace the displayed text with each update. `response_state` is `working` during generation and `completed` in the final update.

Skip empty `summary_result` values when updating the display. HTML in the summary is escaped: `<br>` arrives as `&lt;br&gt;`.

```text
event: summary_updated
data: {"summary_result":"## Decisions\n- Release the documentation on October fifteenth.","citations":null,"response_state":"working","error":null}

event: summary_updated
data: {"summary_result":"## Decisions\n- Release the documentation on October fifteenth.[^1]","response_state":"completed","error":null,"citations":[{"id":1,"marker":"[^1]","start_time":"00:00:00.000","end_time":"00:00:05.200","start_item_index":0,"end_item_index":0}]}

```

The summary is Markdown. When `citations` is enabled, the final update adds Markdown footnote markers, such as `[^1]`, and a `citations` array that links each marker to the transcript. Earlier updates have `"citations": null`.

| Field                                | Description                                                                                                   |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| `id`                                 | Citation number.                                                                                              |
| `marker`                             | The marker used in the summary text, such as `[^1]`.                                                          |
| `chunk_id`                           | ID of the transcript chunk that supports the statement.                                                       |
| `speaker`                            | Speaker label of the cited chunk.                                                                             |
| `start_time`, `end_time`             | The cited span of the recording, in `HH:MM:SS.mmm` format. Use them to find the matching transcript segments. |
| `start_item_index`, `end_item_index` | The first and last transcript segments in the cited span.                                                     |

Preserve the markers when displaying or storing the summary.

### Completion

```text
event: done
data: {"status":"complete","total_latency_ms":8500,"transcribe_ms":5234,"summary_ms":3266}

```

The `done` event reports total processing latency and the transcription and summary stage latencies, in milliseconds. Save the last `summary_result`; the `done` payload does not repeat the summary text.

## Handle errors

Check the HTTP status, then read the SSE events. HTTP `200` starts the stream. A successful request ends with a `summary_updated` event with `response_state: "completed"`, followed by `done`.

Treat an `error` event, a `summary_updated` event with `response_state: "error"`, or a connection that ends before `done` as a failure. When processing fails, the API sends an `error` event without `done`.

| HTTP status   | Meaning                                                                 |
| ------------- | ----------------------------------------------------------------------- |
| `200`         | Streaming response. Read events to determine the outcome.               |
| `400`         | Invalid configuration, missing file, or unsupported format.             |
| `401` / `403` | Invalid credentials, or the request isn't authorized.                   |
| `402`         | Your credit is exhausted, or the credential's credit limit was reached. |
| `405`         | Incorrect HTTP method; use POST.                                        |
| `413`         | Upload exceeds 50 MB.                                                   |
| `429`         | Too many requests. See [rate limits](/docs/api/rate-limits/).           |
| `502`         | Transcription or summary service error.                                 |
| `503`         | The summary service is temporarily unavailable.                         |

An SSE error identifies the failed stage:

```text
event: error
data: {"error":"transcribe failed: connection timeout","stage":"transcribe"}

```

| Stage                 | Meaning                                            |
| --------------------- | -------------------------------------------------- |
| `transcribe`          | Transcription failed.                              |
| `summary_preparation` | Preparing the transcript for summarization failed. |
| `summary`             | Summary generation failed.                         |

If transcription fails, the API does not return a partial transcript. If summary generation fails after `transcribe_complete`, retain the completed transcript and show that summarization did not finish.
