Documentation
Templates & styles
A template is a reusable, named style option: a base theme plus a few tweaks (accent colour, fonts) and a page format. Render with one and every document comes out on-brand and consistent.
template = base theme + style overrides (accent, fonts) + page formatYou reference a template by its slug or id when rendering — via the REST API, an MCP create_pdf call, or the dashboard editor.
Base themes
Five built-in themes ship with every deployment (web, API, MCP). They're bundled modules, so they're identical everywhere.
| Theme | Look |
|---|---|
default | Clean, versatile document style — the fallback for everything. |
editorial | Long-form magazine feel — display serifs, generous measure. |
minimal | Airy Swiss product-doc look — lots of whitespace. |
technical | Dense developer-docs look — grid tables, monospace headings. |
bold | High-impact pitch/report look — heavy headings, punchy accents. |
Use a theme directly on a render with theme: "editorial", or as the base for a template.
Style overrides
Templates layer a small, sanitized set of tweaks over the base theme. Only these fields exist, and each is validated before it touches the CSS:
| Field | Value | Notes |
|---|---|---|
accent | hex colour | e.g. #2f5d50. 3-, 6-, or 8-digit hex. A soft tint is derived automatically for blockquotes, zebra rows, and table heads. |
fontBody | font preset key | Body text. |
fontHeading | font preset key | Headings. |
fontMono | font preset key | Code / monospace. |
<style> block, so nothing user-supplied reaches CSS verbatim: the accent must be a hex colour and fonts are mapped through a fixed preset table. Unknown fields are silently dropped.Fonts
Font values are preset keys, not arbitrary font names. There are two groups.
System stacks — always available, no download:
| Key | Family |
|---|---|
serif | Iowan / Palatino / Georgia serif stack |
sans | System UI sans stack (San Francisco / Segoe / Roboto) |
slab | Roboto Slab / Rockwell slab stack |
mono | SF Mono / JetBrains Mono / Menlo mono stack |
Self-hosted Google fonts — embedded into the PDF as @font-face (only the fonts a render actually uses are embedded):
| Key | Family | Category |
|---|---|---|
inter | Inter | sans |
roboto | Roboto | sans |
opensans | Open Sans | sans |
lato | Lato | sans |
montserrat | Montserrat | sans |
poppins | Poppins | sans |
merriweather | Merriweather | serif |
lora | Lora | serif |
playfair | Playfair Display | display serif |
robotomono | Roboto Mono | mono |
Formats
| Format | Size |
|---|---|
A4 | 210 × 297 mm (default) |
Letter | US Letter |
Legal | US Legal |
Built-in templates
Every deployment ships these ready-to-use system templates. Render with any slug directly — no setup. (They're read-only starting points; fork/clone in the dashboard to customise.)
| Slug | Theme | Format | Accent | Fonts (heading / body) |
|---|---|---|---|---|
quarterly-report | default | A4 | #14463A | sans / serif |
sales-proposal | default | A4 | #1F6FEB | sans / sans |
investor-update | default | Letter | #6A3FA9 | slab / serif |
onboarding-guide | default | A4 | #C2972A | sans / sans |
technical-manual | default | A4 | #0F766E | mono / sans |
case-study | default | A4 | #B4432F | slab / serif |
meeting-minutes | default | Letter | #334155 | sans / sans |
legal-brief | default | Legal | #6D2932 | serif / serif |
whitepaper | editorial | A4 | #7A5C3E | playfair / merriweather |
editorial-letter | editorial | A4 | #8C2F39 | playfair / lora |
annual-letter | editorial | Letter | #35524A | playfair / merriweather |
product-brief | minimal | A4 | #3B5BDB | inter / inter |
design-spec | minimal | A4 | #0EA5A4 | montserrat / opensans |
one-pager | minimal | Letter | #111827 | inter / inter |
api-reference | technical | A4 | #2563EB | robotomono / inter |
runbook | technical | A4 | #0F766E | mono / roboto |
release-notes | technical | Letter | #7C3AED | robotomono / inter |
pitch-handout | bold | A4 | #C2410C | poppins / inter |
impact-report | bold | A4 | #1D4ED8 | montserrat / lato |
executive-summary | bold | Letter | #BE123C | poppins / inter |
List them live (plus your own) with GET /api/v1/templates or the MCP list_templates tool.
Creating templates
Three ways, all producing the same record:
- Dashboard → Templates (
https://inkrun.dev/templates): a visual builder for theme, accent, fonts, and format. - REST API →
POST /api/v1/templates— see API · Templates. - MCP → the
create_templatetool, then render with the returned slug.
curl "https://inkrun.dev/api/v1/templates" \
-H "Authorization: Bearer $INKRUN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Proposal",
"themeName": "default",
"format": "A4",
"styles": { "accent": "#1F6FEB", "fontHeading": "sans", "fontBody": "serif" }
}'Style precedence (how the CSS layers)
At render time the CSS is composed in this order (later wins):
base theme CSS < custom-theme tokens < template style overridesAnd at the request level, an explicit theme/format on the render call overrides whatever the template specifies. Style overrides work by injecting a :root { --accent: …; --font-body: …; } block after the theme CSS, so they win by source order — the built-in themes are driven entirely by these CSS variables.
Custom themes & cover pages
Beyond the tweakable style options, the dashboard (Themes, https://inkrun.dev/themes) lets you fork a built-in theme into a fully custom one:
- Theme tokens — palette, typography, headings, spacing, page margins, and header/footer, edited visually. (Hex-only colours and preset fonts — no raw CSS, by design.)
- Cover page — an optional designed first page built in a visual editor. Placeholders (e.g. title, subtitle) are filled from the document's frontmatter. Cover images are validated raster data (PNG/JPG, ≤300 KB; no SVG) and the cover renders full-bleed.
A custom theme has its own slug/id (thm_…). Render on it directly (theme: "my-brand"), or base a template on it (themeName: "my-brand").
Frontmatter
A leading --- YAML block is stripped before rendering and used to fill cover placeholders and the document title:
---
title: Q2 Revenue Report
subtitle: FY2026
---
# Q2 Revenue
Strong quarter…- Scalars only, bounded sizes. Values bind to cover-page placeholders and the PDF
<title>. - The frontmatter
title:is used as the render's title when the request doesn't supply one. - A malformed or oversized block is not swallowed — it renders as ordinary Markdown so you can see it.
Charts
Add a chart by including a fenced code block tagged chart: a key: value settings block, a --- separator, then a GitHub-style Markdown data table.
```chart
type: bar
x: Quarter
y: Revenue, Costs
title: 2026 Performance
stacked: false
---
| Quarter | Revenue | Costs |
| ------- | ------- | ----- |
| Q1 | 120 | 80 |
| Q2 | 180 | 95 |
```Settings
| Key | Values | Notes |
|---|---|---|
type | bar | line | area | pie | Default bar. |
x | column header | Required. Category axis (bar/line/area) or slice label (pie). |
y | one or more headers, comma-separated | Required. Value columns. Pie uses only the first. |
title | text | Optional chart title. |
xLabel / yLabel | text | Optional axis titles. |
height | px | Plot height, clamped 160–760 (default 340). |
stacked | true | yes | 1 | Stack bars/areas (ignored for line/pie). |
Rules
- Every cell under a
ycolumn must be numeric. Thousands separators and trailing units like%or$are tolerated; any non-numericycell makes the whole fence fall back to a plain code block. - At least one data row is required.
- Charts render as static inline SVG sized to fit the page — offline and deterministic, no interactivity.
Over MCP, the get_chart_syntax tool returns this spec verbatim.