Templates / Manual
Manual
Product or process manual with a cover, table of contents, numbered chapters and step lists from JSON. Everything an agent needs to turn notes into a document people will actually read.
3 pages, A4. Rendered in 27 ms. 7 inputs, all optional.
Inputs
Everything variable comes in through sys.inputs. Missing keys fall back to sensible defaults, so an agent can send only what it knows.
| Key | Sample value |
|---|---|
chapters | JSON, 948 chars |
company | Meridian Studio GmbH |
logo | logo.png |
product | Meridian Desk Lamp M1 |
subtitle | Assembly, use and care |
support | support@meridian.example · +49 30 1234 567 |
version | Rev. 2, September 2026 |
Render it
After copying the template into your account:
curl -X POST https://api.foliant.dev/v1/render \
-H "Authorization: Bearer $FOLIANT_API_KEY" \
-H "Content-Type: application/json" \
-o manual.pdf -d @- <<'JSON'
{ "template": "manual.typ",
"inputs": {
"chapters": "[{\"title\":\"Safety\",\"intro\":\"Read this section before first use.\",\"steps\":[\"Use only the supplied 12 V adapter.\",\"Keep the lamp head at least 20 cm away from flammable material.\",\"Do not open the housing; there are no user-serviceable parts inside.\"]},{\"title\":\"Assembly\",\"intro\":\"The lamp arrives in three parts: base, arm and head.\",\"steps\":[\"Place the base on a flat surface and tighten the clamp screw by hand.\",\"Insert the arm into the base until it clicks.\",\"Attach the head to the arm and route the cable through the guide.\",\"Connect the adapter. The ring light blinks once when power is present.\"]},{\"title\":\"Daily use\",\"intro\":\"\",\"steps\":[\"Tap the ring once to switch on, twice to switch off.\",\"Hold the ring to dim; release at the desired level.\",\"The lamp remembers the last brightness.\"]},{\"title\":\"Care\",\"intro\":\"\",\"steps\":[\"Wipe with a dry cloth. No solvents.\",\"Replace the adapter only with the original part, article MS-1001-PSU.\"]}]",
"company": "Meridian Studio GmbH",
"logo": "logo.png",
"product": "Meridian Desk Lamp M1",
"subtitle": "Assembly, use and care",
"support": "support@meridian.example · +49 30 1234 567",
"version": "Rev. 2, September 2026"
} }
JSON
Through MCP, render_document with template: "manual.typ" and the same inputs; get_template or fetch lists the keys.
Source
template.typ, 34 lines
#let input(k, default: "") = sys.inputs.at(k, default: default)
#let chapters = json(bytes(input("chapters", default: "[]")))
#let logo = input("logo")
#set page(paper: "a4", margin: (top: 24mm, bottom: 24mm, x: 24mm),
footer: context if counter(page).get().first() > 1 [#set text(size: 8.5pt, fill: luma(110)); #input("product") · #input("version") #h(1fr) #counter(page).display()])
#set text(font: "Noto Sans", size: 10.5pt, fill: rgb("1a1917"))
#set heading(numbering: "1.")
#show heading.where(level: 1): it => block(above: 10mm, below: 4mm)[#text(size: 18pt, weight: 700)[#counter(heading).display() #h(5pt) #it.body]]
#show outline.entry: it => text(size: 11pt)[#it]
// Cover
#v(1fr)
#if logo != "" { image(logo, width: 44mm) }
#v(12mm)
#text(size: 30pt, weight: 700)[#input("product")]
#v(3mm)
#text(size: 14pt, fill: luma(110))[#input("subtitle")]
#v(1fr)
#text(size: 9.5pt, fill: luma(110))[#input("company") · #input("version")]
#pagebreak()
#text(size: 18pt, weight: 700)[Contents]
#v(4mm)
#outline(title: none, indent: auto)
#pagebreak()
#for ch in chapters [
= #ch.title
#if ch.intro != "" [#ch.intro #v(2mm)]
#enum(tight: false, spacing: 3mm, ..ch.steps.map(s => [#s]))
]
#v(10mm)
#block(fill: rgb("f3efe6"), inset: 12pt, width: 100%, radius: 2pt)[*Support* \ #input("support")]