Build on the BankOps.ai platform. Generate investment-grade presentations programmatically with a stable JSON format, a REST API, and a public deck schema that any LLM or script can target.
JSON schema for slides, zones, charts, tables, and text. Stable, versioned, public.
Auth, GET/PATCH presentations, render slides as PNG, JSON Patch (RFC 6902) for partial updates.
Full example decks across industries — copy, adapt, ship.
A presentation is a JSON document with a small, stable shape: a top-level style preset and an array of slides. Each slide describes its layout as a nested grid of zones, and every zone holds typed content — text, charts, tables, images, or stat blocks. The same JSON renders to PowerPoint (.pptx), PDF, and PNG.
{
"style": "corporate",
"slides": [
{
"type": "grid",
"title": "Q1 Review",
"body": {
"direction": "row",
"children": [
{ "span": 1 },
{
"span": 7,
"direction": "col",
"children": [
{
"content": {
"type": "text",
"text": "Q1 Business Review",
"fontSize": 2800
}
}
]
},
{ "span": 4 }
]
}
}
]
}Style presets — corporate, minimal, dark, warm, or an inline style object for custom colors and fonts.
Slide types — grid covers ~95% of layouts via nested row/column zones with integer spans. Section dividers and bare title slides have their own types.
Content types — text, chart (bar/line/pie/area), table, statGrid, image, callout.
Units — font sizes are in hundredths of a point (e.g. 2800 = 28pt). Slide size is in inches. Spans are integer grid units.
Three steps: log in for a token, create an empty presentation to get an ID, then PATCH it with your deck JSON. Each step is a single curl call.
No account? Try the public endpoint
POST /api/public/decks with raw deck JSON — no auth required — returns a viewable URL at /p/<id>. Decks expire after 30 days. Max 256 KB. Rate-limited per IP.
curl -X POST "https://staging.bankops.ai/api/public/decks" \
-H "Content-Type: application/json" \
-d '{
"style": "corporate",
"slides": [
{
"type": "grid",
"title": "Hello",
"body": {
"direction": "row",
"children": [
{ "content": { "type": "text", "text": "Hello from JSON", "fontSize": 4800 } }
]
}
}
]
}'
# → { "id": "AbC123...", "viewUrl": "https://staging.bankops.ai/p/AbC123...", "expiresAt": "..." }For persistent decks tied to your account, use the authenticated flow:
# 1. Log in and capture the token
TOKEN=$(curl -s -X POST "$BANKOPS_API_URL/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"username":"YOUR_USERNAME","password":"YOUR_PASSWORD"}' \
| python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")
# 2. Create a new (empty) presentation and capture its ID
ID=$(curl -s -X POST "$BANKOPS_API_URL/api/presentations" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Hello Deck"}' \
| python3 -c "import sys,json; print(json.load(sys.stdin)['presentation']['id'])")
# 3. Push deck content to the presentation
curl -X PATCH "$BANKOPS_API_URL/api/presentations/$ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": {
"style": "corporate",
"slides": [
{
"type": "grid",
"title": "Hello",
"body": {
"direction": "row",
"children": [
{ "span": 1 },
{ "span": 10, "direction": "col", "children": [
{ "content": { "type": "text", "text": "Hello from JSON", "fontSize": 4800 } },
{ "content": { "type": "text", "text": "Pushed via the BankOps.ai API", "fontSize": 1400 } }
]},
{ "span": 1 }
]
}
}
]
}
}'Why two requests?
POST /api/presentations only accepts title, templateId, and folderId. Deck content is set via PATCH so the same endpoint handles updates throughout a deck’s lifetime — no create-vs-update split to remember.
Authenticate with a Bearer token, then read or write presentations. Use PATCH with a full deck or with RFC 6902 JSON Patch operations for atomic partial updates.
/api/auth/login/api/presentations/api/presentations/:id/api/presentations/:id/api/presentations/:id/slides/:num/imageTwo complete example decks demonstrating the format end-to-end.
Building an agent that generates decks? Point it at agent.md — a concise system prompt with the format rules, dos and don’ts, and a worked example tuned for LLM consumption.