Publish a presentation you narrated yourself
publish_narrated_presentationPublish an html-presentation/v1 document using audio YOU synthesized locally (e.g. with bisque-voice) — free, unlimited, and works on macOS, Linux and Windows. Send each narrated slide's word timings and MP3 metadata; the server assembles presentation.json (recomputing cues from your narration markers) and returns one upload URL per MP3. Then PUT each file and POST the returned completeUrl with the returned files array. RE-PUBLISHING: audio is optional — any narrated slide you omit reuses the audio from the last publish whenever its narration text and speechSpeed are unchanged, so an HTML-only edit needs no synthesis at all. The response reports reused, synthesized, and staleSlides (narrated slides whose text changed and have no audio — synthesize exactly those and publish again). Use create_presentation instead to have the server narrate.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| slug | No | URL slug; defaults to a slugified title. | |
| audio | No | One entry per slide you synthesized, from the JSON `bisque-voice` prints on stdout. `words`, `durationMs`, `size` and `hash` map across verbatim. Optional: omit a slide (or the whole array) and its audio carries forward from the previous publish if the narration text is unchanged — otherwise that slide publishes silent and is listed in `staleSlides`. A FIRST publish with nothing to carry forward is rejected. | |
| title | No | ||
| assets | No | Files the document references relative to itself — fonts, images, SVG, Lottie, Rive, bundled audio cues. html-presentation/v1 requires these to be self-hosted, so a presentation that renders locally is broken once published unless they travel with it. Each gets an upload URL back alongside the MP3s; PUT them the same way. Paths must be under `assets/` — the server owns index.html, presentation.json and context.md, and the manifest owns audio/. Omit for a presentation that references nothing. | |
| handle | No | Publish under a specific channel handle you own. | |
| voiceId | No | Records what actually spoke, e.g. kokoro:af_heart for a locally synthesized Kokoro voice. No audio is generated server-side. | |
| designMd | No | Design frontmatter mapped to theme tokens. | |
| contextMd | No | Shared-with-viewer context.md. | |
| indexHtml | Yes | Full html-presentation/v1 document (the presentation-format meta gate applies). | |
| visibility | No | unlisted (the default) is shareable by link and plays in chat-embedded players; private requires the owner to sign in, so an inline chat player shows a sign-in wall instead of playing — choose private only when the user asked for it. | unlisted |
| speechSpeed | No | Must match the speed you synthesized at — it is part of the audio cache key, so changing it on a re-publish makes every slide stale instead of carrying forward. | |
| presentationId | No | Stable id for idempotent re-publishes; defaults to slug-<hash(userId:slug)>. | |
| voiceStability | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| files | Yes | Echo back verbatim as the complete call's `files`. | |
| reused | Yes | Slide keys whose audio carried forward — no upload. | |
| webUrl | Yes | Shareable watch URL. | |
| warnings | Yes | ||
| publishId | Yes | ||
| uploadUrls | Yes | One pre-signed PUT per file to upload. | |
| completeUrl | Yes | POST here after every PUT, echoing `files` back verbatim. | |
| staleSlides | Yes | Narrated slide keys that will publish SILENT — synthesize exactly these and publish again. | |
| synthesized | Yes | Slide keys this request supplied audio for. | |
| presentationId | Yes |