More · 3 min read

SDK

@bisquecloud/sdk, the TypeScript client: publish from a script or a CI job.

@bisquecloud/sdk is the TypeScript client for the Bisque API: publish a presentation from a script, a CI job, or a server, and read any shared one back as text. It has zero dependencies and runs anywhere fetch does: Node 18 and later, Bun, Deno, and browsers. The current version is 0.2.0, under the MIT license.

npm install @bisquecloud/sdk

Read a presentation, no sign-in

import { Bisque } from "@bisquecloud/sdk";

const bisque = new Bisque();
const ctx = await bisque.presentations.context({
  url: "https://bisque.today/p/siderakis/claude-system-card",
});
console.log(ctx.title);
for (const slide of ctx.transcript) console.log(slide.startSec, slide.text);

Public and unlisted presentations need no credential. ctx.contextMd carries the presentation's context.md when it has one.

Publish

Publishing needs a credential: an API key from bisque.cloud/setup/keys, or an OAuth 2.1 token for a hosted agent. auth.md walks through both. Pass the key as apiKey when you construct the client; it is sent as a bearer token on every call that needs one.

const bisque = new Bisque({ apiKey: process.env.BISQUE_API_KEY });

// 1. Read the authoring format. Never write html-presentation/v1 from memory.
const spec = await bisque.presentations.spec();

// 2. Write index.html to that spec (your agent does this), then publish.
const created = await bisque.presentations.create({
  indexHtml,
  slug: "release-notes-2026-08",
  visibility: "unlisted",
});

// 3. Narration finishes in the background; wait for it.
const status = await bisque.presentations.waitUntilReady(
  created.presentationId,
);
console.log(status.webUrl); // https://bisque.today/p/<handle>/release-notes-2026-08

create sends an Idempotency-Key on every call (a UUID unless you pass { idempotencyKey }), so a retried request replays the first result instead of publishing twice.

The calls

CallWhat it does
presentations.spec(part?)The authoring format, or one module of it (charts, macos, and so on), as markdown.
presentations.context(ref)Metadata, per-slide transcript, and context.md for any shared presentation.
presentations.list(params?) / listAll()Your presentations, one page or every page.
presentations.create(req)Create from HTML and have the server narrate it.
presentations.status(id) / waitUntilReady(id)Narration and publish progress.
presentations.startCreation(req)Create from HTML and narrate it yourself. The slides are viewable immediately, silent.
presentations.addSlideAudio(id, slideKey, audio)Give one slide its narration; anyone watching sees it appear.
presentations.finalize(id)Finish the creation and claim its version.
presentations.publishNarrated(req)Deprecated. One call, but nothing is viewable until every slide is narrated.
oembed(url)The oEmbed payload for a watch URL.
ask(query)A natural-language question over the docs and public presentations.
openapi()The OpenAPI 3.1 document this SDK wraps.

Every method takes an optional { signal } for cancellation. The client talks to https://bisque.today unless you pass baseUrl.

Errors and rate limits

Failures throw BisqueError with status, the API's stable code (NOT_FOUND, CONTEXT_RATE_LIMITED, and so on), and a requestId to quote in a bug report. A 429 or 5xx is retried twice, honouring Retry-After; maxRetries changes that. The rate-limit headers from the latest response are on bisque.lastRateLimit.

Reference