Beezifi Slides Developer Platform
Build on Beezifi Slides
Create decks from your data, keep reports up to date, and let AI assistants draft slides. Every change goes through the same command engine as the editor, so anyone with the deck open watches it happen live.
Quickstart
Make your first deck from code in about two minutes.
- Create an access token. Sign in to Beezifi Slides, open the account menu (your avatar, top right) and choose AI connections (MCP) → Create token. Copy the
bzs_…token. It's shown only once. - Install an SDK, or skip this and use cURL.
npm install /developers/downloads/beezifi-slides-1.0.0.tgzpip install /developers/downloads/beezifi-slides-python-1.0.0.zip - Set your credentials as environment variables.
export SLIDES_URL= export SLIDES_TOKEN=bzs_your_token_here - Create a deck, add a chart and download it.
import { Slides } from '@beezifi/slides'; const slides = new Slides(); // reads SLIDES_URL and SLIDES_TOKEN const deck = await slides.presentations.create({ theme: 'Harbor', outline: '# Launch plan\nSpring 2027\n\n## Why now\n- Customers asked for it\n- The market is moving', }); const { slides: list } = await deck.summary(); await deck.batch() .chart(list[1].id, 'column', ['Q1', 'Q2', 'Q3'], [{ name: 'Requests', values: [120, 260, 410] }], { rect: [520, 150, 380, 300] }) .transition('all', 'fade') .commit(); await deck.download('pptx', 'launch-plan.pptx'); console.log(deck.url); // open it in the appfrom beezifi_slides import Slides slides = Slides() # reads SLIDES_URL and SLIDES_TOKEN deck = slides.presentations.create( theme="Harbor", outline="# Launch plan\nSpring 2027\n\n## Why now\n- Customers asked for it\n- The market is moving", ) second = deck.summary()["slides"][1]["id"] deck.batch().chart(second, "column", ["Q1", "Q2", "Q3"], [{"name": "Requests", "values": [120, 260, 410]}], rect=[520, 150, 380, 300]) \ .transition("all", "fade").commit() deck.download("pptx", "launch-plan.pptx") print(deck.url) # open it in the app# create from an outline curl -s -X POST "$SLIDES_URL/api/presentations" \ -H "Authorization: Bearer $SLIDES_TOKEN" -H "Content-Type: application/json" \ -d '{"theme":"Harbor","outline":"# Launch plan\nSpring 2027\n\n## Why now\n- Customers asked for it"}' # → {"id":"5d7c2e1a-…","title":"Launch plan"} # download as PowerPoint curl -s "$SLIDES_URL/api/presentations/$ID/export?format=pptx" \ -H "Authorization: Bearer $SLIDES_TOKEN" -o launch-plan.pptx
Authentication
Send Authorization: Bearer <token> with every request. Use a personal access token (bzs_…) for scripts, servers and AI assistants. Tokens act as you, with exactly your access: they can open only presentations you own or that are shared with you, and viewers can't edit.
- Only a SHA-256 hash of each token is stored. Revoke tokens any time from AI connections (MCP).
- Tokens can't create or revoke other tokens; that needs a real sign-in.
- Apps where people sign in can use
POST /api/auth/login, which returns a short-lived session token.
Core concepts
- Presentation: a deck with a title, a slide size (points,
960 × 540is 16:9), a theme, sections and slides. - Slide: a layout (
title,titleAndContent,twoContent…), shapes, speaker notes, a transition, animations and comments. Refer to a slide by its id or 0-based index. - Shape: a placeholder, text box, preset shape, picture, table, chart or ink, positioned with
x, y, w, hin points. Get ids fromGET /summary. - Colours:
#RRGGBBor theme colours (accent1–accent6,tx1,bg1,tx2,bg2). Add+40to lighten or-25to darken, e.g.accent1+60. - Commands: every change is a command
{ id, params }, the same ones the editor sends. Commands that create things return their new ids. - Text: plain text sets one paragraph per line, and a leading tab indents a bullet level. For formatting, send paragraphs of runs:
{"runs":[{"t":"Bold","b":true}],"align":"c"}.
Errors
Errors return a JSON body with a readable error, a stable code and a requestId (also in the X-Request-Id header). Include the request id when you contact support.
{ "error": "No slide 12", "code": "invalid_request", "requestId": "0b6c…" }| Status | code | Meaning |
|---|---|---|
| 400 | invalid_request | Bad input, such as an unknown layout or a missing shape id. |
| 401 | unauthorized | Missing, expired or revoked token. |
| 403 | forbidden | Your role doesn't allow this (for example a viewer editing). |
| 404 | not_found | No such presentation, or it isn't shared with you. |
| 413 | payload_too_large | Upload or deck over the size limit. |
| 429 | rate_limited | Too many requests. Wait and retry. |
In POST /commands, each command reports its own result. A failed command doesn't undo the ones before it.
Rate limits
Each token gets 600 API requests a minute by default (API_RATE_LIMIT on self-hosted servers) and 240 MCP calls a minute. Responses carry RateLimit-* headers. Batch commands: one request can run up to 500.
SDKs
| Task | JavaScript | Python |
|---|---|---|
| List decks | slides.presentations.list({ search }) | slides.presentations.list(search=…) |
| Create | create({ title, theme, template, outline }) | create(title=, theme=, template=, outline=) |
| Import a file | import(bytes, 'deck.pptx') | import_file('deck.pptx') |
| Read | deck.summary(), deck.slide(2) | deck.summary(), deck.slide(2) |
| Add slides | deck.addSlides(markdown) | deck.add_slides(markdown) |
| Change text | deck.setText(slide, shapeId, text) | deck.set_text(slide, shape_id, text) |
| Many changes | deck.batch().chart(…).theme('Ember').commit() | deck.batch().chart(…).theme("Ember").commit() |
| Any command | deck.run([{ id, params }]) | deck.run([{"id": …, "params": …}]) |
| Download | deck.download('pptx', path) | deck.download("pptx", path) |
| Versions | saveVersion(label), versions(), restoreVersion(id) | save_version, versions, restore_version |
| Sharing | share(email, 'editor') | share(email, "editor") |
| Live changes | deck.watch(e => …) | Use the WebSocket directly |
Other languages
Generate a client from the OpenAPI 3.1 spec, or call the REST API with any HTTP library.
Build a deck from an outline
Markdown is the quickest way to create many slides at once, from your code or an AI model.
| You write | You get |
|---|---|
# Title + a line of text | A title slide with a subtitle |
## Heading | A new slide with that title |
- item, 1. item | Bullets and numbering; indent two spaces per level |
| a | b | rows | A styled table |
> text | Speaker notes |
**bold**, *italic*, [link](https://…) | Formatted text and links |
--- | A new slide without a heading |
curl -s -X POST "$SLIDES_URL/api/presentations/$ID/outline" \
-H "Authorization: Bearer $SLIDES_TOKEN" -H "Content-Type: application/json" \
-d '{"markdown":"## Results\n- Revenue up 18%\n- 37 new customers\n\n> Pause for questions."}'Edit slides precisely
Read the deck to get slide and shape ids, then send commands. This example adds a highlighted callout and animates it in.
{ "commands": [
{ "id": "shape.insert", "params": { "slide": 2, "preset": "wedgeRoundRectCallout", "rect": [620, 120, 260, 120],
"text": "New record!", "fill": { "color": "accent2" }, "line": null } },
{ "id": "text.format", "params": { "slide": 2, "ids": ["$RESULT_ID"], "props": { "b": true, "size": 24 } } },
{ "id": "animation.add", "params": { "slide": 2, "shape": "$RESULT_ID", "effect": "zoom", "start": "after" } }
] }Commands that create shapes return { id }. Run the first command, then use its id in the next ones, or pass your own id in the params.
Import and export
- Import
.pptx, Markdown, text outlines and JSON withPOST /presentations/import(multipartfile). The response lists anything that couldn't be imported. - Export with
GET /presentations/:id/export?format=pptx|html|md|txt|json. The.htmlfile plays on its own in any browser. PDF comes from the app's Print dialog. - Animations aren't written to
.pptxyet; theX-Export-Warningsheader says so.
REST API
Base URL: /api. Generated from the OpenAPI spec.
Loading the reference…
Realtime events
Connect a WebSocket to /ws?id=<presentation id>&token=<token> to receive every change as it happens. The first message is a snapshot.
| Message | When |
|---|---|
init | On connect: snapshot, seq, your role and who else is here (presence). |
op | A command was applied: { seq, user, cmd: { id, params } }. |
join / leave | Someone opened or closed the deck. |
sel | Someone moved to another slide or selected shapes. |
saved | Changes were written to the database. |
reload | A version was restored; the message carries the new snapshot. |
To edit over the socket, send {"type":"cmd","cid":"me:1","cmd":{"id":"…","params":{…}}}; the server answers with an op carrying your cid, or a reject.
Commands
Every command the editor and the API accept, loaded live from GET /api/commands.
Loading…
Names and options
Accepted names for layouts, themes, shapes, transitions, animation effects, table styles and chart types, from GET /api/options.
Loading…
MCP for AI assistants
Beezifi Slides hosts a remote MCP server at /mcp (Streamable HTTP). Nothing to install on the client. Assistants act as you, through the same access checks as the app, and people with the deck open see their edits live. Comments they leave are credited to "Your name (AI)".
claude mcp add --transport http beezifi-slides /mcp --header "Authorization: Bearer bzs_your_token_here"
{ "mcpServers": { "beezifi-slides": { "type": "http", "url": "/mcp", "headers": { "Authorization": "Bearer bzs_your_token_here" } } } }
| Tool | What it does |
|---|---|
list_presentations | Find decks by title. |
get_presentation | Every slide with its layout, shape ids, text, notes and transition. |
read_slide | One slide in full, as JSON. |
create_presentation | New deck: blank, from a template, or from a Markdown outline. |
add_slides | Append or insert slides from Markdown. |
edit_text, set_notes | Rewrite a shape's text or a slide's speaker notes. |
run_commands, list_commands, list_options | Anything the editor can do: shapes, charts, tables, themes, transitions, animations. |
export_outline, export_pptx | The deck as Markdown, text or a .pptx file. |
save_version | A restore point before big changes. |
Not yet: OAuth sign-in, which the claude.ai and Claude Desktop connector directories require. Clients that accept a URL and a header, such as Claude Code, work today.
Changelog
- 1.0.0 · November 15, 2026. First release: REST API, Markdown outlines, realtime feed, MCP server, JavaScript and Python SDKs, OpenAPI 3.1 spec.
Support
Questions or bugs? Email support@beezifi.com with the requestId from the error. Security reports: security@beezifi.com.