Template data
data is an object of param names and values. Each key changes every layer that has that param. A short value sets the main field of the layer. An object sets any field you name.
Find the params
In the editor, turn on "Changeable" for a layer and give it a name. The name is the param. GET /v1/templates/{id} lists the params with their type, pages and default value. The editor's Code panel shows a call with all of them.
Short values
| Layer type | Value | Sets | Example |
|---|---|---|---|
| text | text or a number | text | "title": "Ten ways to sell more" |
| image | a URL or asset:<id> | src | "photo": "https://example.com/a.jpg" |
| shape | a colour | fill | "badge": "#16a34a" |
| qr | text or a number | value | "qr": "https://example.com/t/123" |
| barcode | text or a number | value | "code": "4006381333931" |
| chart | a number | chart.value (progress, number) | "score": 72 |
| chart | a list of numbers | chart.series: one series with these values | "sales": [3, 5, 8] |
| any type | true or false | visible | "ribbon": false |
A group takes only true, false or an object. null and other kinds of value are a 400 that says what the layer takes.
Objects of fields
An object sets several fields of the layer at once. Its keys are the layer's fields from the field tables:
"data": { "title": { "text": "Hello", "color": "#ef4444", "size": 64, "align": "center" }, "photo": { "src": "https://example.com/a.jpg", "fit": "contain", "radius": 24 }, "logo": { "x": 900, "y": 40, "opacity": 0.8 }, "sales": { "kind": "line", "series": [{ "name": "2026", "values": [4, 6, 9] }], "labels": ["Q1", "Q2", "Q3"] }}- For a chart, keys of the chart (
kind,series,labelsand so on) go intochart, and other keys (x,visible) go onto the layer.seriesis replaced whole. - A new text
sizemovesminSizeandmaxSizewith it, unless you set them too. - The fields
id,type,param,name,lockedand a group'slayerscannot be changed by data.
Pages
A plain key sets the param on every page that has it. A key like page2.title sets page 2 only (pages count from 1) and wins over the plain key for that page:
"data": { "name": "Ada Lovelace", "page2.name": "A. Lovelace"}Rules
- A key that matches no param is a 400
unknown_paramthat names it. Send"ignore_unknown": trueto skip such keys, for example when your data has more fields than the template. - Keys that you do not send keep the template's values.
- After the merge, the whole scene is checked again. A value that breaks a rule (for example a minSize over the new size) is a 400 whose message starts with "after the data merge".
- Image URLs in data are fetched by us when the render runs: PNG, JPEG, GIF or WebP, at most 20 MB and 16 megapixels, answering within 10 seconds with at most 3 redirects. One render can use at most 20 different image URLs (400
limit). For an SVG, upload it as an asset and useasset:<id>. - In signed links and CSV files every value is text. Text, image, shape, QR and barcode params work. Charts need numbers, so use the API's JSON for them.
- Text from data is drawn as typed.
*and{become markup only when the layer hasmarkup: true.
A full example
One render that uses each kind of value:
curl
curl -X POST "https://mintrender.com/v1/render" \ -H "Authorization: Bearer $MINTRENDER_KEY" \ -H "Content-Type: application/json" \ -d '{"template":"tpl_3k2jQ8xLm0P4nB7vR2sT","data":{"title":"Spring sale: 30% off","subtitle":{"text":"Only this week","color":"#f59e0b","size":40},"photo":"https://example.com/shoe.jpg","logo":"asset:img_9Lk2mQ8xP0aB4nC7vR2s","badge":"#16a34a","price":49,"qr":"https://example.com/p/123","chart":[3,5,8,13],"ribbon":false,"page2.title":"Terms"},"format":"png"}'JavaScript
const res = await fetch("https://mintrender.com/v1/render", { method: "POST", headers: { Authorization: `Bearer ${process.env.MINTRENDER_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ template: "tpl_3k2jQ8xLm0P4nB7vR2sT", data: { title: "Spring sale: 30% off", subtitle: { text: "Only this week", color: "#f59e0b", size: 40, }, photo: "https://example.com/shoe.jpg", logo: "asset:img_9Lk2mQ8xP0aB4nC7vR2s", badge: "#16a34a", price: 49, qr: "https://example.com/p/123", chart: [3, 5, 8, 13], ribbon: false, "page2.title": "Terms", }, format: "png", }),});const body = await res.json();if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message} (${body.error.request_id})`);console.log(body);Python
import os import requests res = requests.post( "https://mintrender.com/v1/render", headers={"Authorization": f"Bearer {os.environ['MINTRENDER_KEY']}"}, json={ "template": "tpl_3k2jQ8xLm0P4nB7vR2sT", "data": { "title": "Spring sale: 30% off", "subtitle": { "text": "Only this week", "color": "#f59e0b", "size": 40, }, "photo": "https://example.com/shoe.jpg", "logo": "asset:img_9Lk2mQ8xP0aB4nC7vR2s", "badge": "#16a34a", "price": 49, "qr": "https://example.com/p/123", "chart": [3, 5, 8, 13], "ribbon": False, "page2.title": "Terms", }, "format": "png", }, timeout=120,)body = res.json()if not res.ok: raise RuntimeError(f"{body['error']['code']}: {body['error']['message']} ({body['error']['request_id']})")print(body)Errors
Errors name the data field, so you can show them next to the input:
{"error": {"code": "invalid_param", "message": "must be a hex colour like #0f172a, or transparent", "field": "data.subtitle.color", "request_id": "req_…"}}{"error": {"code": "unknown_param", "message": "no layer has the param \"subtitel\"", "field": "data.subtitel", "request_id": "req_…"}}{"error": {"code": "invalid_param", "message": "cannot be changed by data", "field": "data.title.id", "request_id": "req_…"}}| Status | Code | When |
|---|---|---|
| 400 | unknown_param | A key matches no param (on that page, for a page key). |
| 400 | invalid_param | A value does not fit the layer, a field cannot be changed, or the scene breaks a rule after the merge. |
| 400 | url_refused, url_failed | An image URL cannot be fetched. |
| 400 | unsupported_type | An image URL is not a PNG, JPEG, GIF or WebP. |
| 400 | image_too_large | An image URL is over 16 megapixels. |
Seen MintRender used for content that breaks our terms? Report it. Questions about the API: support@mintrender.com, with the request id.