Publish a presentation from any program, and read any shared presentation
back as text. The API is what the /present skill calls; you can call it
without the skill. Two hosts serve it, https://bisque.today and
https://bisque.cloud, and every path on this page works on both.
The whole surface is described in OpenAPI 3.1 at
/openapi.json. The same tools are available over MCP —
see the MCP page. Agents reading this site start at
/llms.txt.
Read a presentation, no sign-in
GET /api/presentations/context returns a presentation's title, its
narration transcript slide by slide with timestamps, and the context.md
its author shipped for agents. Public and unlisted presentations need no
credential.
curl -s "https://bisque.today/api/presentations/context?url=https://bisque.today/p/siderakis/agent-readiness"
{
"requestId": "…",
"presentationId": "…",
"title": "…",
"handle": "siderakis",
"slug": "agent-readiness",
"webUrl": "https://bisque.today/p/siderakis/agent-readiness",
"visibility": "public",
"transcript": [{ "slideIndex": 0, "startSec": 0, "title": "…", "text": "…" }],
"contextMd": "…"
}
Anonymous callers get 60 requests per 10 minutes per IP; send a credential for 300, and to read your own private presentations.
Get a credential
Every write needs Authorization: Bearer <credential>.
- API key (
bisque_live_…) — for scripts, CLIs, and coding agents on your machine. Create one at bisque.cloud/setup/keys, or runbisque loginand approve the pairing code in the browser. - OAuth (
bisque_oat_…) — for hosted chat products where nobody can paste a key. Dynamic client registration, PKCE, refresh, revocation.
The step-by-step for agents, in the order they run it, is
/auth.md.
Publish
Fetch the authoring format first — it is served live and never written from memory:
curl -s https://bisque.today/api/presentations/spec
Write one HTML file in that format, then post it:
curl -s -X POST https://bisque.today/api/presentations/create \
-H "Authorization: Bearer $BISQUE_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile html index.html '{indexHtml: $html, slug: "agent-readiness", visibility: "unlisted"}')"
{
"requestId": "…",
"presentationId": "…",
"webUrl": "https://bisque.today/p/you/agent-readiness",
"status": "queued",
"statusUrl": "https://bisque.today/api/presentations/status?presentationId=…"
}
The reply is immediate. Narration runs in the background; poll statusUrl
until ready is true. Post again with the same slug to republish.
| Endpoint | What it does |
|---|---|
GET /api/presentations/spec | The html-presentation/v1 format, as markdown. Public. |
GET /api/presentations/context | A presentation as text. Public for public and unlisted presentations. |
POST /api/presentations/create | Publish; Bisque narrates. Returns 202 and a status URL. |
GET /api/presentations/status | Narration and publish progress by presentationId. |
POST /api/presentations/publish-narrated | Publish with audio you synthesized locally (what /present does). API keys only. |
GET /api/oembed | oEmbed for a watch URL. |
POST /mcp | The presentations MCP server. |
POST /docs/mcp | The documentation MCP server. No credential. |
Errors
Every error is JSON with a stable code, a message for people, and a
requestId to quote:
{
"requestId": "…",
"error": {
"code": "INVALID_PRESENTATION_ID",
"message": "presentationId query parameter is required."
}
}
401 means the credential is missing, expired, or revoked; 429 on the
context endpoint means the per-IP limit; a 404 from any /api path that
does not exist is also JSON, with a hint pointing at this page.
Where it fits
The /present skill wraps this API: it writes the HTML,
narrates locally, and calls publish-narrated. Reach for the API directly
when you are building your own tool, or a pipeline that publishes without an
agent in the loop.