Documentation
Generate from a spreadsheet
Have a list of records — one invoice per customer, one certificate per attendee — instead of a single JSON payload? Generate a batch of documents straight from a CSV or Excel file: upload the file, map its columns to the template’s fields, and Ristmark renders one document per row, returned as a single zip.
1. Upload
Open a template and choose Spreadsheet on its row action menu, or Generate from spreadsheet in the modal. Choose a .csv or .xlsx file (10 MB upload ceiling). The file is read immediately in a dry-run preview — no rendering, no billing yet.
Legacy .xls workbooks (the pre-2007 binary format) are not supported. Open one in Excel or LibreOffice and use Save As to save a .xlsx, then upload that.
2. Map columns to fields
The preview lists your file’s columns next to the template’s data fields, auto-mapped by a case-insensitive, trimmed header match (e.g. a column literally named invoiceNo auto-maps to the invoiceNo field). Adjust any mapping by hand where the auto-match missed. A column left unmapped, or a row missing a value for a mapped column, renders as an empty string for that field — never an error.
You’ll see a row count and the resulting generation count before you commit: “N rows detected — this will use N generations.” That is a count of documents, not of credits: each of those documents is then billed by rendered pages, so a 200-row run of 3-page invoices is 200 generations and 400 credits.
3. Generate
Click Generate. Each row renders through the same deterministic engine as every other generation — metered by rendered pages — ½ credit per page, counted per page, exactly like a manual render or a /v1 batch item. The result downloads as a zip: one rendered file per row (named from your chosen filename column, or row-1, row-2, … by default), plus a _manifest.json summarizing the run (requested, succeeded, and a per-row status: ok, error, or quota_exceeded).
Limits
- 200 rows per run is the hard cap — a larger file is rejected up front (a clear error, never a silent truncation to 200); split it into smaller files.
- If your plan’s generation quota runs out mid-run, the run stops there: rows already rendered stay in the zip, and every remaining row is recorded
quota_exceededin the manifest rather than silently dropped. - Unlike the /v1 API, which only generates from approved templates, generating from a spreadsheet in the app works from any of your own templates, approved or still in review — the same posture as a manual in-app render.
See Pricing & limits for what a generation counts against on your plan.