Skip to main content

Documentation Index

Fetch the complete documentation index at: https://duomi.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Presentation Generation

Generation turns an analyzed template slide into a real .pptx. The template provides the visual system. Your request provides the content, the layout payload, and any overrides you want to apply.
Run template analysis first. Generation uses each slide’s analyzed slideId as template_slide_id.

1. Supported Layouts

Layouts describe how content is arranged on the slide. Your template should contain a slide that structurally matches one of these patterns.
LayoutPayload shape
Title / text slidetitle, subtitle, optional text blocks
Single tableOne table block
Table + textOne table block plus one or more text blocks
Single chartOne chart block
AgendaOne agenda block
Two-column table + chartcontent as two columns; one side table, one side chart
Two-column table + tablecontent as two columns; both sides table
Do not use a two-column content array for arbitrary layouts. The current renderer routes two-column content for table + chart and table + table layouts; chart + chart and text + text are not treated as distinct left/right content regions. The sections below describe the content blocks used inside those layouts.

2. Content Blocks

Content blocks are the JSON objects placed inside slide_data.content.blocks. Use them to fill the matching regions in a template slide.
BlockUse it forDetails
textSection headers, paragraphs, bullets, and supporting copyText Blocks
tableRow-and-column data, logos, table styling, conditional formatting, and paginationTable Blocks
chartBar and column charts with categories, series, axes, legends, labels, and data rowsChart Blocks
agendaAgenda slides with section labels and an active sectionSlide Input
For a single-column layout, content is one column object:
{
  "content": {
    "blocks": [
      { "type": "text", "text": { "bullets": ["Point 1", "Point 2"] } }
    ]
  }
}
In a text block, bullets is an array of strings. Each string renders as one bullet paragraph in the matching text region. For a two-column layout, content is an array of column objects. The optional column header is only used by two-column templates that include header textboxes marked LHS_header and RHS_header, where LHS means left-hand side and RHS means right-hand side.
{
  "content": [
    {
      "header": "Renewal pipeline",
      "blocks": [
        { "type": "table", "table": { "table": { "rows": [] } } }
      ]
    },
    {
      "header": "ARR at risk",
      "blocks": [
        { "type": "chart", "chart": { "categories": [], "series": [] } }
      ]
    }
  ]
}

Table Blocks

Author table rows, dynamic columns, logos, reusable styles, conditional formatting, and pagination.

Chart Blocks

Author bar and column charts with series, axes, legends, labels, and data rows.

Text Blocks

Author slide text, text sections, bullets, and formatting overrides.

3. Template Inheritance

By default, generation inherits from the template. If you omit formatting fields, the renderer uses the fonts, sizes, colors, table styling, chart presets, placeholder positions, and master layouts already encoded in the .pptx. Use overrides only where the generated content needs to differ from the template.
If you sendResult
No formattingTemplate styling is used wherever available
Partial formattingSpecified fields override; unspecified fields continue to inherit where supported
Full formattingPayload controls that element’s font, size, color, emphasis, or cell styling
The common pattern is: let the template carry the brand, then override only data-driven styling such as status colors, risk flags, chart series colors, or one-off title sizing.

4. Generate Slides

There are two generation modes:
ModeEndpointUse when
Single slidePOST /api/v1/presentations/generateYou need one logical slide generated as an async job
DeckPOST /api/v1/presentations/generate-deckYou need multiple slides in one .pptx
Both modes use the same slide object shape:
{
  "template_slide_id": "slide_a3f81c92",
  "slide_data": {},
  "options": {}
}
FieldWhat it controls
template_slide_idWhich analyzed template slide to clone and populate
slide_dataThe content and optional formatting for that slide
optionsPagination, font-fit, footer, and slide-number behavior
For layout guidance, option fields, defaults, and deck inheritance rules, see Layout & Rendering Controls.

What you can specify in slide_data

AreaFields
Slide texttitle, subtitle, footer, footnote
Text blocksSingle-column: content.blocks[].text.{header,text,bullets}. Two-column: content[].blocks[].text.{header,text,bullets}
Text formattingslide_format.title, slide_format.subtitle, slide_format.body, slide_format.textbox.{header,text,bullets}, plus text-block header_format, text_format, bullets_format
Tablesrows, rows[].cells, row is_header, cell value, cell is_logo, multi-paragraph or bullet cell values, column_configs
Table formattingtable_format, format_templates, format_template references from cells, paragraphs, or column_configs[], conditional rules, text formatting, and cell formatting
ChartsBar/column chart fields: chart_type, categories, series[].{name,values,color}, title, title_format, legend, value_axis, category_axis, value_axis_unit, caption, show_bar_labels, show_data_table, data_rows, data_table_header_column, data_table_format
Agendasections, active_index, active_font_color, active_bold, active_underline
Formatting objects commonly accept:
{
  "font_name": "Arial",
  "font_size": 12,
  "bold": true,
  "italic": false,
  "color": "#333333",
  "alignment": "left",
  "line_spacing": 1.2
}

