---
title: "PATCH /v1/presentations/{presentationId}"
description: "Append sections while the creation is open."
canonical: https://bisque.cloud/docs/api/presentations/add-slides
---

# Add slides

Append sections while the creation is open.

Page: https://bisque.cloud/docs/api/presentations/add-slides

`PATCH /v1/presentations/{presentationId}` · API v1 · [versioning](/docs/api/versioning)

Send the whole HTML again with new sections appended. Existing slides keep their keys and order (`LIVE_APPEND_ONLY` otherwise); unchanged slides carry their audio forward, assets the body leaves out are kept, and the response names the slides that need narrating with an upload target for each, exactly as create does. Add `baseRevision`, the `live.revision` the slides were written against, and an append that fell behind is refused (`LIVE_REVISION_CONFLICT`) rather than overwriting slides it never saw; an append waits up to 20 seconds for another append or narration upload in progress, and is refused with `LIVE_APPEND_IN_PROGRESS` if it is still going. `live.revision` on the presentation rises by one and anyone watching sees the new slides without a reload. API-key callers only.

## Authentication

Send an API key as `Authorization: Bearer bisque_live_…`. Keys come from [bisque.cloud/setup/keys](https://bisque.cloud/setup/keys); see [Authentication](/docs/api/authentication).

## Request

| Parameter | In | Meaning |
| --- | --- | --- |
| `presentationId` | path, required |  |

`Content-Type: application/json`. Required: `indexHtml`.

| Field | Type | Meaning |
| --- | --- | --- |
| `indexHtml` | string, required | The whole `html-presentation/v1` file. |
| `audio` | array of object | One entry per narrated slide you synthesized. Omit a slide to carry its last-published audio forward when its narration text is unchanged; omit the array to carry every slide forward. |
| `assets` | object | Page assets (fonts, images) keyed by bundle path. |
| `title` | string | Overrides the title parsed from the HTML. |
| `slug` | string | URL slug under your channel. Reuse it to republish. |
| `presentationId` | string | Republish an existing presentation by id instead of slug. |
| `handle` | string | Which of your channels to publish on; defaults to your account's. |
| `dryRun` | boolean | Sandbox: run every check a real create runs (format, slug and org conflicts, tier cap, credit preflight) and write nothing. The reply is a 200 with status `validated`. |
| `visibility` | public · unlisted · private · org | Who can open the watch link. Unlisted unless you say otherwise; `org` publishes into the bisque.team organization named by `org`. |
| `org` | string | bisque.team organization slug; publishes into the company space. |
| `contextMd` | string | Agent-facing background shipped with the bundle as `context.md`. |
| `designMd` | string | Design notes shipped with the bundle. |
| `voiceId` | string | Narration voice tag; defaults to the account's saved voice. |
| `madeWith` | array of up to 8 of string, up to 80 characters | Models credited with making this presentation — e.g. ["Claude Opus 5", "Kokoro af_heart"]. Free text, shown to viewers in the watch page's ⋯ menu. Omit to keep what a previous publish recorded; send `[]` to clear it. |
| `description` | string, up to 5,000 characters | Plain-text description shown under the player on the watch page, with web URLs linked — a summary, then the sources. Omit to keep what a previous publish sent; send an empty string to clear it. |
| `speechSpeed` | number | Narration speed. 1.0 is normal. |
| `voiceStability` | number | How closely the voice keeps to its reference, for voices that take it. Omit for the voice's default. |

## Example

```bash
curl -X PATCH https://bisque.cloud/v1/presentations/{presentationId} \
  -H "Authorization: Bearer $BISQUE_API_KEY" \
  -H "Content-Type: application/json" \
  --data @body.json
```

## Response

**200**: The slides are appended and live.

Errors:

- `400`: An existing slide was removed or reordered.
- `401`: Missing or invalid credential.
- `404`: No creation is open for this presentation.
- `409`: Another publish superseded this creation, another append got there first, or one is being written.

## Other endpoints

| Page | Call | What it does |
| --- | --- | --- |
| [Create a presentation](/docs/api/presentations/create) | `POST /v1/presentations` | Put the slides up now and narrate them one at a time. |
| [Get a presentation](/docs/api/presentations/get) | `GET /v1/presentations/{presentationId}` | The open creation, to resume it from a new session. |
| [Update a slide](/docs/api/presentations/update-slide) | `PATCH /v1/presentations/{presentationId}/slides/{slideKey}` | Give one slide its narration after the MP3 is uploaded. |
| [Wait for an answer](/docs/api/presentations/wait-for-answer) | `GET /v1/presentations/{presentationId}/surveys/{surveyId}/response` | Hold for the viewer's answer to a question on a slide. |
| [Finalize](/docs/api/presentations/finalize) | `POST /v1/presentations/{presentationId}:finalize` | Claim the version. Slides still without audio stay silent. |
| [Read as text](/docs/api/presentations/read-as-text) | `GET /api/presentations/context` | Any shared presentation as a transcript. No credential needed. |
