MostlyRender

Batch

POST /v1/renders/batch renders up to 50 images in a single request. Items run concurrently and are metered per item; a failure on one item never aborts the others.

# Two shapes

One template, many modification sets — the common case:

bash
curl https://api.mostlyrender.com/v1/renders/batch \
  -H "Authorization: Bearer mr_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "tpl_abc",
    "output": "png",
    "items": [
      { "title": "One" },
      { "title": "Two" },
      { "title": "Three" }
    ]
  }'

Each item is a modifications object, or { "modifications": {…}, "output": "…" } to override the format per item.

Heterogeneous renders — different templates in one call:

json
{
  "renders": [
    { "template": "tpl_a", "modifications": { "title": "A" }, "output": "png" },
    { "template": "tpl_b", "modifications": { "title": "B" }, "output": "pdf" }
  ]
}

# Merge into one multi-page PDF

Add merge: true to render every item as a page and stitch them into a single multi-page PDF — the path for legal docs, reports, and other multi-page documents:

json
{
  "template": "tpl_report",
  "merge": true,
  "items": [
    { "title": "Cover" },
    { "title": "Summary" },
    { "title": "Appendix" }
  ]
}

Instead of per-item results you get one document:

json
{ "id": "rnd_doc", "url": "https://img.mostlyrender.com/mostlyrender/renders/rnd_doc.pdf", "output": "pdf", "pages": 3 }

# Response

Without merge, results are positional — one entry per item:

json
{
  "results": [
    { "id": "rnd_1", "url": "https://img.mostlyrender.com/mostlyrender/renders/rnd_1.png", "output": "png" },
    { "error": "render failed" }
  ],
  "count": 2,
  "ok": 1
}

results is positional — each entry is either a render result or an { "error" } object. count is the total processed; ok is how many succeeded.

# Node SDK

js
const res = await mr.renderBatch({
  templateId: 'tpl_abc',
  output: 'png',
  items: [{ title: 'One' }, { title: 'Two' }, { title: 'Three' }],
});
console.log(res.count, res.ok);

For batches larger than 50, don’t split them into many requests. Use a generator: upload rows (up to 1,000 inline or 10,000 from a CSV) and it renders them as a background job with a dry run first, upserts by row key (unchanged rows are skipped and free), retries failures, and gives you a manifest, an optional zip or merged PDF, and a webhook when it finishes. For a handful of renders that need a result right now, keep using this endpoint, or async jobs for single renders.