[{"data":1,"prerenderedAt":655},["ShallowReactive",2],{"\u002Fdocs\u002Fautomate-indesign-projects":3},{"id":4,"title":5,"body":6,"category":644,"date":645,"description":646,"extension":647,"heroImage":648,"meta":649,"navigation":282,"path":650,"readingMinutes":330,"seo":651,"stem":652,"tool":653,"__hash__":654},"docs\u002Fdocs\u002Fautomate-indesign-projects.md","Automate InDesign projects",{"type":7,"value":8,"toc":635},"minimark",[9,14,18,26,30,41,46,56,75,81,184,191,198,222,235,239,554,557,563,573,577,591,595,631],[10,11,13],"h2",{"id":12},"the-problem","The problem",[15,16,17],"p",{},"InDesign is a design tool, not a rendering server. The moment you need to generate a hundred name badges, a thousand certificates, or a weekly batch of social posts from one master layout, you're stuck: either someone opens InDesign and does it by hand, or you buy and run InDesign Server — a license, a machine, and an operations burden, just to turn a template into pixels.",[15,19,20,21,25],{},"Bluepic's IDML renderer is a plain HTTP API that does exactly that one job: take an InDesign file (exported as IDML) and a set of field values, and hand back rendered output. No InDesign install, no server to maintain, no license — a ",[22,23,24],"code",{},"POST"," request from wherever your automation already lives (a cron job, a serverless function, a CI pipeline, your app's backend).",[10,27,29],{"id":28},"the-building-blocks","The building blocks",[15,31,32,36,37,40],{},[33,34,35],"strong",{},"1. Export once."," Design your master in InDesign, ",[22,38,39],{},"File → Export → InDesign Markup (IDML)",". This is your template — the thing you POST every time.",[15,42,43],{},[33,44,45],{},"2. Render it.",[47,48,53],"pre",{"className":49,"code":51,"language":52},[50],"language-text","POST https:\u002F\u002Fapi.bluepic.io\u002Fapi\u002Fidml\u002Frender\nAuthorization: \u003Cyour API key>\nContent-Type: multipart\u002Fform-data\n\nidml=@certificate.idml\nassets=@seal.png\nassets=@Signature-Font.ttf\n","text",[22,54,51],{"__ignoreMap":55},"",[15,57,58,59,62,63,66,67,70,71,74],{},"Every asset the IDML links to (images, fonts) goes in a repeated ",[22,60,61],{},"assets"," field, matched back to the document ",[33,64,65],{},"by filename"," — so name each part after what the IDML actually links (",[22,68,69],{},"hero.jpg",", not ",[22,72,73],{},"hero-final-v2.jpg","). Anything you leave out renders as a placeholder rather than failing the request, so partial asset sets are safe to iterate on.",[15,76,77,80],{},[33,78,79],{},"3. Pick your output."," Query parameters control the render:",[82,83,84,97],"table",{},[85,86,87],"thead",{},[88,89,90,94],"tr",{},[91,92,93],"th",{},"Param",[91,95,96],{},"What it does",[98,99,100,124,140,157,170],"tbody",{},[88,101,102,108],{},[103,104,105],"td",{},[22,106,107],{},"format",[103,109,110,113,114,113,117,120,121],{},[22,111,112],{},"png",", ",[22,115,116],{},"jpeg",[22,118,119],{},"pdf"," or ",[22,122,123],{},"svg",[88,125,126,131],{},[103,127,128],{},[22,129,130],{},"pages",[103,132,133,136,137],{},[22,134,135],{},"all",", or a 1-based list like ",[22,138,139],{},"1,3,5",[88,141,142,147],{},[103,143,144],{},[22,145,146],{},"engine",[103,148,149,152,153,156],{},[22,150,151],{},"puppeteer"," (full fidelity — the default) or ",[22,154,155],{},"resvg"," (faster PNG\u002FJPEG, no Chromium)",[88,158,159,164],{},[103,160,161],{},[22,162,163],{},"dpi",[103,165,166,167],{},"Output resolution for raster and PDF, default ",[22,168,169],{},"300",[88,171,172,181],{},[103,173,174,177,178],{},[22,175,176],{},"width"," \u002F ",[22,179,180],{},"height",[103,182,183],{},"Override the rendered size in px",[15,185,186,187,190],{},"Multiple pages come back as a single merged PDF (for ",[22,188,189],{},"format=pdf",") or a zip with one file per page (PNG\u002FJPEG\u002FSVG) — one request, one response, no follow-up polling.",[15,192,193],{},[194,195],"img",{"alt":196,"src":197},"The API playground's Files and Options cards — the same parameters as the table above, live","\u002Fscreenshots\u002Fapi-files-options.png",[15,199,200,203,204,207,208,211,212,217,218,221],{},[33,201,202],{},"4. Fill in the dynamic fields."," This is what turns a converter into automation: ",[22,205,206],{},"textOverrides",", a JSON object of ",[22,209,210],{},"{\"\u003CpageIndex>:\u003CelementId>\": \"value\"}"," pairs. Any text element you name gets replaced; anything you don't name keeps its source value. The ",[213,214,216],"a",{"href":215},"\u002Fidml\u002Fapi","interactive playground"," generates this JSON for you — load your IDML once, type into the fields you want to control, and copy the live-updating ",[22,219,220],{},"curl"," command as your starting point.",[15,223,224,225,229,230,234],{},"One field you'll almost always vary this way is a name — and names vary a lot in length. The text frame's size in InDesign is the hard ceiling any override gets fit inside (it shrinks or wraps, it never grows the frame), so size name\u002Fvalue fields generously for your longest real record, not just your test data. Full detail in ",[213,226,228],{"href":227},"\u002Fdocs\u002Ftext-frames-and-best-practices","Text frames, bounds & best practices",". If a field has mixed formatting inside it, its override needs the array shape from ",[213,231,233],{"href":232},"\u002Fdocs\u002Frichtext-override-format","Rich text format for overrides"," instead of a plain string.",[10,236,238],{"id":237},"a-concrete-pipeline-personalized-certificates","A concrete pipeline: personalized certificates",[47,240,244],{"className":241,"code":242,"language":243,"meta":55,"style":55},"language-js shiki shiki-themes github-dark","const attendees = await getAttendeesFromYourDatabase(); \u002F\u002F [{ name, date, score }, ...]\n\nfor (const attendee of attendees) {\n  const textOverrides = {\n    '0:TextFrame_name': attendee.name,\n    '0:TextFrame_date': attendee.date,\n    '0:TextFrame_score': `${attendee.score}%`,\n  };\n\n  const form = new FormData();\n  form.append('idml', certificateIdml);\n  form.append('assets', sealImage, 'seal.png');\n\n  const res = await fetch(\n    `https:\u002F\u002Fapi.bluepic.io\u002Fapi\u002Fidml\u002Frender?format=pdf&textOverrides=${encodeURIComponent(JSON.stringify(textOverrides))}`,\n    { method: 'POST', headers: { Authorization: apiKey }, body: form },\n  );\n\n  await saveFile(`certificate-${attendee.name}.pdf`, await res.blob());\n}\n","js",[22,245,246,277,284,304,318,328,337,364,370,375,394,412,433,438,456,487,499,505,510,548],{"__ignoreMap":55},[247,248,251,255,259,262,265,269,273],"span",{"class":249,"line":250},"line",1,[247,252,254],{"class":253},"snl16","const",[247,256,258],{"class":257},"sDLfK"," attendees",[247,260,261],{"class":253}," =",[247,263,264],{"class":253}," await",[247,266,268],{"class":267},"svObZ"," getAttendeesFromYourDatabase",[247,270,272],{"class":271},"s95oV","(); ",[247,274,276],{"class":275},"sAwPA","\u002F\u002F [{ name, date, score }, ...]\n",[247,278,280],{"class":249,"line":279},2,[247,281,283],{"emptyLinePlaceholder":282},true,"\n",[247,285,287,290,293,295,298,301],{"class":249,"line":286},3,[247,288,289],{"class":253},"for",[247,291,292],{"class":271}," (",[247,294,254],{"class":253},[247,296,297],{"class":257}," attendee",[247,299,300],{"class":253}," of",[247,302,303],{"class":271}," attendees) {\n",[247,305,307,310,313,315],{"class":249,"line":306},4,[247,308,309],{"class":253},"  const",[247,311,312],{"class":257}," textOverrides",[247,314,261],{"class":253},[247,316,317],{"class":271}," {\n",[247,319,321,325],{"class":249,"line":320},5,[247,322,324],{"class":323},"sU2Wk","    '0:TextFrame_name'",[247,326,327],{"class":271},": attendee.name,\n",[247,329,331,334],{"class":249,"line":330},6,[247,332,333],{"class":323},"    '0:TextFrame_date'",[247,335,336],{"class":271},": attendee.date,\n",[247,338,340,343,346,349,352,355,358,361],{"class":249,"line":339},7,[247,341,342],{"class":323},"    '0:TextFrame_score'",[247,344,345],{"class":271},": ",[247,347,348],{"class":323},"`${",[247,350,351],{"class":271},"attendee",[247,353,354],{"class":323},".",[247,356,357],{"class":271},"score",[247,359,360],{"class":323},"}%`",[247,362,363],{"class":271},",\n",[247,365,367],{"class":249,"line":366},8,[247,368,369],{"class":271},"  };\n",[247,371,373],{"class":249,"line":372},9,[247,374,283],{"emptyLinePlaceholder":282},[247,376,378,380,383,385,388,391],{"class":249,"line":377},10,[247,379,309],{"class":253},[247,381,382],{"class":257}," form",[247,384,261],{"class":253},[247,386,387],{"class":253}," new",[247,389,390],{"class":267}," FormData",[247,392,393],{"class":271},"();\n",[247,395,397,400,403,406,409],{"class":249,"line":396},11,[247,398,399],{"class":271},"  form.",[247,401,402],{"class":267},"append",[247,404,405],{"class":271},"(",[247,407,408],{"class":323},"'idml'",[247,410,411],{"class":271},", certificateIdml);\n",[247,413,415,417,419,421,424,427,430],{"class":249,"line":414},12,[247,416,399],{"class":271},[247,418,402],{"class":267},[247,420,405],{"class":271},[247,422,423],{"class":323},"'assets'",[247,425,426],{"class":271},", sealImage, ",[247,428,429],{"class":323},"'seal.png'",[247,431,432],{"class":271},");\n",[247,434,436],{"class":249,"line":435},13,[247,437,283],{"emptyLinePlaceholder":282},[247,439,441,443,446,448,450,453],{"class":249,"line":440},14,[247,442,309],{"class":253},[247,444,445],{"class":257}," res",[247,447,261],{"class":253},[247,449,264],{"class":253},[247,451,452],{"class":267}," fetch",[247,454,455],{"class":271},"(\n",[247,457,459,462,465,467,470,472,475,477,479,482,485],{"class":249,"line":458},15,[247,460,461],{"class":323},"    `https:\u002F\u002Fapi.bluepic.io\u002Fapi\u002Fidml\u002Frender?format=pdf&textOverrides=${",[247,463,464],{"class":267},"encodeURIComponent",[247,466,405],{"class":323},[247,468,469],{"class":257},"JSON",[247,471,354],{"class":323},[247,473,474],{"class":267},"stringify",[247,476,405],{"class":323},[247,478,206],{"class":271},[247,480,481],{"class":323},"))",[247,483,484],{"class":323},"}`",[247,486,363],{"class":271},[247,488,490,493,496],{"class":249,"line":489},16,[247,491,492],{"class":271},"    { method: ",[247,494,495],{"class":323},"'POST'",[247,497,498],{"class":271},", headers: { Authorization: apiKey }, body: form },\n",[247,500,502],{"class":249,"line":501},17,[247,503,504],{"class":271},"  );\n",[247,506,508],{"class":249,"line":507},18,[247,509,283],{"emptyLinePlaceholder":282},[247,511,513,516,519,521,524,526,528,531,534,536,539,542,545],{"class":249,"line":512},19,[247,514,515],{"class":253},"  await",[247,517,518],{"class":267}," saveFile",[247,520,405],{"class":271},[247,522,523],{"class":323},"`certificate-${",[247,525,351],{"class":271},[247,527,354],{"class":323},[247,529,530],{"class":271},"name",[247,532,533],{"class":323},"}.pdf`",[247,535,113],{"class":271},[247,537,538],{"class":253},"await",[247,540,541],{"class":271}," res.",[247,543,544],{"class":267},"blob",[247,546,547],{"class":271},"());\n",[247,549,551],{"class":249,"line":550},20,[247,552,553],{"class":271},"}\n",[15,555,556],{},"Same shape works for event badges, invoice-style documents, personalized social graphics, or a weekly report that only changes three numbers — anywhere you'd otherwise open InDesign, change some text, and export by hand.",[10,558,560,562],{"id":559},"engine-fidelity-vs-throughput",[22,561,146],{},": fidelity vs. throughput",[15,564,565,566,568,569,572],{},"For a handful of renders, the default ",[22,567,151],{}," engine (a real, full layout engine — the same technology behind the free converter) is the right call: full fidelity, every feature. For a large batch of simple PNG\u002FJPEG exports where you're rendering hundreds or thousands of variants, ",[22,570,571],{},"engine=resvg"," skips the Chromium instance entirely and renders faster — worth benchmarking against your own document before committing to it for a production batch job.",[10,574,576],{"id":575},"credits","Credits",[15,578,579,580,583,584,586,587,354],{},"Every account gets ",[33,581,582],{},"100 free credits a month"," — 1 credit per rendered page, regardless of format or how many ",[22,585,206],{}," you send. A 500-badge batch job is 500 credits; check usage and get in touch for higher volume from the ",[213,588,590],{"href":589},"\u002Fidml\u002Faccount","account page",[10,592,594],{"id":593},"next-steps","Next steps",[596,597,598,605,612,623],"ul",{},[599,600,601,604],"li",{},[213,602,603],{"href":215},"Get your API key"," and try the playground against your own IDML.",[599,606,607,608,611],{},"Read the ",[213,609,610],{"href":215},"full API reference"," for every parameter.",[599,613,614,615,619,620,622],{},"If your automation is specifically about shipping the same layout in multiple languages, see ",[213,616,618],{"href":617},"\u002Fdocs\u002Ftranslate-indesign-automatically","Translate InDesign projects automatically"," — same API, same ",[22,621,206],{}," mechanism.",[599,624,625,627,628,630],{},[213,626,228],{"href":227}," and ",[213,629,233],{"href":232}," — worth reading before your first production batch.",[632,633,634],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":55,"searchDepth":279,"depth":279,"links":636},[637,638,639,640,642,643],{"id":12,"depth":279,"text":13},{"id":28,"depth":279,"text":29},{"id":237,"depth":279,"text":238},{"id":559,"depth":279,"text":641},"engine: fidelity vs. throughput",{"id":575,"depth":279,"text":576},{"id":593,"depth":279,"text":594},"automate","2026-07-16","Turn a single InDesign layout into a rendering pipeline — batch outputs, dynamic fields, and PDF\u002FPNG\u002FJPEG\u002FSVG generation with no InDesign install anywhere.","md","\u002Fdocs-images\u002Fautomate-indesign-projects.svg",{},"\u002Fdocs\u002Fautomate-indesign-projects",{"title":5,"description":646},"docs\u002Fautomate-indesign-projects","indesign","62e0euc3H7eCxiSGHCIbg_lM3eMCR0_kUmIQuOzgwtg",1784233655659]