Generate One Slide

Use generate for one logical slide. The endpoint returns immediately with a generation_id; poll status until the generated file is ready.
POST /api/v1/presentations/generate
X-API-Key: your-api-key
Content-Type: application/json

{
  "template_slide_id": "slide_customer_health_table",
  "slide_data": {
    "title": "Customer Health Overview",
    "footnote": "Source: CRM export, April 2026",
    "slide_format": {
      "title": {
        "font_name": "Arial",
        "font_size": 30,
        "bold": true,
        "color": "#111827"
      }
    },
    "content": {
      "blocks": [
        {
          "type": "table",
          "table": {
            "table": {
              "format_templates": {
                "health_score": {
                  "rules": [
                    {
                      "condition": { "field": "value", "operator": "greater_than_or_equal", "value": 8 },
                      "cell": { "background_color": "#E7F4EE" },
                      "text": { "bold": true, "color": "#0F5132" }
                    },
                    {
                      "condition": { "field": "value", "operator": "less_than", "value": 6 },
                      "cell": { "background_color": "#FDECEC" },
                      "text": { "bold": true, "color": "#842029" }
                    }
                  ]
                }
              },
              "column_configs": [
                { "column_index": 2, "format_template": "health_score" }
              ],
              "rows": [
                {
                  "is_header": true,
                  "cells": [
                    { "value": "Company" },
                    { "value": "Owner" },
                    { "value": "Health" },
                    { "value": "Signal" },
                    { "value": "Next step" }
                  ]
                },
                {
                  "cells": [
                    { "value": "stripe.com", "is_logo": true },
                    { "value": "Sarah Chen" },
                    { "value": "9" },
                    { "value": "Expansion-ready" },
                    { "value": "Send pricing proposal" }
                  ]
                }
              ]
            }
          }
        }
      ]
    }
  },
  "options": {
    "auto_paginate_tables": true,
    "table_min_font_size": 8,
    "show_slide_numbers": true,
    "footer_text": "Confidential"
  }
}
Example response:
{
  "generation_id": "gen_def456",
  "status": "pending",
  "message": "Generation started. Poll status URL for progress.",
  "status_url": "https://api.example.com/api/v1/presentations/gen_def456/status",
  "created_at": "2026-04-30T17:35:00Z"
}
The final status response includes total_pages_generated, slide_results, file size, and a signed download_url. total_pages_generated can be greater than 1 when a table-only slide paginates.

Generate a Deck

Use generate-deck for multi-slide output. The endpoint returns immediately with a generation_id; poll status until the deck is ready. Slides render in the same order as the slides array. Each slide can use a different template_slide_id, including slides from different analyzed templates in the same organization.
POST /api/v1/presentations/generate-deck
X-API-Key: your-api-key
Content-Type: application/json

{
  "slides": [
    {
      "template_slide_id": "slide_cover",
      "slide_data": {
        "title": "Q2 2026 Portfolio Review",
        "subtitle": "Investment Committee Draft"
      }
    },
    {
      "template_slide_id": "slide_agenda",
      "slide_data": {
        "title": "Agenda",
        "content": {
          "blocks": [
            {
              "type": "agenda",
              "agenda": {
                "sections": [
                  "Portfolio snapshot",
                  "Customer health",
                  "Renewal outlook",
                  "Action plan"
                ],
                "active_index": 1,
                "active_bold": true,
                "active_underline": true
              }
            }
          ]
        }
      }
    },
    {
      "template_slide_id": "slide_chart_and_table",
      "slide_data": {
        "title": "Renewal Outlook by Cohort",
        "content": [
          {
            "header": "ARR at risk",
            "blocks": [
              {
                "type": "chart",
                "chart": {
                  "chart_type": "stacked_column",
                  "categories": ["Q2", "Q3", "Q4"],
                  "series": [
                    { "name": "Committed", "values": [18.2, 21.4, 24.1], "color": "#0F766E" },
                    { "name": "Upside", "values": [4.5, 3.9, 5.2], "color": "#2563EB" },
                    { "name": "At risk", "values": [2.1, 3.4, 2.8], "color": "#DC2626" }
                  ],
                  "show_bar_labels": true,
                  "value_axis_unit": "$M",
                  "legend": {
                    "position": "bottom",
                    "text_format": { "font_size": 8 }
                  },
                  "data_rows": [
                    ["Total ARR", "$24.8M", "$28.7M", "$32.1M"],
                    ["At-risk %", "8%", "12%", "9%"]
                  ],
                  "data_table_format": {
                    "font_name": "Arial",
                    "font_size": 8,
                    "color": "#333333"
                  }
                }
              }
            ]
          },
          {
            "header": "Management actions",
            "blocks": [
              {
                "type": "table",
                "table": {
                  "table": {
                    "table_format": {
                      "header_row": {
                        "text": { "bold": true, "font_size": 9 },
                        "cell": { "background_color": "#E5E7EB" }
                      },
                      "default": {
                        "text": { "font_size": 8 }
                      }
                    },
                    "rows": [
                      {
                        "is_header": true,
                        "cells": [
                          { "value": "Account group" },
                          { "value": "Action" },
                          { "value": "Owner" }
                        ]
                      },
                      {
                        "cells": [
                          { "value": "Executive sponsor gaps" },
                          { "value": "Schedule renewal risk review" },
                          { "value": "CS leadership" }
                        ]
                      },
                      {
                        "cells": [
                          { "value": "Q3 renewals" },
                          { "value": "Pull forward adoption readout" },
                          { "value": "Product strategy" }
                        ]
                      }
                    ]
                  }
                }
              }
            ]
          }
        ]
      },
      "options": {
        "auto_paginate_tables": false,
        "table_min_font_size": 7,
        "textbox_min_font_size": 8
      }
    }
  ],
  "options": {
    "auto_paginate_tables": true,
    "show_slide_numbers": true,
    "footer_text": "Confidential",
    "footer_font_size": 8,
    "footer_font_name": "Arial",
    "table_min_font_size": 8,
    "textbox_min_font_size": 8
  }
}
Example response:
{
  "generation_id": "gen_ghi789",
  "status": "pending",
  "message": "Generation started. Poll status URL for progress.",
  "status_url": "https://api.example.com/api/v1/presentations/gen_ghi789/status",
  "created_at": "2026-04-30T17:40:00Z"
}

Poll Status

GET /api/v1/presentations/{generation_id}/status
X-API-Key: your-api-key
Poll every 2 to 5 seconds until status is terminal.
StatusMeaning
pendingRequest is queued
processingSlides are being rendered
completedEvery requested slide succeeded
partialSome slides succeeded and some failed
failedNo usable deck was generated
Completed example:
{
  "generation_id": "gen_ghi789",
  "status": "completed",
  "progress": 100,
  "message": "Generated 4 pages from 3/3 slides",
  "total_slides_requested": 3,
  "total_pages_generated": 4,
  "slide_results": [
    { "slide_index": 0, "template_slide_id": "slide_cover", "pages_generated": 1, "status": "completed", "error": null },
    { "slide_index": 1, "template_slide_id": "slide_agenda", "pages_generated": 1, "status": "completed", "error": null },
    { "slide_index": 2, "template_slide_id": "slide_chart_and_table", "pages_generated": 2, "status": "completed", "error": null }
  ],
  "file_size": 7450000,
  "download_url": "https://storage.example.com/download/gen_ghi789.pptx?token=...",
  "download_url_expires_in": 3600
}
Always inspect slide_results for async deck jobs. A partial result can still include a downloadable .pptx.

Download

Use the signed download_url when available. To download through the API instead:
GET /api/v1/presentations/{presentation_id}/download
X-API-Key: your-api-key
presentation_id can be either:
  • gen_xxx from slide generation
  • gen_xxx from deck generation
  • pres_xxx from older direct-return generation output, if present
For generation jobs, download is available after status is completed or partial.

Page Counts and Indexes

Pagination can make output slide counts differ from request slide counts:
  • total_slides_requested is the number of logical slides in the request.
  • total_pages_generated is the number of actual PowerPoint slides in the output file.
  • slide_results[].pages_generated tells you which logical slides expanded.
  • Chart update slide_index values refer to the output presentation, so paginated table-only slides can shift later indexes.

Table Blocks

Rows, cells, logos, reusable styles, conditional formatting, and pagination.

Chart Blocks

Chart types, categories, series, legends, axes, labels, and data rows.

Text Blocks

Slide text, text sections, bullets, and formatting overrides.

Slide Input

Full JSON shapes for text, tables, charts, agendas, and formatting.

Layout & Rendering Controls

Layout compatibility, aspect ratio, pagination, fitting, footers, and slide numbers.

Examples

Complete payloads for common slide and deck patterns.