MintRender
All docs pages

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 typeValueSetsExample
texttext or a numbertext"title": "Ten ways to sell more"
imagea URL or asset:<id>src"photo": "https://example.com/a.jpg"
shapea colourfill"badge": "#16a34a"
qrtext or a numbervalue"qr": "https://example.com/t/123"
barcodetext or a numbervalue"code": "4006381333931"
charta numberchart.value (progress, number)"score": 72
charta list of numberschart.series: one series with these values"sales": [3, 5, 8]
any typetrue or falsevisible"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, labels and so on) go into chart, and other keys (x, visible) go onto the layer. series is replaced whole.
  • A new text size moves minSize and maxSize with it, unless you set them too.
  • The fields id, type, param, name, locked and a group's layers cannot 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_param that names it. Send "ignore_unknown": true to 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 use asset:<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 has markup: 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_…"}}
StatusCodeWhen
400unknown_paramA key matches no param (on that page, for a page key).
400invalid_paramA value does not fit the layer, a field cannot be changed, or the scene breaks a rule after the merge.
400url_refused, url_failedAn image URL cannot be fetched.
400unsupported_typeAn image URL is not a PNG, JPEG, GIF or WebP.
400image_too_largeAn 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.