POST /v1/presentations · API v1 · versioning
Start a creation: send the HTML and the assets, and the slides are viewable at the returned webUrl straight away — silent until narration arrives. The response names the slides that still need narrating (needsAudio) and the ones whose audio carried forward from last time (reused), with an upload target for each asset and each slide. Narrate each slide with the bisque-voice CLI, PUT the MP3 to its target, then PATCH the slide. While the creation is open it can take more slides (PATCH /v1/presentations/{presentationId}): the presentation document carries live: { revision, startedAt }, revision rises on every append, and the watch page appends the new slides in place. API-key callers only.
Authentication
Send an API key as Authorization: Bearer bisque_live_…. Keys come from bisque.cloud/setup/keys; see Authentication.
A unique key per logical request (a UUID). A retry with the same key and body replays the first response with Idempotent-Replayed: true instead of publishing again; the same key with a different body is a 422 IDEMPOTENCY_KEY_REUSED. Keys last 24 hours.
Request
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
curl -X POST https://bisque.cloud/v1/presentations \
-H "Authorization: Bearer $BISQUE_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
--data @body.json
Response
200: The creation is open and the slides are live.
Errors:
401: Missing or invalid credential.
Other endpoints
| Page | Call | What it does |
|---|---|---|
| Get a presentation | GET /v1/presentations/{presentationId} | The open creation, to resume it from a new session. |
| Add slides | PATCH /v1/presentations/{presentationId} | Append sections while the creation is open. |
| Update a slide | PATCH /v1/presentations/{presentationId}/slides/{slideKey} | Give one slide its narration after the MP3 is uploaded. |
| Wait for an answer | GET /v1/presentations/{presentationId}/surveys/{surveyId}/response | Hold for the viewer's answer to a question on a slide. |
| Finalize | POST /v1/presentations/{presentationId}:finalize | Claim the version. Slides still without audio stay silent. |
| Read as text | GET /api/presentations/context | Any shared presentation as a transcript. No credential needed. |