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
template + params
0 LLM calls. <1s, $0.03. Response contains pptx_url directly — no polling.
template + brief
1 LLM call (extraction). ~2s, $0.05. Poll GET /v1/jobs/{id} for result.
template + brief + enrich
2 LLM calls. ~3s, $0.07. Fills gaps in terse briefs before extraction.
/v1/renderRender a consulting-quality slide from a template. Provide structured params for instant synchronous output, or a natural language brief for LLM-assisted extraction.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| template | string | required | Template UUID. Get IDs from POST /v1/templates/search or GET /v1/templates. |
| params | object | optional | Structured data matching the template schema. Triggers synchronous 200 response — no polling needed. Get the schema from GET /v1/templates/{id}. |
| brief | string | optional | Natural language description. LLM extracts params and chrome automatically (~2s). Required if params is omitted. |
| enrich | boolean | optional | Enrich a terse brief before extraction. Adds a second LLM call to fill schema gaps (~3s, $0.07). Default: false. |
| theme_id | string | optional | Theme identifier. Built-in: "consulting_blue", "consulting_dark", "consulting_light". Or a saved custom theme ID. |
| chrome | object | optional | Slide chrome overrides: {title, subtitle, kicker, footer, source, page_number, classification}. |
| name | string | optional | Human-readable name for the slide. Auto-generated if omitted. |
Response
{
"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.
/v1/render/specRender 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
| Name | Type | Required | Description |
|---|---|---|---|
| spec | object | required | Slide spec with chrome (title, subtitle, footer), body (component or flex container tree), takeaway, and annotations. |
| theme_id | string | optional | Theme identifier. |
| name | string | optional | Human-readable slide name. |
Response
{
"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 detailsPOST /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