Use the BankOps.ai REST API to create and update presentations programmatically. External agents and scripts can authenticate with a Bearer token and manage presentation content via JSON.
All API requests require authentication. Obtain a JWT token by calling the login endpoint, then include it as a Bearer token in subsequent requests.
/api/auth/login— Authenticate and receive a JWT token.{
"username": "your_username",
"password": "your_password"
}{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "uuid",
"username": "your_username"
},
"org": {
"id": "uuid",
"name": "A-1 Investment Bank"
}
}Using the token
Include the token in all subsequent requests:
Authorization: Bearer <token>Tokens expire after 7 days. Browser clients can also use the httpOnly cookie set during login.
Retrieve a presentation by ID, including its content JSON. The presentation must belong to your organization.
/api/presentations/:id— Fetch presentation metadata and content.{
"presentation": {
"id": "bde47f40-c324-4624-af2a-5a779c6c7d10",
"orgId": "...",
"title": "Quarterly Review",
"content": {
"style": "corporate",
"slides": [...]
},
"createdAt": "2026-02-19T00:00:00.000Z",
"updatedAt": "2026-02-19T00:00:00.000Z"
}
}The content field is null until a deck JSON is submitted via PATCH.
Update a presentation's content and/or title. Uses PATCH semantics — only provided fields are updated.
/api/presentations/:id— Update presentation content or title.{
"title": "AI Strategy Deck",
"content": {
"style": "corporate",
"slides": [
{
"type": "title",
"title": "AI Strategy",
"subtitle": "Q1 2026"
},
{
"type": "grid",
"title": "Key Metrics",
"body": {
"direction": "row",
"children": [...]
}
}
]
}
}{
"presentation": {
"id": "bde47f40-...",
"title": "AI Strategy Deck",
"content": {
"style": "corporate",
"slides": [...]
},
"createdAt": "...",
"updatedAt": "..."
}
}| Field | Type | Required | Description |
|---|---|---|---|
| content | object | No | Full deck JSON (see schema below) |
| title | string | No | Presentation title |
At least one field must be provided.
| Status | Body | Cause |
|---|---|---|
| 401 | { "error": "Not authenticated." } | Missing or invalid token |
| 404 | { "error": "Presentation not found." } | Wrong ID or different org |
| 400 | { "error": "..." } | Validation error |
The content field stores a deck JSON object. Below is the complete schema reference. You can also download the raw file: schema.md
# PPTX SDK — LLM Reference
You are generating JSON that will be converted into PowerPoint (.pptx) presentations. Follow this reference exactly. Every property name, nesting level, and type matters.
---
## Deck Structure
```json
{
"style": "corporate",
"slideSize": { "width": 13.333, "height": 7.5 },
"slides": [ ... ]
}
```
| Property | Type | Default | Description |
|---|---|---|---|
| `style` | `string` or `object` | `"corporate"` | Style preset name or inline style object |
| `slideSize` | `{ width, height }` | `{ 10, 7.5 }` | Slide dimensions in inches |
| `slides` | `array` | required | Array of slide definitions |
### Style Presets
| Name | Look | Best For |
|---|---|---|
| `"corporate"` | White bg, dark text, blue accent (#4472C4), Arial/Calibri | Investment banking, finance, formal presentations |
| `"minimal"` | White bg, blue accent (#2980b9), Helvetica Neue | Clean tech pitches, product decks |
| `"dark"` | Dark bg (#1a1a2e), red accent (#E94560), light text | Executive keynotes, dramatic impact |
| `"warm"` | White bg, terracotta accent (#D57F5B), Georgia/Garamond | Creative briefs, editorial presentations |
---
## Slide Types
### Title Slide
```json
{ "type": "title", "title": "Presentation Title", "subtitle": "February 2026" }
```
### Grid Slide (Inline Body)
```json
{
"type": "grid",
"title": "Slide Title",
"sectionLabel": "SECTION NAME",
"footer": "Source: Company data",
"body": { ... }
}
```
| Property | Type | Required | Description |
|---|---|---|---|
| `title` | `string` | no | Main heading at top |
| `sectionLabel` | `string` | no | Eyebrow text above title (e.g. section name) |
| `footer` | `string` | no | Footnote at bottom |
| `body` | `object` | yes | Layout tree (see Grid Layout below) |
### Grid Slide (Template Reference)
```json
{
"type": "grid",
"title": "Override Title",
"$template": "templateName",
"$templateData": { ... }
}
```
Top-level `title`, `sectionLabel`, and `footer` override whatever the template returns.
---
## Grid Layout System
The layout engine uses a 12-column nested grid (like Bootstrap/MUI). Every node is either a **leaf** (has `content`) or a **container** (has `children`).
### Layout Node
```json
{
"span": 6,
"direction": "row",
"gap": 0.15,
"padding": 0.1,
"background": "#F5F0EB",
"border": "#999999",
"header": "Panel Header",
"subheader": "Sub-section",
"subfooter": "Source note",
"children": [ ... ],
"content": { ... }
}
```
| Property | Type | Default | Description |
|---|---|---|---|
| `span` | `number` (1-12) | equal split | Column weight in parent's 12-column grid |
| `direction` | `"row"` or `"col"` | `"row"` | Stack children horizontally or vertically |
| `gap` | `number` | 0.15 | Gap between children (inches) |
| `padding` | `number` | 0 | Inner padding (inches) |
| `background` | `string` | none | Fill color for this zone |
| `border` | `string` | none | Border color |
| `header` | `string` | none | Dark bar with white text above content |
| `subheader` | `string` | none | Smaller text label with underline above content |
| `subfooter` | `string` | none | Small italic text below content |
| `children` | `array` | — | Child layout nodes (container mode) |
| `content` | `object` | — | Content object (leaf mode) |
**Rules:**
- A node has EITHER `children` OR `content`, never both.
- `span` values in sibling nodes should sum to 12 for balanced layouts, but the engine handles any sum.
- Nesting depth is unlimited. Use `direction: "col"` for vertical stacking and `direction: "row"` for horizontal.
### Common Grid Patterns
**Two equal columns:**
```json
{ "direction": "row", "children": [{ "span": 6, "content": ... }, { "span": 6, "content": ... }] }
```
**Sidebar layout (wide left, narrow right):**
```json
{ "direction": "row", "children": [{ "span": 8, "content": ... }, { "span": 4, "content": ... }] }
```
**Top bar + main content:**
```json
{ "direction": "col", "children": [{ "span": 3, "content": ... }, { "span": 9, "content": ... }] }
```
**KPI row + two-panel bottom:**
```json
{
"direction": "col", "children": [
{ "span": 3, "direction": "row", "children": [
{ "content": ... }, { "content": ... }, { "content": ... }
]},
{ "span": 9, "direction": "row", "children": [
{ "span": 8, "content": ... }, { "span": 4, "content": ... }
]}
]
}
```
---
## Content Types
Every leaf node's `content` must have a `type` field. Here are all 11 content types:
### `text`
Plain text block. Use for paragraphs, subtitles, large numbers, labels.
```json
{
"type": "text",
"text": "Your text here",
"font": "Arial",
"fontSize": 1400,
"color": "#333333",
"bold": true,
"align": "l",
"anchor": "t"
}
```
| Property | Type | Default | Description |
|---|---|---|---|
| `text` | `string` | required | The text content (supports `\n` for line breaks) |
| `font` | `string` | style default | Font family |
| `fontSize` | `number` | style default | Font size in hundredths of a point (1400 = 14pt) |
| `color` | `string` | style default | Hex color |
| `bold` | `boolean` | `false` | Bold text |
| `align` | `"l"`, `"ctr"`, `"r"` | `"l"` | Horizontal alignment |
| `anchor` | `"t"`, `"ctr"`, `"b"` | `"t"` | Vertical alignment within bounds |
**When to use:** Section subtitles, large section numbers, descriptive paragraphs, labels, any free-form text.
### `bulletList`
Bulleted list of items. Use for key points, features, takeaways.
```json
{
"type": "bulletList",
"items": ["First point", "Second point", "Third point"],
"fontSize": 1200,
"color": "#333333",
"font": "Calibri",
"lineSpacing": "single"
}
```
| Property | Type | Default | Description |
|---|---|---|---|
| `items` | `string[]` | required | Array of bullet point strings |
| `fontSize` | `number` | style default | Font size (hundredths of a point) |
| `color` | `string` | style default | Text color |
| `font` | `string` | style default | Font family |
| `lineSpacing` | `"single"` or `null` | `null` | `"single"` = tight spacing, `null` = normal spacing |
**When to use:** Key takeaways, feature lists, supporting arguments, analysis points. The most common content type for text-heavy slides.
### `statGrid`
KPI/metric display. Large value with smaller label underneath. Auto-arranges in grid.
```json
{
"type": "statGrid",
"items": [
{ "value": "$680M", "label": "Annual Revenue", "sublabel": "+12% YoY" },
{ "value": "64%", "label": "Gross Margin" },
{ "value": "4,820", "label": "Customers" }
]
}
```
| Property | Type | Description |
|---|---|---|
| `items[].value` | `string` | Large display value (e.g. "$680M", "64%", "4.2x") |
| `items[].label` | `string` | Descriptor below the value |
| `items[].sublabel` | `string?` | Optional tertiary line (e.g. growth rate) |
Layout: 1 item = 1 col, 2 = 2 cols, 3-4 = 2 cols, 5+ = 3 cols. Rows auto-wrap.
**When to use:** KPI dashboards, headline metrics, financial summaries. Best in narrow zones (span 3-4) at the top of a slide.
### `cardGrid`
Bordered cards with title + detail lines. Good for entity profiles, product features.
```json
{
"type": "cardGrid",
"items": [
{ "title": "Cloud Platform", "lines": ["AWS-based infrastructure", "99.9% uptime SLA"] },
{ "title": "Mobile SDK", "lines": ["iOS & Android", "React Native support"] }
]
}
```
| Property | Type | Description |
|---|---|---|
| `items[].title` | `string` | Card heading (bold, accent color) |
| `items[].lines` | `string[]` | Detail lines below title |
**When to use:** Feature comparisons, product capabilities, service offerings. Each card gets a rounded border.
### `keyValue`
Key-value pair list. Bold key with colon, then value on same line.
```json
{
"type": "keyValue",
"items": [
{ "key": "Founded", "value": "2015" },
{ "key": "Headquarters", "value": "San Francisco, CA" },
{ "key": "Employees", "value": "2,500+" }
]
}
```
**When to use:** Company overviews, deal parameters, specification lists.
### `table`
Data table with header row and body rows. Auto-styles with alternating row colors.
```json
{
"type": "table",
"data": {
"headers": ["Company", "Revenue", "Growth", "Margin"],
"rows": [
["Acme Corp", "$520M", "15%", "42%"],
["Globex", "$380M", "22%", "38%"],
["Initech", "$290M", "8%", "45%"]
]
}
}
```
| Property | Type | Description |
|---|---|---|
| `data.headers` | `string[]` | Column headers (styled with accent fill) |
| `data.rows` | `string[][]` | 2D array of cell values |
**When to use:** Financial comparisons, peer analysis, data summaries. Best for structured data with 3-8 columns.
### `teamGrid`
Vertical list of name + title pairs. Simple team roster format.
```json
{
"type": "teamGrid",
"items": [
{ "name": "Jane Smith", "title": "Managing Director" },
{ "name": "John Doe", "title": "Vice President" }
]
}
```
**When to use:** Team pages, leadership lists, contact information.
### `profile`
Single person/entity profile with name + bullet items. Used inside card layouts.
```json
{
"type": "profile",
"name": "Jane Smith",
"items": ["20+ years experience", "Former Partner at McKinsey", "Harvard MBA"]
}
```
**When to use:** Inside profile card templates. Rarely used directly — prefer `teamGrid` for simple lists or the `profileCards` template for elaborate layouts.
### `image`
Embedded image. Two sizing modes: percentage (stretch to container) or pixel (fit with aspect ratio).
```json
{ "type": "image", "path": "images/chart.png", "width": "100%", "height": "100%" }
```
```json
{ "type": "image", "buffer": "<Buffer>", "width": 800, "height": 500 }
```
| Property | Type | Description |
|---|---|---|
| `path` | `string` | File path (resolved relative to JSON file). Use for JSON-to-PPTX converter. |
| `buffer` | `Buffer` | Raw image data. Use for programmatic API. |
| `width` | `number` or `"N%"` | Pixel width or percentage of container |
| `height` | `number` or `"N%"` | Pixel height or percentage of container |
| `ext` | `string` | Image extension (default: `"png"`) |
**When to use:** Pre-made images, logos, maps, screenshots. For data charts, prefer `type: "chart"` instead (see below).
### `chart`
Inline chart generated at the exact container dimensions. The chart engine renders at the cell's pixel size, so no stretching or squashing occurs.
```json
{ "type": "chart", "chartType": "bar", "title": "Revenue by Year",
"categories": ["2022", "2023", "2024"], "series": [{ "name": "Rev", "data": [520, 640, 780] }] }
```
Properties vary by `chartType` — see the **Chart Types** section below.
**When to use:** Any data visualization. Always prefer `type: "chart"` over `type: "image"` for charts, because charts are generated at the exact container size and look crisp at any layout position.
### `line`
Horizontal divider line. Used for visual separation.
```json
{ "type": "line", "color": "#999999", "width": 9525 }
```
| Property | Type | Default | Description |
|---|---|---|---|
| `color` | `string` | style primary text color | Line color |
| `width` | `number` | 9525 | Line width in EMU (9525 = 0.75pt) |
**When to use:** Separating sections within a zone. Rarely needed — use `subheader` on layout nodes instead for most cases.
---
## Chart Types
All chart content uses `"type": "chart"` with a `chartType` field. An optional `title` string adds a centered title above the chart.
### `bar`
Vertical (or horizontal) bar chart. Supports grouped and stacked modes.
```json
{
"type": "chart", "chartType": "bar",
"title": "Revenue by Segment",
"categories": ["Software", "Services", "Hardware"],
"series": [
{ "name": "2023", "data": [320, 180, 95] },
{ "name": "2024", "data": [380, 210, 88] }
],
"horizontal": false,
"stacked": false
}
```
| Property | Type | Default | Description |
|---|---|---|---|
| `categories` | `string[]` | required | X-axis labels |
| `series` | `array` | required | `[{ name, data: number[] }]` |
| `horizontal` | `boolean` | `false` | Horizontal bars |
| `stacked` | `boolean` | `false` | Stack series |
**When to use:** Comparing values across categories. The most versatile chart type. Use for revenue breakdowns, market share, year-over-year comparisons.
### `line`
Line chart with optional smoothing and area fill.
```json
{
"type": "chart", "chartType": "line",
"categories": ["Q1", "Q2", "Q3", "Q4"],
"series": [{ "name": "Revenue", "data": [145, 162, 178, 195] }],
"smooth": true,
"area": false
}
```
| Property | Type | Default | Description |
|---|---|---|---|
| `categories` | `string[]` | required | X-axis labels |
| `series` | `array` | required | `[{ name, data: number[] }]` |
| `smooth` | `boolean` | `false` | Smooth curves |
| `area` | `boolean` | `false` | Fill area under line |
**When to use:** Trends over time, growth trajectories, margin progression.
### `pie`
Pie or doughnut chart.
```json
{
"type": "chart", "chartType": "pie",
"items": [
{ "name": "Software", "value": 65 },
{ "name": "Services", "value": 25 },
{ "name": "Other", "value": 10 }
],
"doughnut": false
}
```
| Property | Type | Default | Description |
|---|---|---|---|
| `items` | `array` | required | `[{ name, value }]` |
| `doughnut` | `boolean` | `false` | Doughnut style (hollow center) |
**When to use:** Composition breakdowns, revenue mix, market share distribution. Best with 2-6 segments. Note: uses `items` not `series`.
### `combo`
Combined bar + line chart on the same axes. Supports dual Y-axis.
```json
{
"type": "chart", "chartType": "combo",
"categories": ["Q1", "Q2", "Q3", "Q4"],
"bars": [{ "name": "Revenue", "data": [145, 162, 178, 195] }],
"lines": [{ "name": "Margin %", "data": [62, 64, 63, 65] }],
"dualAxis": true
}
```
| Property | Type | Default | Description |
|---|---|---|---|
| `categories` | `string[]` | required | X-axis labels |
| `bars` | `array` | `[]` | `[{ name, data }]` for bar series |
| `lines` | `array` | `[]` | `[{ name, data }]` for line series |
| `dualAxis` | `boolean` | `false` | Separate Y-axis for lines |
**When to use:** Revenue + margin, volume + price, any metric pair where one is absolute and one is relative. `dualAxis: true` when scales differ.
### `waterfall`
Waterfall (bridge) chart. First and last values are totals; middle values are deltas.
```json
{
"type": "chart", "chartType": "waterfall",
"categories": ["FY24 Revenue", "Organic Growth", "Acquisitions", "FX Impact", "FY25E Revenue"],
"data": [680, 85, 45, -30, 780]
}
```
| Property | Type | Description |
|---|---|---|
| `categories` | `string[]` | Labels for each bar |
| `data` | `number[]` | First = start total, last = end total, middle = increments/decrements |
**When to use:** Revenue bridges, cost walks, year-over-year reconciliations. Classic investment banking chart.
### `scatter`
Scatter plot with multiple series. Each data point is `[x, y]`.
```json
{
"type": "chart", "chartType": "scatter",
"series": [
{ "name": "Tech", "data": [[15, 42], [22, 38], [8, 55]] },
{ "name": "Finance", "data": [[12, 35], [18, 28], [25, 45]] }
]
}
```
| Property | Type | Description |
|---|---|---|
| `series` | `array` | `[{ name, data: [x, y][] }]` |
**When to use:** Correlation analysis, peer positioning (growth vs. margin), risk-return plots.
### `gauge`
Single-value gauge/speedometer.
```json
{
"type": "chart", "chartType": "gauge",
"value": 73,
"min": 0,
"max": 100,
"label": "NPS Score",
"format": "{value}"
}
```
| Property | Type | Default | Description |
|---|---|---|---|
| `value` | `number` | `0` | Current value |
| `min` | `number` | `0` | Minimum |
| `max` | `number` | `100` | Maximum |
| `label` | `string` | `""` | Label below gauge |
| `format` | `string` | `"{value}%"` | Display format |
**When to use:** Single KPI with context (NPS, utilization rate, goal progress). Best in small zones.
---
## Templates
Templates generate complete slide specs from structured data. Use `$template` and `$templateData` on the slide definition. Templates handle layout complexity so you only provide the data.
### `investorActivity`
Table-like layout showing investors and their portfolio targets.
```
┌──────────────────────────────────────────────────────────────┐
│ [sectionLabel] │
│ [title] │
├────┬──────┬──────────────────────────────────────────────────┤
│Inv │ # │ Target 1 │ Target 2 │ Target 3 │ ← header row
├────┼──────┼──────────────┼──────────────┼────────────────────┤
│Name│ 15 │ Co | Desc │ Co | Desc │ Co | Desc │ ← data rows
└────┴──────┴──────────────┴──────────────┴────────────────────┘
```
```json
{
"$template": "investorActivity",
"$templateData": {
"title": "Investor Activity in Construction Tech",
"sectionLabel": "Market Overview",
"investors": [
{
"name": "Vista Equity",
"count": 15,
"targets": [
{ "company": "Procore", "description": "Project management platform" },
{ "company": "PlanGrid", "description": "Construction blueprints" },
{ "company": "Fieldwire", "description": "Field management" }
]
}
]
}
}
```
**When to use:** Competitive landscape, investor mapping, M&A activity tracking.
### `dashboard`
KPI row on top + two-panel content area below.
```
┌──────────────────────────────────────────────────────────────┐
│ KPI 1 │ KPI 2 │ KPI 3 │ KPI 4 │ span:3
├───────────────────────────────────┬──────────────────────────┤
│ │ │
│ Left Panel (8) │ Right Panel (4) │ span:9
│ │ │
└───────────────────────────────────┴──────────────────────────┘
```
```json
{
"$template": "dashboard",
"$templateData": {
"title": "Revenue Dashboard",
"kpis": [
{ "value": "$680M", "label": "Revenue" },
{ "value": "64%", "label": "Margin" },
{ "value": "4,820", "label": "Customers" }
],
"leftPanel": {
"header": "Quarterly Trend",
"content": { "type": "chart", "chartType": "combo",
"categories": ["Q1", "Q2", "Q3", "Q4"],
"bars": [{ "name": "Revenue", "data": [145, 162, 178, 195] }],
"lines": [{ "name": "Margin", "data": [62, 64, 63, 65] }],
"dualAxis": true }
},
"rightPanel": {
"header": "Top Segments",
"content": { "type": "table", "data": {
"headers": ["Segment", "Rev"],
"rows": [["Cloud", "$280M"], ["On-Prem", "$210M"]]
}}
}
}
}
```
**When to use:** Executive summary slides, financial dashboards, any slide that needs headline KPIs + detail.
### `peerComparison`
Chart on left + stacked stats/table on right.
```
┌──────────────────────────────────┬───────────────────────────┐
│ │ [Peers section] │ span:7
│ Chart (7) ├───────────────────────────┤
│ │ [Valuation section] │ span:5
└──────────────────────────────────┴───────────────────────────┘
```
```json
{
"$template": "peerComparison",
"$templateData": {
"title": "Peer Comparison",
"chart": {
"header": "EV/Revenue Multiple",
"content": { "type": "chart", "chartType": "bar",
"categories": ["Acme", "Globex", "Initech"],
"series": [{ "name": "EV/Rev", "data": [8.2, 6.5, 4.8] }] }
},
"rightHeader": "Financial Comparison",
"peers": {
"subheader": "Peer Metrics",
"content": { "type": "table", "data": {
"headers": ["Company", "Rev", "Growth"],
"rows": [["Acme", "$520M", "15%"], ["Globex", "$380M", "22%"]]
}}
},
"valuation": {
"subheader": "Valuation Summary",
"content": { "type": "statGrid", "items": [
{ "value": "6.5x", "label": "Median EV/Rev" },
{ "value": "18%", "label": "Median Growth" }
]}
}
}
}
```
**When to use:** Competitive benchmarking, peer analysis, valuation comparisons.
### `profileCards`
Two columns of entity profile cards (logo + name + bullets) in a 2x2 grid per column.
```json
{
"$template": "profileCards",
"$templateData": {
"title": "Key Players",
"leftHeader": "Strategic Buyers",
"rightHeader": "Financial Sponsors",
"left": [
{ "name": "Acme Corp", "logo": "images/acme.png",
"items": ["$2.5B revenue", "15 acquisitions since 2020"] }
],
"right": [
{ "name": "Vista Equity", "logo": "images/vista.png",
"items": ["$100B AUM", "Focus: enterprise software"] }
]
}
}
```
**When to use:** Buyer profiles, competitor overviews, entity comparisons with logos.
### `tableOfContents`
Numbered section list with optional decorative right panel.
```json
{
"$template": "tableOfContents",
"$templateData": {
"title": "Table of Contents",
"sections": ["Executive Summary", "Market Overview", "Financials", "Outlook"],
"panelColor": "#D9D9D9"
}
}
```
**When to use:** Agenda/TOC slide near the beginning of a presentation.
### `sectionTitle`
Full-bleed section divider with large number and uppercase title.
```json
{
"$template": "sectionTitle",
"$templateData": {
"number": "01.",
"name": "EXECUTIVE SUMMARY",
"panelColor": "#8FA4B3"
}
}
```
**When to use:** Section dividers between major presentation sections. Place before each new section.
### `transactionGrid`
Grid of tombstone cards (deal announcements). N columns of tombstones.
```json
{
"$template": "transactionGrid",
"$templateData": {
"title": "Select Transactions",
"columns": 4,
"transactions": [
{
"clientName": "Acme Corp",
"clientLogo": "images/acme.png",
"transactionText": "— Acquired by —",
"counterpartyLogo": "images/buyer.png",
"date": "Sep 2025"
}
]
}
}
```
**When to use:** Deal track record, credentials slides, M&A transaction lists.
### `globalBuyers`
Large image (e.g. world map) on top + row of tombstones below.
```json
{
"$template": "globalBuyers",
"$templateData": {
"title": "Global Buyer Universe",
"mapImage": { "type": "image", "path": "images/world-map.png", "width": "100%", "height": "100%" },
"transactions": [
{ "clientName": "Asia Buyer", "transactionText": "— Acquired —", "date": "2025" }
]
}
}
```
**When to use:** Geographic buyer mapping, global transaction coverage.
### `customerQuotes`
Quote cards on top + press/testimonial banner below.
```json
{
"$template": "customerQuotes",
"$templateData": {
"title": "What Our Clients Say",
"quotes": [
{ "text": "Transformed our workflow completely.", "author": "Jane Smith",
"role": "VP Engineering", "company": "Acme Corp" }
],
"banner": [
{ "text": "\"Best platform we've used\" — TechCrunch" },
{ "text": "\"Game-changing\" — Forbes" }
],
"bannerColor": "#F5F0EB"
}
}
```
**When to use:** Testimonials, client endorsements, press quotes.
### `credentialsProfile`
2x2 quadrant: stats, practice areas (icon grid), tombstones, team profiles.
```json
{
"$template": "credentialsProfile",
"$templateData": {
"title": "Firm Overview",
"stats": {
"header": "Key Metrics",
"items": [{ "value": "$50B+", "label": "Transactions" }, { "value": "200+", "label": "Deals" }]
},
"practiceAreas": {
"header": "Practice Areas",
"items": [{ "label": "M&A Advisory" }, { "label": "Capital Markets" }]
},
"transactions": {
"header": "Recent Deals",
"tombstones": [{ "clientName": "Acme", "transactionText": "Acquired by", "date": "2025" }]
},
"team": {
"header": "Senior Team",
"members": [{ "name": "John Doe", "items": ["Managing Director", "20+ years"] }]
}
}
}
```
**When to use:** Firm credentials, company overview, "about us" slides.
### `marketUpdate`
Chart on top half + 2x2 trend grid on bottom (icon + title + bullets per cell).
```json
{
"$template": "marketUpdate",
"$templateData": {
"title": "Market Update",
"chart": {
"header": "S&P 500 Performance",
"content": { "type": "chart", "chartType": "line",
"categories": ["Jan", "Feb", "Mar", "Apr"],
"series": [{ "name": "S&P", "data": [4800, 4950, 5100, 5200] }] }
},
"trendsHeader": "Key Market Themes",
"trends": [
{ "title": "AI Infrastructure", "bullets": ["$200B capex cycle", "Cloud demand accelerating"] },
{ "title": "Rate Environment", "bullets": ["Fed holding steady", "Yield curve normalizing"] }
]
}
}
```
**When to use:** Market overview slides, industry update briefings.
### `chartQuadrant`
2x2 grid of chart panels. Each quadrant has a header and 1+ charts.
```json
{
"$template": "chartQuadrant",
"$templateData": {
"title": "Industry Dynamics",
"quadrants": [
{ "header": "Revenue Growth",
"charts": [{ "type": "chart", "chartType": "bar",
"categories": ["2022", "2023", "2024"],
"series": [{ "name": "Rev", "data": [520, 640, 780] }] }] },
{ "header": "Margin Trend",
"charts": [{ "type": "chart", "chartType": "line",
"categories": ["2022", "2023", "2024"],
"series": [{ "name": "Margin", "data": [58, 62, 65] }] }] },
{ "header": "Revenue Mix",
"charts": [{ "type": "chart", "chartType": "pie",
"items": [{ "name": "Software", "value": 65 }, { "name": "Services", "value": 35 }] }] },
{ "header": "Revenue Bridge",
"charts": [{ "type": "chart", "chartType": "waterfall",
"categories": ["FY24", "Growth", "M&A", "FY25E"],
"data": [640, 95, 45, 780] }] }
]
}
}
```
**When to use:** Multi-chart analysis slides, industry dynamics, comprehensive data overview. Best when you need 4 related charts on one slide.
### `keyTrends`
Subtitle row on top + 3 equal columns, each with header, 2/3 text, 1/3 visual.
```
┌──────────────────────────────────────────────────────────────┐
│ [title] │
├──────────────────────────────────────────────────────────────┤
│ [subtitle text] │ span:2
├──────────────────┬──────────────────┬────────────────────────┤
│ ██ Header 1 ██ │ ██ Header 2 ██ │ ██ Header 3 ██ │
│ │ │ │ span:10
│ [bullets] │ [bullets] │ [bullets] │ 2/3
│ │ │ │
│ [chart/visual] │ [chart/visual] │ [chart/visual] │ 1/3
└──────────────────┴──────────────────┴────────────────────────┘
```
```json
{
"$template": "keyTrends",
"$templateData": {
"title": "Industry Key Trends",
"subtitle": "As demand for digital transformation accelerates...",
"sectionLabel": "Market Overview",
"columns": [
{
"header": "Cloud Adoption",
"text": { "type": "bulletList", "items": [
"85% of enterprises adopting multi-cloud",
"Annual cloud spend exceeding $600B"
]},
"visual": { "type": "chart", "chartType": "bar",
"categories": ["2022", "2023", "2024"],
"series": [{ "name": "Spend ($B)", "data": [410, 500, 620] }] }
},
{
"header": "AI Integration",
"text": { "type": "bulletList", "items": [
"GenAI adoption up 3x YoY",
"Enterprise AI market at $150B"
]},
"visual": { "type": "chart", "chartType": "pie",
"items": [{ "name": "GenAI", "value": 45 }, { "name": "ML Ops", "value": 35 }, { "name": "Other", "value": 20 }] }
},
{
"header": "Security Spend",
"text": { "type": "bulletList", "items": [
"Zero-trust adoption at 61%",
"Cybersecurity M&A accelerating"
]},
"visual": { "type": "chart", "chartType": "line",
"categories": ["2022", "2023", "2024"],
"series": [{ "name": "Spend ($B)", "data": [170, 195, 225] }], "smooth": true }
}
]
}
}
```
**When to use:** Industry trend analysis, thematic overviews. Best when you have 3 parallel themes each needing explanation + visual evidence.
---
## Components
Components are reusable sub-slide building blocks that can be placed in any grid cell. Use `$component` in body node children.
### `tombstone`
Investment banking deal tombstone card.
```json
{
"$component": "tombstone",
"clientName": "Acme Corp",
"clientLogo": "images/acme.png",
"transactionText": "— Acquired by —",
"counterpartyLogo": "images/buyer.png",
"date": "September 2025",
"logoWidth": 100,
"logoHeight": 40
}
```
**When to use:** Inside `transactionGrid` or `globalBuyers` templates, or in custom grid layouts for deal credentials.
---
## Decision Guide
### Choosing a Slide Type
| User Intent | Slide Type |
|---|---|
| Opening/title slide | `type: "title"` |
| Agenda / table of contents | `$template: "tableOfContents"` |
| Section break | `$template: "sectionTitle"` |
| KPI dashboard with charts | `$template: "dashboard"` |
| Financial comparison | `$template: "peerComparison"` |
| 4 charts on one slide | `$template: "chartQuadrant"` |
| 3 parallel themes/trends | `$template: "keyTrends"` |
| Deal track record | `$template: "transactionGrid"` |
| Client testimonials | `$template: "customerQuotes"` |
| Firm credentials / about us | `$template: "credentialsProfile"` |
| Market briefing with trends | `$template: "marketUpdate"` |
| Buyer/investor profiles | `$template: "profileCards"` or `$template: "investorActivity"` |
| Custom layout | `type: "grid"` with inline `body` |
### Choosing a Chart Type
| Data Shape | Chart Type |
|---|---|
| Values across categories | `bar` |
| Trend over time | `line` |
| Composition / market share | `pie` |
| Revenue + margin (two scales) | `combo` with `dualAxis: true` |
| Year-over-year bridge | `waterfall` |
| Correlation (x,y pairs) | `scatter` |
| Single KPI with range context | `gauge` |
### Choosing a Content Type
| Content Need | Content Type |
|---|---|
| Key points / analysis | `bulletList` |
| Headline metrics | `statGrid` |
| Structured data comparison | `table` |
| Feature/product cards | `cardGrid` |
| Specifications / parameters | `keyValue` |
| Team roster | `teamGrid` |
| Free-form text | `text` |
| Data visualization | `chart` |
| Pre-made image | `image` |
---
## Common Presentation Structures
### Corporate / Investment Banking Pitch
```json
{
"style": "corporate",
"slides": [
{ "type": "title", "title": "...", "subtitle": "..." },
{ "type": "grid", "$template": "tableOfContents", "$templateData": { "sections": [...] } },
{ "type": "grid", "$template": "sectionTitle", "$templateData": { "number": "01.", "name": "EXECUTIVE SUMMARY" } },
{ "type": "grid", "$template": "dashboard", "$templateData": { ... } },
{ "type": "grid", "$template": "sectionTitle", "$templateData": { "number": "02.", "name": "MARKET OVERVIEW" } },
{ "type": "grid", "$template": "keyTrends", "$templateData": { ... } },
{ "type": "grid", "$template": "chartQuadrant", "$templateData": { ... } },
{ "type": "grid", "$template": "sectionTitle", "$templateData": { "number": "03.", "name": "COMPETITIVE LANDSCAPE" } },
{ "type": "grid", "$template": "peerComparison", "$templateData": { ... } },
{ "type": "grid", "$template": "investorActivity", "$templateData": { ... } },
{ "type": "grid", "$template": "sectionTitle", "$templateData": { "number": "04.", "name": "CREDENTIALS" } },
{ "type": "grid", "$template": "transactionGrid", "$templateData": { ... } },
{ "type": "grid", "$template": "credentialsProfile", "$templateData": { ... } }
]
}
```
### Product / Tech Pitch
```json
{
"style": "minimal",
"slides": [
{ "type": "title", "title": "...", "subtitle": "..." },
{ "type": "grid", "title": "The Problem", "body": { "direction": "row", "children": [
{ "span": 7, "content": { "type": "bulletList", "items": [...] } },
{ "span": 5, "content": { "type": "statGrid", "items": [...] } }
]}},
{ "type": "grid", "title": "Our Solution", "body": { "direction": "row", "children": [
{ "span": 6, "content": { "type": "cardGrid", "items": [...] } },
{ "span": 6, "content": { "type": "chart", "chartType": "bar", ... } }
]}},
{ "type": "grid", "$template": "dashboard", "$templateData": { ... } },
{ "type": "grid", "$template": "customerQuotes", "$templateData": { ... } }
]
}
```
---
## Important Rules
1. **Always use `type: "chart"` for data visualizations**, not `type: "image"`. Charts are rendered at the exact container size.
2. **`fontSize` is in hundredths of a point**: 1400 = 14pt, 1200 = 12pt, 2800 = 28pt.
3. **Colors are hex strings** with `#` prefix: `"#4472C4"`, `"#333333"`.
4. **`pie` charts use `items`**, all other charts use `series` (except `waterfall` which uses `data`).
5. **`combo` charts use `bars` and `lines`**, not `series`.
6. **Template properties go in `$templateData`**, not on the slide root (except `title`, `sectionLabel`, `footer` which override).
7. **`span` values are relative weights** in a 12-column grid. Two children with span 6 each = two equal halves.
8. **Images in JSON files use `path`** (file path), while programmatic API uses `buffer` (Buffer object).
9. **Keep bullet items concise** — 1-2 lines each, 3-6 items per list.
10. **Use `sectionLabel`** on content slides to show which section the slide belongs to.
A working 3-slide example demonstrating a title slide, an inline grid layout, and a dashboard template. Download: example-deck.json
{
"style": "corporate",
"slides": [
{
"type": "title",
"title": "Quarterly Business Review",
"subtitle": "Q1 2026 — A-1 Investment Bank"
},
{
"type": "grid",
"title": "Executive Summary",
"sectionLabel": "OVERVIEW",
"body": {
"direction": "row",
"children": [
{
"span": 6,
"header": "Key Metrics",
"content": {
"type": "statGrid",
"items": [
{ "value": "$42M", "label": "Revenue", "sublabel": "+18% YoY" },
{ "value": "68%", "label": "Gross Margin" },
{ "value": "1,250", "label": "Customers", "sublabel": "+320 net new" },
{ "value": "4.2x", "label": "LTV/CAC" }
]
}
},
{
"span": 6,
"header": "Revenue Trend",
"content": {
"type": "chart",
"chartType": "bar",
"title": "Quarterly Revenue ($M)",
"categories": ["Q2 '25", "Q3 '25", "Q4 '25", "Q1 '26"],
"series": [{ "name": "Revenue", "data": [32, 35, 38, 42] }]
}
}
]
}
},
{
"type": "grid",
"$template": "dashboard",
"$templateData": {
"title": "Financial Dashboard",
"kpis": [
{ "value": "$42M", "label": "Revenue" },
{ "value": "68%", "label": "Gross Margin" },
{ "value": "$8.2M", "label": "EBITDA" },
{ "value": "118%", "label": "Net Retention" }
],
"leftPanel": {
"header": "Revenue & Margin Trend",
"content": {
"type": "chart",
"chartType": "combo",
"categories": ["Q2 '25", "Q3 '25", "Q4 '25", "Q1 '26"],
"bars": [{ "name": "Revenue ($M)", "data": [32, 35, 38, 42] }],
"lines": [{ "name": "Margin %", "data": [64, 65, 67, 68] }],
"dualAxis": true
}
},
"rightPanel": {
"header": "Top Segments",
"content": {
"type": "table",
"data": {
"headers": ["Segment", "Rev", "Growth"],
"rows": [
["Enterprise", "$24M", "+22%"],
["Mid-Market", "$12M", "+15%"],
["SMB", "$6M", "+8%"]
]
}
}
}
}
}
]
}
Complete workflow using curl to authenticate, update a presentation, and verify.
# 1. Login and capture token
TOKEN=$(curl -s -X POST "$BANKOPS_API_URL/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"username":"'$BANKOPS_USERNAME'","password":"'$BANKOPS_PASSWORD'"}' \
| python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")
# 2. Download the schema reference
curl -s "$BANKOPS_API_URL/developers/schema.md" -o schema.md
# 3. Download the example deck
curl -s "$BANKOPS_API_URL/developers/example-deck.json" -o example-deck.json
# 4. PATCH presentation with your deck JSON
curl -X PATCH "$BANKOPS_API_URL/api/presentations/YOUR_PRESENTATION_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Q1 Review",
"content": {
"style": "corporate",
"slides": [
{
"type": "title",
"title": "Q1 Business Review",
"subtitle": "A-1 Investment Bank"
},
{
"type": "grid",
"$template": "dashboard",
"$templateData": {
"title": "Financial Summary",
"kpis": [
{ "value": "$42M", "label": "Revenue" },
{ "value": "68%", "label": "Margin" }
],
"leftPanel": {
"header": "Trend",
"content": {
"type": "chart",
"chartType": "bar",
"categories": ["Q1","Q2","Q3","Q4"],
"series": [{"name":"Rev","data":[35,38,40,42]}]
}
},
"rightPanel": {
"header": "Segments",
"content": {
"type": "table",
"data": {
"headers": ["Segment","Rev"],
"rows": [["Enterprise","$24M"],["SMB","$6M"]]
}
}
}
}
}
]
}
}'
# 5. Verify
curl -s "$BANKOPS_API_URL/api/presentations/YOUR_PRESENTATION_ID" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool