Render a Slide from a Template

Deterministic rendering from a template. The same input always produces the same output. Use this for KPI dashboards, timelines, comparisons, SWOT, and any other slide type covered by the 50 built-in templates. For custom layouts where no template fits, use POST /v1/generate instead.

Two paths based on your input

200 sync

template + params

0 LLM calls. <1s, $0.03. Response contains pptx_url directly — no polling.

202 async

template + brief

1 LLM call (extraction). ~2s, $0.05. Poll GET /v1/jobs/{id} for result.

202 async

template + brief + enrich

2 LLM calls. ~3s, $0.07. Fills gaps in terse briefs before extraction.

POST/v1/render

Render a consulting-quality slide from a template. Provide structured params for instant synchronous output, or a natural language brief for LLM-assisted extraction.

Parameters

NameTypeRequiredDescription
templatestringrequiredTemplate UUID. Get IDs from POST /v1/templates/search or GET /v1/templates.
paramsobjectoptionalStructured data matching the template schema. Triggers synchronous 200 response — no polling needed. Get the schema from GET /v1/templates/{id}.
briefstringoptionalNatural language description. LLM extracts params and chrome automatically (~2s). Required if params is omitted.
enrichbooleanoptionalEnrich a terse brief before extraction. Adds a second LLM call to fill schema gaps (~3s, $0.07). Default: false.
theme_idstringoptionalTheme identifier. Built-in: "consulting_blue", "consulting_dark", "consulting_light". Or a saved custom theme ID.
chromeobjectoptionalSlide chrome overrides: {title, subtitle, kicker, footer, source, page_number, classification}.
namestringoptionalHuman-readable name for the slide. Auto-generated if omitted.

Response

200
{
  "job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "complete",
  "pptx_url": "/v1/files/user123/slides/job456.pptx?sig=abc&exp=1711036800&name=Q1+Performance",
  "preview_url": "/v1/files/user123/previews/job456.png?sig=def&exp=1711036800",
  "cost_charged": 0.03,
  "latency_ms": 407
}

Examples

curl -X POST https://api.slideforge.dev/v1/render \
  -H "Authorization: Bearer sf_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "cbddc7b0-1234-5678-abcd-ef1234567890",
    "params": {
      "title": "Q1 2026 Performance",
      "metrics": [
        {"value": "$12.4M", "label": "Revenue", "trend": "+18% YoY", "trend_dir": "up"},
        {"value": "847", "label": "New Clients", "trend": "+23%", "trend_dir": "up"}
      ],
      "takeaway": "Strongest quarter since launch"
    },
    "theme_id": "consulting_blue",
    "chrome": {"footer": "Confidential", "page_number": 5}
  }'

Brief path response (202)

When only brief is provided, the endpoint returns 202 and the job runs async. Poll GET /v1/jobs/{job_id} until status is complete.

{
  "job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "queued"
}

Finding templates

Use POST /v1/templates/suggest to find the best template for a brief, or GET /v1/templates to browse all 50 templates. Use GET /v1/templates/{id} to get the full param schema before passing structured data.

POST/v1/render/spec

Render a slide from a declarative JSON spec using CSS Flexbox layout and design system components (Metric, BarList, Table, etc.). Deterministic, <1s, $0.05. No LLM, no sandbox. Use suggest-layout to generate a spec from a brief.

Parameters

NameTypeRequiredDescription
specobjectrequiredSlide spec with chrome (title, subtitle, footer), body (component or flex container tree), takeaway, and annotations.
theme_idstringoptionalTheme identifier.
namestringoptionalHuman-readable slide name.

Response

200
{
  "job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "complete",
  "pptx_url": "/v1/files/user123/slides/job456.pptx?sig=abc&exp=1711036800&name=Q1+Performance",
  "preview_url": "/v1/files/user123/previews/job456.png?sig=def&exp=1711036800",
  "cost_charged": 0.03,
  "latency_ms": 407
}

Examples

curl -X POST https://api.slideforge.dev/v1/render/spec \
  -H "Authorization: Bearer sf_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "spec": {
      "chrome": {"title": "Q1 KPIs", "subtitle": "Executive Summary"},
      "body": {
        "display": "flex",
        "direction": "row",
        "gap": 20,
        "children": [
          {"component": "Metric", "params": {"metrics": [
            {"value": "$12.4M", "label": "Revenue", "trend": "+18%", "trend_dir": "up"},
            {"value": "847", "label": "New Clients", "trend": "+23%", "trend_dir": "up"}
          ]}},
          {"component": "BarList", "params": {"items": [
            {"name": "Enterprise", "value": 64},
            {"name": "Mid-Market", "value": 28},
            {"name": "SMB", "value": 8}
          ], "title": "Revenue Mix (%)"}}
        ]
      }
    },
    "theme_id": "consulting_blue"
  }'

POST /v1/render/preflight

Validate a template + params combination without rendering or charging. Returns ok: true if params match the schema, or an error with the same detail an actual render would emit. Free.

curl -X POST https://api.slideforge.dev/v1/render/preflight \
  -H "Authorization: Bearer sf_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"template": "cbddc7b0-...", "params": {"title": "Test", "metrics": []}}'

# Returns: {"ok": true} or error with validation details

POST /v1/suggest-layout

Takes a natural language brief and returns a JSON spec ready for POST /v1/render/spec. Uses an LLM to select the right components and compose a flex layout. ~1-5s. Free — no charge for suggestions.

curl -X POST https://api.slideforge.dev/v1/suggest-layout \
  -H "Authorization: Bearer sf_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"brief": "Q1 dashboard with 4 KPIs and a bar chart of revenue by segment"}'

# Returns: a full JSON spec ready for POST /v1/render/spec