[{"data":1,"prerenderedAt":3245},["ShallowReactive",2],{"content-page-\u002Fdocs\u002Fmockups":3,"api-docs-metadata":2487,"icon-harvest":3231},{"id":4,"title":5,"body":6,"description":2477,"extension":2478,"meta":2479,"navigation":2482,"path":2483,"seo":2484,"stem":2485,"__hash__":2486},"all\u002Fdocs\u002Fmockups.md","Mockups",{"type":7,"value":8,"toc":2460},"minimark",[9,13,22,27,30,72,81,85,88,185,216,220,387,398,408,411,416,425,485,505,515,518,521,588,592,595,619,628,632,651,677,684,687,697,737,746,797,833,837,840,915,918,922,925,1003,1022,1029,1033,1049,1063,1132,1479,1552,1573,1622,1720,1746,1756,2338,2361,2372,2376,2379,2422,2426,2456],[10,11,5],"h1",{"id":12},"mockups",[14,15,16,17,21],"p",{},"A ",[18,19,20],"strong",{},"mockup"," puts your design on a product photo: a t-shirt, a hoodie, a mug, a poster on a wall, a phone in a hand, a tote bag. The print follows the product's folds, catches its light and shadows, and stops at its edges. The design is a variable, so one mockup template renders every design you feed it.",[23,24,26],"h2",{"id":25},"what-a-mockup-is","What a mockup is",[14,28,29],{},"A mockup is two layers in an ordinary template:",[31,32,33,40,66],"ul",{},[34,35,36,39],"li",{},[18,37,38],{},"The product photo",": an image layer. Nothing is baked into it.",[34,41,42,45,46],{},[18,43,44],{},"A warp layer"," over it, with mockup settings. Its child layers are the design. The warp bends the design onto the printable area, and the mockup settings print it through three maps made from the photo:\n",[31,47,48,54,60],{},[34,49,50,53],{},[18,51,52],{},"Print mask",": where ink may land (white = printable). The design stops at seams, collars, handles and screen bezels.",[34,55,56,59],{},[18,57,58],{},"Wrinkles",": a displacement map derived from the photo's depth, so the print shifts with the folds instead of floating on top.",[34,61,62,65],{},[18,63,64],{},"Look",": how the photo's shading reaches the ink (shadows, highlights, grain, colour cast), how soft the print is, and how the light falls across it.",[34,67,68,71],{},[18,69,70],{},"Product color"," (optional): the product itself re-tinted inside the print mask, so one white tee photo becomes a navy, red or brand-coloured tee.",[14,73,74,75,80],{},"Because it is a normal template, everything else works the same way: variables, brand tokens, variations, bulk rendering and the ",[76,77,79],"a",{"href":78},"\u002Fdocs\u002Frendering","Render API",".",[23,82,84],{"id":83},"surfaces","Surfaces",[14,86,87],{},"Pick the surface that matches the product. Each one sets a look preset and decides whether wrinkles are on by default.",[89,90,91,107],"table",{},[92,93,94],"thead",{},[95,96,97,101,104],"tr",{},[98,99,100],"th",{},"Surface",[98,102,103],{},"Use it for",[98,105,106],{},"What the preset does",[108,109,110,125,138,151,168],"tbody",{},[95,111,112,119,122],{},[113,114,115],"td",{},[116,117,118],"code",{},"fabric",[113,120,121],{},"T-shirts, hoodies, totes, caps made of cloth",[113,123,124],{},"Strong shading from the folds and the garment's broad lighting, ink that soaks into the cloth with a fine weave over it, a slightly soft print edge, wrinkles on (12 px).",[95,126,127,132,135],{},[113,128,129],{},[116,130,131],{},"paper",[113,133,134],{},"Posters, prints, books, paper bags",[113,136,137],{},"Gentle shading and paper texture; flat unless you turn wrinkles on.",[95,139,140,145,148],{},[113,141,142],{},[116,143,144],{},"rigid",[113,146,147],{},"Boxes, signs, billboards, hard cases",[113,149,150],{},"Shading from the light falloff across the face, no wrinkles.",[95,152,153,158,161],{},[113,154,155],{},[116,156,157],{},"label",[113,159,160],{},"Mugs, cans, bottles",[113,162,163,164,167],{},"Shading that follows the curve, so the print darkens as it turns away. The print is bent to the cylinder the mask shows (",[18,165,166],{},"Fit to cylinder","). No wrinkles.",[95,169,170,175,178],{},[113,171,172],{},[116,173,174],{},"screen",[113,176,177],{},"Phones, laptops, tablets, monitors",[113,179,180,181,184],{},"Emissive: the design shows at full brightness, with the glass's own reflections and glare kept over it (",[18,182,183],{},"Glass","). No shading, no grain, no wrinkles. The print mask's corners are rounded to follow the glass.",[14,186,187,188,190,191,194,195,194,198,194,201,204,205,207,208,211,212,215],{},"The look preset is a starting point. The ",[18,189,64],{}," section shows five sliders: ",[18,192,193],{},"Shadow",", ",[18,196,197],{},"Highlight",[18,199,200],{},"Texture",[18,202,203],{},"Match color"," and ",[18,206,183],{},". Each one moves a few of the detailed settings together. ",[18,209,210],{},"Advanced"," opens every setting (the editor remembers whether you left it open). A dot next to ",[18,213,214],{},"Reset to surface preset"," shows that the look no longer matches the preset, and the button brings the preset back.",[23,217,219],{"id":218},"build-one-in-the-editor","Build one in the editor",[221,222,223,241,248,257,270,291,347,375,378],"ol",{},[34,224,225,226,228,229,232,233,236,237,240],{},"Open the ",[18,227,5],{}," panel in the left rail. ",[18,230,231],{},"Starters"," are ready-made mockups from the gallery. One click drops a starter onto the canvas with its mask and wrinkles already made, fits the print box to the print area and selects the design layer. Drop your image on the print, or use ",[18,234,235],{},"Add your design",". ",[18,238,239],{},"Yours"," lists the mockups saved as components in this space.",[34,242,243,244,247],{},"Click ",[18,245,246],{},"New"," and pick the photo: upload one, generate one from a prompt, or use the image layer you have selected. The editor groups the photo with a new warp layer and selects the warp.",[34,249,250,252,253,256],{},[18,251,52],{},": describe the printable part (\"the t-shirt\", \"the mug body\", \"the phone screen\") or click on the photo (shift-click excludes an area). You can also upload a mask, or ",[18,254,255],{},"Paint"," it with a brush and lasso. Smooth, grow, shrink or feather it until the edge sits where the print should stop.",[34,258,259,262,263,266,267,269],{},[18,260,261],{},"Placement",": the warp is placed for the surface, on the chest of a garment or across a screen or a poster face. Drag the corners and the curve handles on the canvas to fine-tune. In ",[18,264,265],{},"Warp surface"," you can switch between a grid, corners and a curved patch, or apply a dome, bulge or cylinder. On a mug, can or bottle, ",[18,268,166],{}," reads the print mask and bows the print's top and bottom to the rims and squeezes it toward the sides as the surface turns away; it is greyed out, with the reason on hover, when the mask does not look like a cylinder seen from the front.",[34,271,272,274,275,278,279,204,282,285,286,290],{},[18,273,58],{},": ",[18,276,277],{},"Estimate depth"," reads the photo's shape, and the ",[18,280,281],{},"Strength",[18,283,284],{},"Smoothing"," sliders decide how far the folds push the print. The same depth also gives the print the photo's light (see ",[76,287,289],{"href":288},"#print-technique-and-light","Print technique and light","), and on fabric the editor takes a patch of the photo's own cloth as the print's texture.",[34,292,293,295,296,236,299,301,302,305,306,308,309],{},[18,294,64],{},": start with the five sliders (Shadow, Highlight, Texture, Match color, Glass) and ",[18,297,298],{},"Match photo",[18,300,183],{}," keeps the glass's own reflections, flares and glare over the print: on a screen, or on a poster photographed behind a shop window or a glazed frame, the print should never look cleaner than the glass around it. It starts at 0.35 on screens and 0 elsewhere; 0.3–0.45 suits most glass. The first time you raise it on a mockup that has never measured its glass, the editor reads the darkest glass under the print, and everything brighter than that in the photo counts as reflection. With a shiny technique (foil, puff, embroidery, screen print) a fifth slider, ",[18,303,304],{},"Shine",", sets how much the ink catches the light. Under ",[18,307,210],{}," you can adjust shadows, highlights, grain, colour cast, shading radius and gain, ink flatten, curve shade and the mask's feather, edge and erode one by one. Then:\n",[31,310,311,320,326,332,338],{},[34,312,313,316,317,319],{},[18,314,315],{},"Print blur"," softens the print to the photo's own sharpness, in photo pixels (0–2). A crisp design on a soft or upscaled photo is the first thing that gives a mockup away. ",[18,318,298],{}," measures how sharp and how grainy the photo is under the print and sets the print blur and grain for you. It runs by itself when you finish a new mockup or pick a different photo, and it costs nothing.",[34,321,322,325],{},[18,323,324],{},"Ambient"," carries the photo's broad lighting into the print, so the side of the garment that faces the light is brighter and the side turned away is darker (0–1). Fold shading alone only follows small wrinkles.",[34,327,328,331],{},[18,329,330],{},"Ink soak"," lets the ink sink into the material: a little less saturated, and dimmer on darker cloth (0–1). Pure, glowing ink is a common giveaway.",[34,333,334,337],{},[18,335,336],{},"Weave"," lays a fine knit texture over the print that follows the folds (0–1). It shows up close and in large renders, and helps when the photo is too soft to show its own fabric texture.",[34,339,340,204,343,346],{},[18,341,342],{},"Light from",[18,344,345],{},"Falloff"," darken the print across a flat face, away from the light. Set the direction the light comes from (in degrees, clockwise from the top: 270 is from the left) and how dark the far edge gets (0–1). Use it on billboards, signs, boxes and posters, where the photo's own shading is too even to show. It is off (0) by default.",[34,348,349,351,352,355,356,358,359,362,363,366,367,370,371,374],{},[18,350,70],{}," (optional): click ",[18,353,354],{},"+"," on the section, then pick a swatch. Your brand's colours come first. The product is re-tinted inside the print mask and keeps the photo's folds and light. ",[18,357,281],{}," sets how much of the new colour replaces the photo's own (0–1). ",[18,360,361],{},"Keep photo brightness"," changes only the hue and keeps the photo's own brightness: a white tee then stays light. Leave it off to take the colour's own tone, so a white tee can become navy. To change the colour per render, type an expression such as ",[116,364,365],{},"{{ color }}"," or ",[116,368,369],{},"{{ brand.colors.primary }}"," in the colour field. ",[18,372,373],{},"Original color"," removes the tint.",[34,376,377],{},"Put your design inside the warp layer, and make it a variable (an image variable bound to the design layer's source). Every render then prints whatever image you pass.",[34,379,380,382,383,80],{},[18,381,261],{}," (in the inspector of the print layer or of the design inside it): place the design inside the print area. See ",[76,384,386],{"href":385},"#place-the-design","Place the design",[14,388,389,390,393,394,397],{},"The ",[18,391,392],{},"Mockup"," section of the inspector shows which image layer is the product photo and which surface is in use. ",[18,395,396],{},"Re-place from mask"," places the warp again after you change the mask.",[14,399,400,403,404,407],{},[18,401,402],{},"Remove existing print"," erases a logo, slogan or print that is already on the product, so it cannot show through your design. It edits the photo with AI and saves the result as a new image in your media library; the mask and wrinkles stay as they are, because the framing does not change. ",[18,405,406],{},"Restore original"," puts the photo from before back, and Undo works too. The button is off while the photo is bound to a variable: unbind it first.",[14,409,410],{},"Each AI step shows its price before it runs, and you can skip it and upload or paint the map instead.",[412,413,415],"h3",{"id":414},"scenes-and-relight","Scenes and relight",[14,417,389,418,421,422,424],{},[18,419,420],{},"Scene"," tab of the Mockups panel gives the selected mockup's photo new light or a new setting. Select the photo or its print first. The ",[18,423,420],{}," row in the inspector's Mockup section opens the same tab.",[31,426,427,459],{},[34,428,429,432,433,194,436,194,439,194,442,194,445,204,448,451,452,454,455,458],{},[18,430,431],{},"Relight"," presets change only the light: ",[18,434,435],{},"Studio soft",[18,437,438],{},"Spotlight",[18,440,441],{},"Sunlit blinds",[18,443,444],{},"Window light",[18,446,447],{},"Golden hour",[18,449,450],{},"Overcast",". The product and the framing stay where they were, so the print mask and placement are kept. The AI can still move the folds a little, so the editor estimates the depth of the new photo again and the wrinkles follow it. ",[18,453,298],{}," then runs again, so the print takes on the new photo's sharpness and grain, and the light direction is read again from the new photo so the print's light falloff follows the new light (when the photo's light is unclear, the falloff is left as it was). Tick ",[18,456,457],{},"Keep current wrinkles"," to skip the depth step and save its credit.",[34,460,461,464,465,194,468,194,471,194,474,204,477,480,481,484],{},[18,462,463],{},"New setting"," presets (marked with a picture icon) move the product into a new scene: ",[18,466,467],{},"Concrete wall",[18,469,470],{},"Café",[18,472,473],{},"Marble counter",[18,475,476],{},"Linen table",[18,478,479],{},"Street",". The photo's geometry changes, so the editor sets the old mask and wrinkles aside and opens ",[18,482,483],{},"Find print area"," with your last mask prompt filled in. If the photo has several print areas, find each one again.",[14,486,487,488,491,492,496,497,500,501,504],{},"Add a short note in your own words (\"warmer, light from the right\") to steer a preset, or use the note on its own to relight the photo. The note is screened like any other image prompt; a declined note is not run or charged (",[116,489,490],{},"PROMPT_REJECTED",", see ",[76,493,495],{"href":494},"\u002Fdocs\u002Ferrors","Errors","). ",[18,498,499],{},"Regenerate"," runs the same settings again for a new take. ",[18,502,503],{},"Try another"," runs the next preset in the same group. Each run shows its price first: a relight costs the edit plus one depth estimate, a new setting costs the edit (Find print area and wrinkles are charged as usual after).",[14,506,507,508,511,512,514],{},"Every result is saved as a new image in your media library. The last four sit under the controls: click one to use it again. Presets always start from the photo the results came from, so the edits do not stack. ",[18,509,510],{},"Original"," (or ",[18,513,406],{}," in the inspector) puts the photo you started with back, together with its mask, wrinkles and placement.",[23,516,386],{"id":517},"place-the-design",[14,519,520],{},"The print area is the part of the photo your design prints on. While the print layer or a layer inside it is selected, the canvas shows the print area as a dashed outline.",[31,522,523,537,547,553,568,578],{},[34,524,525,528,529,532,533,536],{},[18,526,527],{},"Snapping",": drag the design and it snaps to the print area's edges, centre lines and thirds, with the usual pink guides. Dragging a corner of the print on the photo snaps to the saved print area the same way. Hold ",[18,530,531],{},"⌥ Option"," while resizing to resize from the centre, and ",[18,534,535],{},"⇧ Shift"," to keep the proportions.",[34,538,539,542,543,546],{},[18,540,541],{},"Print width",": type how wide the print area prints, in inches or centimetres. ",[18,544,545],{},"Units"," then switches X, Y, W and H between pixels, inches and centimetres.",[34,548,549,552],{},[18,550,551],{},"DPI",": with a print width set, an image design shows the DPI it prints at (its pixels per printed inch). Under 150 DPI it turns amber (it may print soft), and under 100 DPI it turns red.",[34,554,555,194,558,194,561,204,564,567],{},[18,556,557],{},"Contain",[18,559,560],{},"Cover",[18,562,563],{},"Stretch",[18,565,566],{},"Center"," fit the design to the print area: the whole design inside it, the area filled, the area filled exactly (stretched), or centred at its current size.",[34,569,570,573,574,577],{},[18,571,572],{},"Rotate 90°"," left or right, and ",[18,575,576],{},"Flip"," horizontal or vertical.",[34,579,580,583,584,587],{},[18,581,582],{},"Fit box to print area"," pins the print to the saved print area again. ",[18,585,586],{},"Save as print area"," saves the corners where you dragged them as the new print area.",[412,589,591],{"id":590},"several-print-areas-on-one-photo","Several print areas on one photo",[14,593,594],{},"A photo can carry more than one print: front and back, a sleeve, a pocket, a label. Each print area is its own print layer on the same photo, with its own mask, placement and design, and they share the photo, its wrinkles and its look.",[221,596,597,603,613],{},[34,598,599,600,602],{},"Select a print (or its photo). The ",[18,601,5],{}," panel lists the photo's print areas.",[34,604,605,606,609,610,612],{},"Type or pick a name (Back, Sleeve, Pocket, Label, or your own) and click ",[18,607,608],{},"Duplicate for area",". The print is copied onto the same photo and the ",[18,611,483],{}," step opens for the new area. Describe the part, for example \"the left sleeve\".",[34,614,615,618],{},[18,616,617],{},"Apply this design to all areas"," copies the selected print's design image into every other area. Each area keeps its own placement.",[14,620,389,621,624,625,627],{},[18,622,623],{},"Area"," field in the ",[18,626,261],{}," section renames an area.",[412,629,631],{"id":630},"all-over-pattern","All-over pattern",[14,633,634,636,637,639,640,194,643,646,647,650],{},[18,635,631],{}," repeats the design across the whole print, so the folds, mask and shading apply to every repeat. Click ",[18,638,354],{}," on the section, then pick ",[18,641,642],{},"Grid",[18,644,645],{},"Brick"," (every other row shifted) or ",[18,648,649],{},"Half drop"," (every other column shifted).",[31,652,653,659,665,671],{},[34,654,655,658],{},[18,656,657],{},"Scale",": the size of one repeat, as a multiple of the design layer (0.05–4).",[34,660,661,664],{},[18,662,663],{},"Spacing",": the gap between repeats, as a fraction of a repeat (0–2).",[34,666,667,670],{},[18,668,669],{},"Offset",": how far every other row or column shifts (0–1, 0.5 is half a repeat).",[34,672,673,676],{},[18,674,675],{},"Rotation",": turns the whole pattern (-180° to 180°).",[14,678,679,680,683],{},"The first layer in the print repeats. For an all-over print, make the print area cover the whole product. ",[18,681,682],{},"Turn off"," prints the design once again.",[23,685,289],{"id":686},"print-technique-and-light",[14,688,689,692,693,696],{},[18,690,691],{},"Print"," sets how the design is printed. Each technique sets its own look, and ",[18,694,695],{},"Plain"," puts the surface's look back:",[31,698,699,705,711,725,731],{},[34,700,701,704],{},[18,702,703],{},"Screen print",": flat, opaque ink with crisp edges and a hint of colour misregistration at the edges.",[34,706,707,710],{},[18,708,709],{},"DTG"," (direct to garment): the ink soaks into the cloth, a little duller, and the weave shows through.",[34,712,713,716,717,720,721,724],{},[18,714,715],{},"Embroidery",": thread lines, a raised edge, and the design stitched in a few flat thread colours picked from the design itself. ",[18,718,719],{},"Threads"," sets how many (2–8, default 6): fewer gives a flatter, more stitched look. ",[18,722,723],{},"Stitch angle"," turns the stitch direction.",[34,726,727,730],{},[18,728,729],{},"Puff",": raised ink that bulges and catches the light.",[34,732,733,736],{},[18,734,735],{},"Foil",": metallic ink that mirrors the photo's light and shines where it faces the light.",[14,738,739,742,743,745],{},[18,740,741],{},"Light"," (needs ",[18,744,277],{},", or a technique): the print is relit by the photo's own folds under the key light.",[31,747,748,759,764,770,775,791],{},[34,749,750,753,754,756,757,80],{},[18,751,752],{},"Elevation",": how high the light sits above the surface, from 0 (grazing) to 90 (straight on). The direction is ",[18,755,342],{}," under the Look's ",[18,758,210],{},[34,760,761,763],{},[18,762,431],{},": how much the folds facing toward or away from the light brighten or darken the print (0–1).",[34,765,766,769],{},[18,767,768],{},"Edge",": ink thickness, a thin shadow just outside the print's edge on the side away from the light and a highlight on the lit edge (0–1). It shows around shapes inside the print layer, so leave some transparent margin around the artwork.",[34,771,772,774],{},[18,773,298],{}," also reads the light's direction and elevation from the photo once the depth is estimated.",[34,776,777,780,781,366,784,787,788,790],{},[18,778,779],{},"Enhance photo detail"," upscales the photo with AI so the cloth holds up when you zoom in or render large. Pick ",[18,782,783],{},"2x",[18,785,786],{},"4x"," above the button, or leave both off for auto (4× for photos up to 1024 px, 2× for larger ones). On flat cotton, 2× is the safer pick: 4× can invent cloth bands the photo does not have. It runs once per photo; the mask and wrinkles stay, and ",[18,789,406],{}," puts the old photo back.",[34,792,793,796],{},[18,794,795],{},"Use photo cloth"," (fabric) takes a patch of bare cloth from the photo, away from the print, and uses it as the print's texture instead of the drawn knit. It blurs exactly like the photo when you zoom in.",[14,798,799,802,803,806,807,809,810,813,814,816,817,820,821,824,825,828,829,832],{},[18,800,801],{},"In front",": mark what sits in front of the print, such as a hand, a strap, a cord, hair or a sleeve, and the print passes behind it while the photo shows through. Pick one or more chips and click ",[18,804,805],{},"Find",", or ",[18,808,255],{}," it by hand with the mask tools. ",[18,811,812],{},"Remove cords"," under ",[18,815,52],{}," finds drawstrings and straps over the print and marks them as in front. Once something is marked, ",[18,818,819],{},"Tighten"," (0–6 photo pixels, ",[116,822,823],{},"blend.occluderErode",") pulls its edge in when a grey halo shows beside a cord, and ",[18,826,827],{},"Soften"," (0–4 photo pixels, ",[116,830,831],{},"blend.occluderSoft",", default 1) matches the photo's own edge softness.",[23,834,836],{"id":835},"credits","Credits",[14,838,839],{},"The AI steps cost credits. The rendering itself is billed like any other render.",[89,841,842,851],{},[92,843,844],{},[95,845,846,849],{},[98,847,848],{},"Step",[98,850,836],{},[108,852,853,861,868,876,882,890,900,908],{},[95,854,855,858],{},[113,856,857],{},"Print mask (segment)",[113,859,860],{},"1",[95,862,863,866],{},[113,864,865],{},"Estimate depth (wrinkles)",[113,867,860],{},[95,869,870,873],{},[113,871,872],{},"AI print fit",[113,874,875],{},"3",[95,877,878,880],{},[113,879,402],{},[113,881,875],{},[95,883,884,887],{},[113,885,886],{},"Relight (each run, wrinkles re-estimated)",[113,888,889],{},"4 (3 edit + 1 depth)",[95,891,892,898],{},[113,893,894,895,897],{},"Relight with ",[18,896,457],{},", or a new setting",[113,899,875],{},[95,901,902,905],{},[113,903,904],{},"Enhance photo detail (upscale)",[113,906,907],{},"2",[95,909,910,913],{},[113,911,912],{},"In front (segment, per chip)",[113,914,860],{},[14,916,917],{},"These are the default prices. A platform admin can change them, so the editor and the API always report what was charged. A step that fails is not charged.",[23,919,921],{"id":920},"re-print-a-design-on-every-render","Re-print a design on every render",[14,923,924],{},"Bind the design to a variable once, then pass a new value per render:",[926,927,932],"pre",{"className":928,"code":929,"language":930,"meta":931,"style":931},"language-bash shiki shiki-themes bannx-docs-light bannx-docs-dark","curl -X POST https:\u002F\u002Fbannx.com\u002Fapi\u002Fv1\u002Ftemplates\u002FTEMPLATE_ID\u002Frender \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"format\": \"png\", \"variables\": { \"design\": \"https:\u002F\u002Fexample.com\u002Fartwork.png\" } }'\n","bash","",[116,933,934,956,974,988],{"__ignoreMap":931},[935,936,939,943,947,950,953],"span",{"class":937,"line":938},"line",1,[935,940,942],{"class":941},"sMrpa","curl",[935,944,946],{"class":945},"sYgty"," -X",[935,948,949],{"class":945}," POST",[935,951,952],{"class":945}," https:\u002F\u002Fbannx.com\u002Fapi\u002Fv1\u002Ftemplates\u002FTEMPLATE_ID\u002Frender",[935,954,955],{"class":941}," \\\n",[935,957,959,962,966,969,972],{"class":937,"line":958},2,[935,960,961],{"class":945},"  -H",[935,963,965],{"class":964},"sS_0z"," \"",[935,967,968],{"class":945},"Authorization: Bearer YOUR_API_KEY",[935,970,971],{"class":964},"\"",[935,973,955],{"class":941},[935,975,977,979,981,984,986],{"class":937,"line":976},3,[935,978,961],{"class":945},[935,980,965],{"class":964},[935,982,983],{"class":945},"Content-Type: application\u002Fjson",[935,985,971],{"class":964},[935,987,955],{"class":941},[935,989,991,994,997,1000],{"class":937,"line":990},4,[935,992,993],{"class":945},"  -d",[935,995,996],{"class":964}," '",[935,998,999],{"class":945},"{ \"format\": \"png\", \"variables\": { \"design\": \"https:\u002F\u002Fexample.com\u002Fartwork.png\" } }",[935,1001,1002],{"class":964},"'\n",[14,1004,1005,1006,1009,1010,1013,1014,1017,1018,1021],{},"Bind the product colour the same way: set ",[116,1007,1008],{},"mockup.recolor.color"," to ",[116,1011,1012],{},"\"{{ color }}\"",", add a ",[116,1015,1016],{},"color"," variable, and pass ",[116,1019,1020],{},"\"variables\": { \"design\": \"…\", \"color\": \"#b91c1c\" }",". One photo then renders every colourway.",[14,1023,1024,1025,1028],{},"Nothing about the mockup is computed again at render time. The mask, wrinkles and look are stored with the template, so a mockup render costs the same as any other still. See ",[76,1026,1027],{"href":78},"Rendering"," for formats, sizes and bulk jobs.",[23,1030,1032],{"id":1031},"build-one-from-an-agent-mcp","Build one from an agent (MCP)",[14,1034,1035,1036,1039,1040,1043,1044,1048],{},"Two calls build a mockup template: ",[116,1037,1038],{},"mockup_prepare"," makes the maps, and ",[116,1041,1042],{},"template_apply_ops"," adds the layers. See the ",[76,1045,1047],{"href":1046},"\u002Fdocs\u002Fintegrations\u002Fmcp","MCP guide"," for setup.",[14,1050,1051,1054,1055,1058,1059,1062],{},[18,1052,1053],{},"1. Prepare the photo."," Upload the product photo with ",[116,1056,1057],{},"media_upload"," (or use a ",[116,1060,1061],{},"fileId"," already in your library), then:",[926,1064,1068],{"className":1065,"code":1066,"language":1067,"meta":931,"style":931},"language-json shiki shiki-themes bannx-docs-light bannx-docs-dark","{ \"fileId\": \"PHOTO_FILE_ID\", \"surface\": \"fabric\", \"maskPrompt\": \"the t-shirt\" }\n","json",[116,1069,1070],{"__ignoreMap":931},[935,1071,1072,1075,1078,1081,1083,1086,1088,1091,1093,1096,1098,1101,1103,1105,1107,1109,1111,1113,1115,1118,1120,1122,1124,1127,1129],{"class":937,"line":938},[935,1073,1074],{"class":964},"{",[935,1076,965],{"class":1077},"selWe",[935,1079,1061],{"class":1080},"sNgYv",[935,1082,971],{"class":1077},[935,1084,1085],{"class":964},":",[935,1087,965],{"class":964},[935,1089,1090],{"class":945},"PHOTO_FILE_ID",[935,1092,971],{"class":964},[935,1094,1095],{"class":964},",",[935,1097,965],{"class":1077},[935,1099,1100],{"class":1080},"surface",[935,1102,971],{"class":1077},[935,1104,1085],{"class":964},[935,1106,965],{"class":964},[935,1108,118],{"class":945},[935,1110,971],{"class":964},[935,1112,1095],{"class":964},[935,1114,965],{"class":1077},[935,1116,1117],{"class":1080},"maskPrompt",[935,1119,971],{"class":1077},[935,1121,1085],{"class":964},[935,1123,965],{"class":964},[935,1125,1126],{"class":945},"the t-shirt",[935,1128,971],{"class":964},[935,1130,1131],{"class":964}," }\n",[89,1133,1134,1144],{},[92,1135,1136],{},[95,1137,1138,1141],{},[98,1139,1140],{},"Input",[98,1142,1143],{},"Meaning",[108,1145,1146,1158,1184,1193,1218,1235,1245,1279,1296,1312,1367,1396,1422,1448,1465],{},[95,1147,1148,1155],{},[113,1149,1150,366,1152],{},[116,1151,1061],{},[116,1153,1154],{},"imageUrl",[113,1156,1157],{},"The product photo. Exactly one. A library file is best: the photo layer renders from this source.",[95,1159,1160,1164],{},[113,1161,1162],{},[116,1163,1100],{},[113,1165,1166,194,1168,194,1170,194,1172,366,1174,1176,1177,1179,1180,1183],{},[116,1167,118],{},[116,1169,174],{},[116,1171,131],{},[116,1173,144],{},[116,1175,157],{},". For ",[116,1178,157],{},", the returned ",[116,1181,1182],{},"warpNode"," is bent to the cylinder the mask shows (rims bowed, squeezed toward the sides); a mask with straight top and bottom edges keeps a flat corner pin.",[95,1185,1186,1190],{},[113,1187,1188],{},[116,1189,1117],{},[113,1191,1192],{},"The part to print on. Defaults per surface (\"the garment\", \"display screen\", …).",[95,1194,1195,1200],{},[113,1196,1197],{},[116,1198,1199],{},"points",[113,1201,1202,1203,1206,1207,1210,1211,1214,1215,1217],{},"Optional clicks, ",[116,1204,1205],{},"{ x, y, label }"," with ",[116,1208,1209],{},"x","\u002F",[116,1212,1213],{},"y"," from 0 to 1 and ",[116,1216,157],{}," 1 to include or 0 to exclude. Up to 32. Clicks refine what the mask prompt finds, so the prompt is always sent with them.",[95,1219,1220,1225],{},[113,1221,1222],{},[116,1223,1224],{},"wrinkles",[113,1226,1227,1228,1230,1231,1234],{},"Estimate depth and derive wrinkles. Default: on for ",[116,1229,118],{},"; pass ",[116,1232,1233],{},"true"," for crumpled paper.",[95,1236,1237,1242],{},[113,1238,1239],{},[116,1240,1241],{},"strength",[113,1243,1244],{},"How far the wrinkles push the print, in photo pixels (0–60). Default per surface.",[95,1246,1247,1252],{},[113,1248,1249],{},[116,1250,1251],{},"recolor",[113,1253,1254,1255,236,1258,1260,1261,1264,1265,1267,1268,1270,1271,1274,1275,1278],{},"Optional product colour, ",[116,1256,1257],{},"{ color, strength?, keepLum? }",[116,1259,1016],{}," is a hex or ",[116,1262,1263],{},"rgb()"," colour, or a binding such as ",[116,1266,1012],{}," that resolves on every render. ",[116,1269,1241],{}," is 0–1 (default 1). ",[116,1272,1273],{},"keepLum: true"," keeps the photo's brightness, the default ",[116,1276,1277],{},"false"," takes the colour's own tone. No extra credits.",[95,1280,1281,1286],{},[113,1282,1283],{},[116,1284,1285],{},"area",[113,1287,1288,1289,1292,1293,80],{},"Optional name of this print area, for example ",[116,1290,1291],{},"\"Front\"",". Saved as ",[116,1294,1295],{},"mockup.area",[95,1297,1298,1303],{},[113,1299,1300],{},[116,1301,1302],{},"areas",[113,1304,1305,1306,236,1309,1311],{},"Optional extra print areas on the same photo, up to 4: ",[116,1307,1308],{},"[{ \"label\": \"Sleeve\", \"maskPrompt\": \"the left sleeve\" }]",[116,1310,1117],{}," defaults from the label. Each extra area costs 1 more segmentation credit.",[95,1313,1314,1319],{},[113,1315,1316],{},[116,1317,1318],{},"scene",[113,1320,1321,1322,1325,1326,194,1329,194,1332,194,1335,194,1338,194,1341,1344,1345,194,1348,194,1351,194,1354,194,1357,236,1360,1363,1364,1366],{},"Optional, ",[116,1323,1324],{},"{ preset?, prompt? }",". Relights the photo or places the product in a new setting before anything else runs, so the mask and wrinkles fit the new photo. Relight presets: ",[116,1327,1328],{},"studio-soft",[116,1330,1331],{},"spotlight",[116,1333,1334],{},"sunlit-blinds",[116,1336,1337],{},"window-light",[116,1339,1340],{},"golden-hour",[116,1342,1343],{},"overcast",". New-setting presets: ",[116,1346,1347],{},"concrete-wall",[116,1349,1350],{},"cafe",[116,1352,1353],{},"marble-counter",[116,1355,1356],{},"linen-table",[116,1358,1359],{},"street",[116,1361,1362],{},"prompt"," is a short note of up to 200 characters, added to the preset or used alone to relight. Costs 3 more credits by default. ",[116,1365,1199],{}," cannot be combined with a new-setting preset.",[95,1368,1369,1374],{},[113,1370,1371],{},[116,1372,1373],{},"printEffect",[113,1375,1376,1377,194,1380,194,1383,194,1386,366,1389,1392,1393,80],{},"Optional print technique: ",[116,1378,1379],{},"screenPrint",[116,1381,1382],{},"dtg",[116,1384,1385],{},"embroidery",[116,1387,1388],{},"puff",[116,1390,1391],{},"foil",". Sets that technique's look. Default ",[116,1394,1395],{},"none",[95,1397,1398,1403],{},[113,1399,1400],{},[116,1401,1402],{},"occluderPrompt",[113,1404,1405,1406,194,1409,194,1412,194,1415,194,1418,1421],{},"Optional: what sits in front of the print, such as ",[116,1407,1408],{},"\"hand\"",[116,1410,1411],{},"\"strap\"",[116,1413,1414],{},"\"cord\"",[116,1416,1417],{},"\"hair\"",[116,1419,1420],{},"\"sleeve\""," or your own words. The print passes behind it. 1 more segmentation credit. With wrinkles, the surface behind it is filled in from the area around it, so the print does not bend or step along its edge.",[95,1423,1424,1429],{},[113,1425,1426],{},[116,1427,1428],{},"enhance",[113,1430,1431,1432,1434,1435,366,1437,1440,1441,1443,1444,1447],{},"Optional: upscale the photo with AI first, so cloth texture holds up when zoomed. ",[116,1433,1233],{}," picks the factor for you (4× up to 1024 px, else 2×); ",[116,1436,907],{},[116,1438,1439],{},"4"," sets it. Use ",[116,1442,907],{}," for fabric laid flat: 4× can invent cloth bands on smooth cotton. 1 upscale (2 credits by default). Use the returned ",[116,1445,1446],{},"baseUrl"," for the photo layer.",[95,1449,1450,1455],{},[113,1451,1452],{},[116,1453,1454],{},"behindGlass",[113,1456,1457,1458,1460,1461,1464],{},"Optional ",[116,1459,1233],{}," when the print sits behind glass: a poster in a shop window, a print in a glazed frame. The glass's reflections stay over the print (",[116,1462,1463],{},"blend.reflect"," 0.3). Screens get this by default. No extra credits.",[95,1466,1467,1472],{},[113,1468,1469],{},[116,1470,1471],{},"baseBox",[113,1473,1474,1475,1478],{},"Where you will place the photo layer, ",[116,1476,1477],{},"{ x, y, w, h }",". Default: at 0,0 at the photo's pixel size.",[14,1480,1481,1482,194,1484,194,1487,1490,1491,1494,1495,1497,1498,194,1500,194,1502,194,1505,1508,1509,1512,1513,1515,1516,1519,1520,1523,1524,1527,1528,194,1531,204,1534,1537,1538,1497,1541,1544,1545,1548,1549,1551],{},"It returns ",[116,1483,1446],{},[116,1485,1486],{},"baseWidth",[116,1488,1489],{},"baseHeight",", the print ",[116,1492,1493],{},"corners"," (0–1 of the photo), ",[116,1496,1182],{}," (",[116,1499,1209],{},[116,1501,1213],{},[116,1503,1504],{},"w",[116,1506,1507],{},"h"," and the ",[116,1510,1511],{},"warp"," patch), ",[116,1514,20],{}," (surface, mask and wrinkle maps, look) and ",[116,1517,1518],{},"creditsCharged",". The look in ",[116,1521,1522],{},"mockup.blend"," also takes ",[116,1525,1526],{},"printBlur"," (0–2 photo pixels), ",[116,1529,1530],{},"ambient",[116,1532,1533],{},"inkSoak",[116,1535,1536],{},"weave"," (each 0–1) and ",[116,1539,1540],{},"lightFalloff",[116,1542,1543],{},"{ \"angle\": 270, \"strength\": 0.3 }",") if you want to set them. ",[116,1546,1547],{},"mockup.recolor"," is there when you passed ",[116,1550,1251],{},", and you can add, change or remove it later like any other mockup setting. Segmentation and depth cost 1 credit each by default. If any step fails, nothing is charged.",[14,1553,1554,1555,194,1557,204,1559,1562,1563,1566,1567,1569,1570,1572],{},"With ",[116,1556,1318],{},[116,1558,1446],{},[116,1560,1561],{},"baseFileId"," are the new photo, which is also saved in your media library. ",[116,1564,1565],{},"mockup.originalBaseSrc"," holds the photo you passed, so ",[18,1568,406],{}," in the editor can bring it back, and ",[116,1571,1318],{}," in the response says which preset ran and whether the geometry was kept.",[14,1574,1575,1578,1579,194,1581,194,1583,204,1585,1587,1588,1591,1592,1595,1596,1599,1600,1602,1603,1605,1606,194,1608,194,1610,204,1612,1614,1615,1617,1618,1621],{},[116,1576,1577],{},"mockup.printArea"," is the print area on the photo: ",[116,1580,1209],{},[116,1582,1213],{},[116,1584,1504],{},[116,1586,1507],{}," from 0 to 1 of the photo and ",[116,1589,1590],{},"rotation"," in degrees. Add ",[116,1593,1594],{},"widthIn"," (the printed width in inches) to get print units and the DPI readout in the editor, and ",[116,1597,1598],{},"dpiHint"," for your print shop's target DPI. When you passed ",[116,1601,1302],{},", the response has an ",[116,1604,1302],{}," list: each entry has its own ",[116,1607,157],{},[116,1609,1493],{},[116,1611,1182],{},[116,1613,20],{}," (with ",[116,1616,1295],{}," set to the label). Add one more warp layer per entry, with the same ",[116,1619,1620],{},"baseId"," and its own design child.",[14,1623,1624,1625,1628,1629,1497,1632,194,1635,194,1638,1641,1642,1645,1646,1649,1650,236,1652,194,1655,1658,1659,1662,1663,1666,1667,1669,1670,1673,1674,1676,1677,1679,1680,1682,1683,1176,1686,1688,1689,194,1691,1694,1695,1697,1698,1700,1701,1704,1705,1708,1709,194,1712,1715,1716,1719],{},"With wrinkles, the response also has ",[116,1626,1627],{},"normalSrc"," (the photo's surface normals) and ",[116,1630,1631],{},"light",[116,1633,1634],{},"angle",[116,1636,1637],{},"elevation",[116,1639,1640],{},"falloff","), the key light read from the photo and already set in ",[116,1643,1644],{},"mockup.blend.lightFalloff",". On fabric it has ",[116,1647,1648],{},"weaveSrc",", the photo's own cloth texture. Both are already in ",[116,1651,20],{},[116,1653,1654],{},"blend.relight",[116,1656,1657],{},"blend.spec"," (shine) and ",[116,1660,1661],{},"blend.edgeShadow"," (ink thickness) are 0–1 and ",[116,1664,1665],{},"blend.lightFalloff.elevation"," is 0–90 degrees. With ",[116,1668,1402],{}," you get ",[116,1671,1672],{},"occluderSrc"," (also in ",[116,1675,20],{},"), and with ",[116,1678,1428],{}," the new ",[116,1681,1446],{}," plus ",[116,1684,1685],{},"originalBaseUrl",[116,1687,174],{},", and with ",[116,1690,1454],{},[116,1692,1693],{},"mockup.glassBlack"," is the glass's own black level under the print (0–1); ",[116,1696,1463],{}," (0–1, ",[18,1699,183],{}," in the editor) lays everything in the photo brighter than that back over the design. ",[116,1702,1703],{},"reflect"," has no effect without ",[116,1706,1707],{},"glassBlack",". With ",[116,1710,1711],{},"printEffect: \"embroidery\"",[116,1713,1714],{},"mockup.stitchAngle"," turns the stitches (degrees, default 45) and ",[116,1717,1718],{},"mockup.printPalette"," sets how many thread colours the design is stitched in (2–8, default 6): each region of the design takes the nearest of those colours, picked from the design itself.",[14,1721,1722,1723,274,1726,236,1729,1732,1733,194,1736,194,1739,366,1742,1745],{},"For an all-over print, add ",[116,1724,1725],{},"mockup.pattern",[116,1727,1728],{},"{ \"mode\": \"grid\", \"scale\": 0.25, \"spacing\": 0.1, \"offset\": 0.5, \"rotation\": 0 }",[116,1730,1731],{},"mode"," is ",[116,1734,1735],{},"grid",[116,1737,1738],{},"brick",[116,1740,1741],{},"half-drop",[116,1743,1744],{},"off",". The warp's first child is the repeat, so size it to one motif.",[14,1747,1748,1751,1752,1755],{},[18,1749,1750],{},"2. Add the layers in one batch."," Use the values from step 1. ",[116,1753,1754],{},"$base"," refers to the photo layer added earlier in the same batch:",[926,1757,1759],{"className":1065,"code":1758,"language":1067,"meta":931,"style":931},"{\n  \"templateId\": \"TEMPLATE_ID\",\n  \"operations\": [\n    { \"op\": \"setVariables\", \"variables\": [{ \"name\": \"design\", \"type\": \"image\", \"label\": \"Design\", \"default\": \"https:\u002F\u002Fexample.com\u002Fartwork.png\" }] },\n    { \"op\": \"addNode\", \"type\": \"image\", \"ref\": \"base\", \"props\": { \"name\": \"Photo\", \"src\": \"BASE_URL\", \"x\": 0, \"y\": 0, \"w\": 1024, \"h\": 1024 } },\n    { \"op\": \"addNode\", \"type\": \"warp\", \"ref\": \"print\",\n      \"props\": { \"name\": \"Print\", \"...\": \"warpNode from step 1\", \"mockup\": { \"...\": \"mockup from step 1\", \"baseId\": \"$base\" } },\n      \"children\": [{ \"type\": \"image\", \"props\": { \"src\": \"{{ design }}\", \"x\": 0, \"y\": 0, \"w\": 400, \"h\": 360 } }] }\n  ]\n}\n",[116,1760,1761,1766,1788,1802,1912,2068,2122,2215,2326,2332],{"__ignoreMap":931},[935,1762,1763],{"class":937,"line":938},[935,1764,1765],{"class":964},"{\n",[935,1767,1768,1771,1774,1776,1778,1780,1783,1785],{"class":937,"line":958},[935,1769,1770],{"class":1077},"  \"",[935,1772,1773],{"class":1080},"templateId",[935,1775,971],{"class":1077},[935,1777,1085],{"class":964},[935,1779,965],{"class":964},[935,1781,1782],{"class":945},"TEMPLATE_ID",[935,1784,971],{"class":964},[935,1786,1787],{"class":964},",\n",[935,1789,1790,1792,1795,1797,1799],{"class":937,"line":976},[935,1791,1770],{"class":1077},[935,1793,1794],{"class":1080},"operations",[935,1796,971],{"class":1077},[935,1798,1085],{"class":964},[935,1800,1801],{"class":964}," [\n",[935,1803,1804,1807,1809,1812,1814,1816,1818,1821,1823,1825,1827,1830,1832,1834,1837,1839,1842,1844,1846,1848,1851,1853,1855,1857,1860,1862,1864,1866,1869,1871,1873,1875,1877,1879,1881,1883,1886,1888,1890,1892,1895,1897,1899,1901,1904,1906,1909],{"class":937,"line":990},[935,1805,1806],{"class":964},"    {",[935,1808,965],{"class":1077},[935,1810,1811],{"class":1080},"op",[935,1813,971],{"class":1077},[935,1815,1085],{"class":964},[935,1817,965],{"class":964},[935,1819,1820],{"class":945},"setVariables",[935,1822,971],{"class":964},[935,1824,1095],{"class":964},[935,1826,965],{"class":1077},[935,1828,1829],{"class":1080},"variables",[935,1831,971],{"class":1077},[935,1833,1085],{"class":964},[935,1835,1836],{"class":964}," [{",[935,1838,965],{"class":1077},[935,1840,1841],{"class":1080},"name",[935,1843,971],{"class":1077},[935,1845,1085],{"class":964},[935,1847,965],{"class":964},[935,1849,1850],{"class":945},"design",[935,1852,971],{"class":964},[935,1854,1095],{"class":964},[935,1856,965],{"class":1077},[935,1858,1859],{"class":1080},"type",[935,1861,971],{"class":1077},[935,1863,1085],{"class":964},[935,1865,965],{"class":964},[935,1867,1868],{"class":945},"image",[935,1870,971],{"class":964},[935,1872,1095],{"class":964},[935,1874,965],{"class":1077},[935,1876,157],{"class":1080},[935,1878,971],{"class":1077},[935,1880,1085],{"class":964},[935,1882,965],{"class":964},[935,1884,1885],{"class":945},"Design",[935,1887,971],{"class":964},[935,1889,1095],{"class":964},[935,1891,965],{"class":1077},[935,1893,1894],{"class":1080},"default",[935,1896,971],{"class":1077},[935,1898,1085],{"class":964},[935,1900,965],{"class":964},[935,1902,1903],{"class":945},"https:\u002F\u002Fexample.com\u002Fartwork.png",[935,1905,971],{"class":964},[935,1907,1908],{"class":964}," }]",[935,1910,1911],{"class":964}," },\n",[935,1913,1915,1917,1919,1921,1923,1925,1927,1930,1932,1934,1936,1938,1940,1942,1944,1946,1948,1950,1952,1955,1957,1959,1961,1964,1966,1968,1970,1973,1975,1977,1980,1982,1984,1986,1988,1990,1993,1995,1997,1999,2002,2004,2006,2008,2011,2013,2015,2017,2019,2021,2023,2026,2028,2030,2032,2034,2036,2038,2040,2042,2044,2046,2048,2051,2053,2055,2057,2059,2061,2063,2066],{"class":937,"line":1914},5,[935,1916,1806],{"class":964},[935,1918,965],{"class":1077},[935,1920,1811],{"class":1080},[935,1922,971],{"class":1077},[935,1924,1085],{"class":964},[935,1926,965],{"class":964},[935,1928,1929],{"class":945},"addNode",[935,1931,971],{"class":964},[935,1933,1095],{"class":964},[935,1935,965],{"class":1077},[935,1937,1859],{"class":1080},[935,1939,971],{"class":1077},[935,1941,1085],{"class":964},[935,1943,965],{"class":964},[935,1945,1868],{"class":945},[935,1947,971],{"class":964},[935,1949,1095],{"class":964},[935,1951,965],{"class":1077},[935,1953,1954],{"class":1080},"ref",[935,1956,971],{"class":1077},[935,1958,1085],{"class":964},[935,1960,965],{"class":964},[935,1962,1963],{"class":945},"base",[935,1965,971],{"class":964},[935,1967,1095],{"class":964},[935,1969,965],{"class":1077},[935,1971,1972],{"class":1080},"props",[935,1974,971],{"class":1077},[935,1976,1085],{"class":964},[935,1978,1979],{"class":964}," {",[935,1981,965],{"class":1077},[935,1983,1841],{"class":1080},[935,1985,971],{"class":1077},[935,1987,1085],{"class":964},[935,1989,965],{"class":964},[935,1991,1992],{"class":945},"Photo",[935,1994,971],{"class":964},[935,1996,1095],{"class":964},[935,1998,965],{"class":1077},[935,2000,2001],{"class":1080},"src",[935,2003,971],{"class":1077},[935,2005,1085],{"class":964},[935,2007,965],{"class":964},[935,2009,2010],{"class":945},"BASE_URL",[935,2012,971],{"class":964},[935,2014,1095],{"class":964},[935,2016,965],{"class":1077},[935,2018,1209],{"class":1080},[935,2020,971],{"class":1077},[935,2022,1085],{"class":964},[935,2024,2025],{"class":941}," 0",[935,2027,1095],{"class":964},[935,2029,965],{"class":1077},[935,2031,1213],{"class":1080},[935,2033,971],{"class":1077},[935,2035,1085],{"class":964},[935,2037,2025],{"class":941},[935,2039,1095],{"class":964},[935,2041,965],{"class":1077},[935,2043,1504],{"class":1080},[935,2045,971],{"class":1077},[935,2047,1085],{"class":964},[935,2049,2050],{"class":941}," 1024",[935,2052,1095],{"class":964},[935,2054,965],{"class":1077},[935,2056,1507],{"class":1080},[935,2058,971],{"class":1077},[935,2060,1085],{"class":964},[935,2062,2050],{"class":941},[935,2064,2065],{"class":964}," }",[935,2067,1911],{"class":964},[935,2069,2071,2073,2075,2077,2079,2081,2083,2085,2087,2089,2091,2093,2095,2097,2099,2101,2103,2105,2107,2109,2111,2113,2115,2118,2120],{"class":937,"line":2070},6,[935,2072,1806],{"class":964},[935,2074,965],{"class":1077},[935,2076,1811],{"class":1080},[935,2078,971],{"class":1077},[935,2080,1085],{"class":964},[935,2082,965],{"class":964},[935,2084,1929],{"class":945},[935,2086,971],{"class":964},[935,2088,1095],{"class":964},[935,2090,965],{"class":1077},[935,2092,1859],{"class":1080},[935,2094,971],{"class":1077},[935,2096,1085],{"class":964},[935,2098,965],{"class":964},[935,2100,1511],{"class":945},[935,2102,971],{"class":964},[935,2104,1095],{"class":964},[935,2106,965],{"class":1077},[935,2108,1954],{"class":1080},[935,2110,971],{"class":1077},[935,2112,1085],{"class":964},[935,2114,965],{"class":964},[935,2116,2117],{"class":945},"print",[935,2119,971],{"class":964},[935,2121,1787],{"class":964},[935,2123,2125,2128,2130,2132,2134,2136,2138,2140,2142,2144,2146,2148,2150,2152,2154,2157,2159,2161,2163,2166,2168,2170,2172,2174,2176,2178,2180,2182,2184,2186,2188,2190,2193,2195,2197,2199,2201,2203,2205,2207,2209,2211,2213],{"class":937,"line":2124},7,[935,2126,2127],{"class":1077},"      \"",[935,2129,1972],{"class":1080},[935,2131,971],{"class":1077},[935,2133,1085],{"class":964},[935,2135,1979],{"class":964},[935,2137,965],{"class":1077},[935,2139,1841],{"class":1080},[935,2141,971],{"class":1077},[935,2143,1085],{"class":964},[935,2145,965],{"class":964},[935,2147,691],{"class":945},[935,2149,971],{"class":964},[935,2151,1095],{"class":964},[935,2153,965],{"class":1077},[935,2155,2156],{"class":1080},"...",[935,2158,971],{"class":1077},[935,2160,1085],{"class":964},[935,2162,965],{"class":964},[935,2164,2165],{"class":945},"warpNode from step 1",[935,2167,971],{"class":964},[935,2169,1095],{"class":964},[935,2171,965],{"class":1077},[935,2173,20],{"class":1080},[935,2175,971],{"class":1077},[935,2177,1085],{"class":964},[935,2179,1979],{"class":964},[935,2181,965],{"class":1077},[935,2183,2156],{"class":1080},[935,2185,971],{"class":1077},[935,2187,1085],{"class":964},[935,2189,965],{"class":964},[935,2191,2192],{"class":945},"mockup from step 1",[935,2194,971],{"class":964},[935,2196,1095],{"class":964},[935,2198,965],{"class":1077},[935,2200,1620],{"class":1080},[935,2202,971],{"class":1077},[935,2204,1085],{"class":964},[935,2206,965],{"class":964},[935,2208,1754],{"class":945},[935,2210,971],{"class":964},[935,2212,2065],{"class":964},[935,2214,1911],{"class":964},[935,2216,2218,2220,2223,2225,2227,2229,2231,2233,2235,2237,2239,2241,2243,2245,2247,2249,2251,2253,2255,2257,2259,2261,2263,2265,2268,2270,2272,2274,2276,2278,2280,2282,2284,2286,2288,2290,2292,2294,2296,2298,2300,2302,2304,2307,2309,2311,2313,2315,2317,2320,2322,2324],{"class":937,"line":2217},8,[935,2219,2127],{"class":1077},[935,2221,2222],{"class":1080},"children",[935,2224,971],{"class":1077},[935,2226,1085],{"class":964},[935,2228,1836],{"class":964},[935,2230,965],{"class":1077},[935,2232,1859],{"class":1080},[935,2234,971],{"class":1077},[935,2236,1085],{"class":964},[935,2238,965],{"class":964},[935,2240,1868],{"class":945},[935,2242,971],{"class":964},[935,2244,1095],{"class":964},[935,2246,965],{"class":1077},[935,2248,1972],{"class":1080},[935,2250,971],{"class":1077},[935,2252,1085],{"class":964},[935,2254,1979],{"class":964},[935,2256,965],{"class":1077},[935,2258,2001],{"class":1080},[935,2260,971],{"class":1077},[935,2262,1085],{"class":964},[935,2264,965],{"class":964},[935,2266,2267],{"class":945},"{{ design }}",[935,2269,971],{"class":964},[935,2271,1095],{"class":964},[935,2273,965],{"class":1077},[935,2275,1209],{"class":1080},[935,2277,971],{"class":1077},[935,2279,1085],{"class":964},[935,2281,2025],{"class":941},[935,2283,1095],{"class":964},[935,2285,965],{"class":1077},[935,2287,1213],{"class":1080},[935,2289,971],{"class":1077},[935,2291,1085],{"class":964},[935,2293,2025],{"class":941},[935,2295,1095],{"class":964},[935,2297,965],{"class":1077},[935,2299,1504],{"class":1080},[935,2301,971],{"class":1077},[935,2303,1085],{"class":964},[935,2305,2306],{"class":941}," 400",[935,2308,1095],{"class":964},[935,2310,965],{"class":1077},[935,2312,1507],{"class":1080},[935,2314,971],{"class":1077},[935,2316,1085],{"class":964},[935,2318,2319],{"class":941}," 360",[935,2321,2065],{"class":964},[935,2323,1908],{"class":964},[935,2325,1131],{"class":964},[935,2327,2329],{"class":937,"line":2328},9,[935,2330,2331],{"class":964},"  ]\n",[935,2333,2335],{"class":937,"line":2334},10,[935,2336,2337],{"class":964},"}\n",[14,2339,2340,2341,2343,2344,1009,2346,2348,2349,2352,2353,2356,2357,2360],{},"Spread ",[116,2342,1182],{}," into the warp's props and add ",[116,2345,1620],{},[116,2347,20],{},". The design children sit in the warp's own box: ",[116,2350,2351],{},"0,0"," is its top-left and ",[116,2354,2355],{},"warpNode.w"," × ",[116,2358,2359],{},"warpNode.h"," is its size. Size the template's artboard to the photo.",[14,2362,2363,1206,2366,2369,2370,80],{},[18,2364,2365],{},"3. Render",[116,2367,2368],{},"template_render { \"variables\": { \"design\": \"…\" } }",", or the ",[76,2371,79],{"href":78},[23,2373,2375],{"id":2374},"tips-for-product-photos","Tips for product photos",[14,2377,2378],{},"The print borrows its folds, texture and light from the photo, so the photo has to carry them:",[31,2380,2381,2388,2398,2409,2419],{},[34,2382,2383,2384,2387],{},"Use ",[18,2385,2386],{},"directional light"," (from the left or upper left) and visible folds or texture. A flat, evenly lit garment gives the print nothing to sit in, and it will look pasted on.",[34,2389,2390,2391,2394,2395,2397],{},"Use a ",[18,2392,2393],{},"blank"," product with no logo or print where yours will go, or use ",[18,2396,402],{}," to erase it.",[34,2399,2400,2401,2404,2405,2408],{},"For screens, a screen that is ",[18,2402,2403],{},"off and black"," works best. On a screen that is on, keep the ",[18,2406,2407],{},"Screen"," slider low so the old picture does not show through.",[34,2410,2411,2412,2415,2416,2418],{},"Glass (screens, shop windows, bus shelters) should show its ",[18,2413,2414],{},"reflections",": the street, lamps, a window. ",[18,2417,183],{}," keeps exactly what the photo reflects, so perfectly black, reflection-free glass gives the print nothing to sit under.",[34,2420,2421],{},"When you generate a photo in the editor, the prompt scaffold asks for all of this for you.",[23,2423,2425],{"id":2424},"related-docs","Related docs",[31,2427,2428,2435,2442,2447],{},[34,2429,2430,2434],{},[76,2431,2433],{"href":2432},"\u002Fdocs\u002Ftemplates","Templates",": the document model, warp layers and variables",[34,2436,2437,2441],{},[76,2438,2440],{"href":2439},"\u002Fdocs\u002Fvariables","Variables",": image variables and bindings",[34,2443,2444,2446],{},[76,2445,1027],{"href":78},": formats, credits and bulk jobs",[34,2448,2449,274,2452,204,2454],{},[76,2450,2451],{"href":1046},"MCP Server",[116,2453,1038],{},[116,2455,1042],{},[2457,2458,2459],"style",{},"html pre.shiki code .sMrpa, html code.shiki .sMrpa{--shiki-default:#18181B;--shiki-dark:#FAFAFA}html pre.shiki code .sYgty, html code.shiki .sYgty{--shiki-default:#52525B;--shiki-dark:#D4D4D8}html pre.shiki code .sS_0z, html code.shiki .sS_0z{--shiki-default:#A1A1AA;--shiki-dark:#71717A}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);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .selWe, html code.shiki .selWe{--shiki-default:#A1A1AA;--shiki-default-font-weight:bold;--shiki-dark:#71717A;--shiki-dark-font-weight:bold}html pre.shiki code .sNgYv, html code.shiki .sNgYv{--shiki-default:#09090B;--shiki-default-font-weight:bold;--shiki-dark:#FFFFFF;--shiki-dark-font-weight:bold}",{"title":931,"searchDepth":958,"depth":958,"links":2461},[2462,2463,2464,2467,2471,2472,2473,2474,2475,2476],{"id":25,"depth":958,"text":26},{"id":83,"depth":958,"text":84},{"id":218,"depth":958,"text":219,"children":2465},[2466],{"id":414,"depth":976,"text":415},{"id":517,"depth":958,"text":386,"children":2468},[2469,2470],{"id":590,"depth":976,"text":591},{"id":630,"depth":976,"text":631},{"id":686,"depth":958,"text":289},{"id":835,"depth":958,"text":836},{"id":920,"depth":958,"text":921},{"id":1031,"depth":958,"text":1032},{"id":2374,"depth":958,"text":2375},{"id":2424,"depth":958,"text":2425},"Print a design onto a product photo (tee, hoodie, mug, poster, phone, tote) so it follows the folds and the light, and re-print it on every render from a variable.","md",{"layout":2480,"updatedAt":2481},"docs","2026-11-02",true,"\u002Fdocs\u002Fmockups",{"title":5,"description":2477},"docs\u002Fmockups","vZxhfn7RVm74xHDpnKP5252_EvFuYvZk4gDpavgCXnY",{"success":2482,"routes":2488,"total":3229,"generatedAt":3230,"canViewAllApiDocs":2516},[2489,2507,2530,2550,2563,2599,2624,2641,2656,2685,2703,2730,2749,2830,2903,3027,3074,3089,3134,3147,3175,3213],{"path":2490,"method":2491,"summary":2492,"description":2493,"tags":2494,"parameters":2496,"responses":2501,"actionName":2506},"\u002Fapi\u002Fv1\u002Fbrands\u002F:id","GET","Get a brand","Fetch one brand by ID. Public brands (publicOn set) need no auth; private brands require a dashboard session in the owning space. For API-key access use the MCP server (get_brand).",[2495],"Brands",[2497],{"in":2498,"name":2499,"required":2482,"description":2500},"path","id","Brand ID",{"200":2502,"404":2504},{"description":2503},"JSON { doc } — the brand with its token sets",{"description":2505},"Not found or not accessible","getBrand",{"path":2508,"method":2491,"summary":2509,"description":2510,"tags":2511,"parameters":2512,"responses":2524,"actionName":2529},"\u002Fapi\u002Fv1\u002Fbrands\u002Findex","List brands","List brands in the current space. Session-authenticated (dashboard login); pass ?public=true to list public brands anonymously. For API-key access use the MCP server (list_brands).",[2495],[2513,2518,2521],{"in":2514,"name":2515,"required":2516,"description":2517},"query","page",false,"Page number (default 1)",{"in":2514,"name":2519,"required":2516,"description":2520},"perPage","Items per page (default 50)",{"in":2514,"name":2522,"required":2516,"description":2523},"public","\"true\" to list public brands without auth",{"200":2525,"401":2527},{"description":2526},"JSON { list, count, pagesCount } of brands",{"description":2528},"Not logged in (when public is not set)","listBrands",{"path":2531,"method":2532,"summary":2533,"description":2534,"tags":2535,"parameters":2537,"responses":2540,"actionName":2549},"\u002Fapi\u002Fv1\u002Fintegrations\u002Fhooks\u002F:id","DELETE","Unsubscribe from an event (integrations)","Removes a subscription made with `POST \u002Fapi\u002Fv1\u002Fintegrations\u002Fhooks`, the way Zapier unsubscribes when a Zap turns off. Only removes subscriptions an integration created, in the key's space. Bearer API key with the `webhook.manage` scope.",[2536],"Integrations",[2538],{"in":2498,"name":2499,"required":2482,"description":2539},"Subscription id returned on subscribe.",{"200":2541,"401":2543,"403":2545,"404":2547},{"description":2542},"JSON { ok: true, id }",{"description":2544},"Missing or invalid API key, or the key lacks the webhook.manage scope (SCOPE_DENIED).",{"description":2546},"The key's user may not manage webhooks in the space (FORBIDDEN).",{"description":2548},"No integration subscription with that id in the key's space (HOOK_NOT_FOUND).","integrationsUnsubscribeHook",{"path":2531,"method":2491,"summary":2551,"description":2552,"tags":2553,"parameters":2554,"responses":2556,"actionName":2562},"Get an event subscription (integrations)","Reads a subscription made with `POST \u002Fapi\u002Fv1\u002Fintegrations\u002Fhooks`, so an automation platform can check it still exists before reusing it. 404 means it was removed (in Settings → Developers, or by an unsubscribe) and should be created again. Never returns the signing secret. Bearer API key with the `webhook.manage` scope.",[2536],[2555],{"in":2498,"name":2499,"required":2482,"description":2539},{"200":2557,"401":2559,"403":2560,"404":2561},{"description":2558},"JSON { id, event, targetUrl, enabled, templateId?, platform?, signed }",{"description":2544},{"description":2546},{"description":2548},"integrationsGetHook",{"path":2564,"method":2565,"summary":2566,"description":2567,"tags":2568,"requestBody":2569,"responses":2591,"actionName":2598},"\u002Fapi\u002Fv1\u002Fintegrations\u002Fhooks\u002Findex","POST","Subscribe to an event (integrations)","Registers an automation platform's URL for an event, the way Zapier REST hooks subscribe when a Zap turns on. bannx then POSTs `{ id, event, timestamp, spaceId, data }` to `targetUrl` each time the event happens in the key's space; for `render.completed`, `data` holds `templateId`, `format` and `url`. Bearer API key with the `webhook.manage` scope, whose user may manage webhooks in the space. `targetUrl` must be a public HTTPS URL. `templateId` is stored with the subscription so the platform can filter; delivery is not filtered.",[2536],{"required":2482,"content":2570},{"application\u002Fjson":2571},{"schema":2572},{"type":2573,"required":2574,"properties":2577},"object",[2575,2576],"targetUrl","event",{"targetUrl":2578,"event":2581,"templateId":2585,"platform":2587,"secret":2589},{"type":2579,"description":2580},"string","Public HTTPS URL that receives the events.",{"type":2579,"enum":2582,"description":2584},[2583],"render.completed","Event to subscribe to.",{"type":2579,"description":2586},"Optional template the subscriber cares about.",{"type":2579,"description":2588},"Who is subscribing, shown in Settings → Developers. Default \"integration\".",{"type":2579,"description":2590},"Optional, 16-200 characters. bannx then signs each delivery with `X-Webhook-Signature: sha256=\u003Chex HMAC-SHA256 of the raw body>` so the receiver can verify it came from bannx.",{"200":2592,"400":2594,"401":2596,"403":2597},{"description":2593},"JSON { id, event, targetUrl } — keep `id` to unsubscribe.",{"description":2595},"targetUrl is not a public HTTPS URL, or the space has too many integration subscriptions (VALIDATION).",{"description":2544},{"description":2546},"integrationsSubscribeHook",{"path":2600,"method":2491,"summary":2601,"description":2602,"tags":2603,"responses":2604,"actionName":2623},"\u002Fapi\u002Fv1\u002Fintegrations\u002Fme","Who am I (integrations)","Checks an API key and names the space it opens. Automation platforms (Zapier, Make, n8n) call it when a user connects bannx, and show `spaceName` as the connection label. Any valid key works; `scopes.apiEndpoints` lists the REST scopes the key carries (absent = every scope).",[2536],{"200":2605,"401":2621},{"description":2606,"content":2607},"The key's space.",{"application\u002Fjson":2608},{"schema":2609},{"type":2573,"properties":2610},{"spaceId":2611,"spaceName":2612,"tokenName":2613,"creditsRemaining":2614,"scopes":2616},{"type":2579},{"type":2579,"nullable":2482},{"type":2579,"nullable":2482},{"type":2615,"nullable":2482},"number",{"type":2573,"nullable":2482,"properties":2617},{"apiEndpoints":2618},{"type":2619,"items":2620},"array",{"type":2579},{"description":2622},"Missing or invalid API key (AUTH_REQUIRED, TOKEN_INVALID, TOKEN_EXPIRED).","integrationsMe",{"path":2625,"method":2491,"summary":2626,"description":2627,"tags":2628,"parameters":2629,"responses":2635,"actionName":2640},"\u002Fapi\u002Fv1\u002Fintegrations\u002Frenders","Recent renders (integrations)","The key's space's latest successful renders, newest first, each shaped like a `render.completed` event: `{ id, event, templateId, format, url, timestamp }`. Automation platforms use it as sample data for a \"New render\" trigger. Bearer API key with the `template.read` scope.",[2536],[2630,2632],{"in":2514,"name":1773,"required":2516,"description":2631},"Only renders of this template.",{"in":2514,"name":2633,"required":2516,"description":2634},"limit","1-50. Default 3.",{"200":2636,"401":2638},{"description":2637},"JSON { list: [{ id, event, templateId, format, url, timestamp }] }",{"description":2639},"Missing or invalid API key, or the key lacks the template.read scope (SCOPE_DENIED).","integrationsRecentRenders",{"path":2642,"method":2491,"summary":2643,"description":2644,"tags":2645,"parameters":2646,"responses":2649,"actionName":2655},"\u002Fapi\u002Fv1\u002Fintegrations\u002Ftemplates\u002F:id\u002Ffields","Template fields (integrations)","A template's variables as form fields — key, label, type, required, default and choices — so an automation platform can build the render form. Bearer API key with the `template.read` scope. Types: string, text (long text), number, integer, boolean, image (an image URL), color, list and object (both sent as JSON text, or a list as comma-separated text). Also says whether the template animates, so the form can default to a video format, and lists its saved variations.",[2536],[2647],{"in":2498,"name":2499,"required":2482,"description":2648},"Template ID",{"200":2650,"401":2652,"404":2653},{"description":2651},"JSON { id, name, width, height, animated, durationSeconds, fields: [{ key, label, type, required, default?, helpText?, choices? }], variations: [{ id, name }] }",{"description":2639},{"description":2654},"No template with that id in the key's space (TEMPLATE_NOT_FOUND).","integrationsTemplateFields",{"path":2657,"method":2565,"summary":2658,"description":2659,"tags":2660,"parameters":2661,"requestBody":2663,"responses":2674,"actionName":2684},"\u002Fapi\u002Fv1\u002Fintegrations\u002Ftemplates\u002F:id\u002Frender","Render a template (integrations)","Renders like `POST \u002Fapi\u002Fv1\u002Ftemplates\u002F{id}\u002Frender` and takes the same fields except `raw`, but `variables` may be form text: each value is converted to its variable's type (numbers, booleans, a list as JSON or comma-separated text, an object as JSON), undeclared names are dropped and empty values keep the template's default. Without `callbackUrl` the answer is the render route's JSON. With `callbackUrl` it answers 202 at once and POSTs that JSON to `callbackUrl` when the render finishes, or `{ ok: false, templateId, error: { code, message, status } }` when it fails: for clips that outlast an automation platform's step limit. `callbackUrl` must be a public HTTPS URL. A server restart mid-render loses an async render and no callback arrives. Bearer API key with the `template.render` scope; costs what the same render costs.",[2536],[2662],{"in":2498,"name":2499,"required":2482,"description":2648},{"required":2482,"content":2664},{"application\u002Fjson":2665},{"schema":2666},{"type":2573,"properties":2667},{"callbackUrl":2668,"format":2670,"variables":2672},{"type":2579,"description":2669},"Public HTTPS URL that receives the render result. Omit to render and answer in one request.",{"type":2579,"description":2671},"Output format, as on the render route. Default png.",{"type":2573,"description":2673},"Variable values by name; text is converted to each variable's type.",{"200":2675,"202":2677,"400":2679,"401":2681,"404":2683},{"description":2676},"Without callbackUrl: the render route's JSON { ok, templateId, format, url, creditsCharged, balanceAfter, … }.",{"description":2678},"With callbackUrl: JSON { ok: true, status: \"rendering\", templateId } — the result arrives at callbackUrl.",{"description":2680},"callbackUrl is not a public HTTPS URL (VALIDATION).",{"description":2682},"Missing or invalid API key, or the key lacks the template.render scope (SCOPE_DENIED).",{"description":2654},"integrationsRenderWithCallback",{"path":2686,"method":2491,"summary":2687,"description":2688,"tags":2689,"parameters":2690,"responses":2698,"actionName":2702},"\u002Fapi\u002Fv1\u002Fintegrations\u002Ftemplates\u002Findex","List templates (integrations)","The key's space templates, most recently updated first, for a template picker on an automation platform. Bearer API key with the `template.read` scope. `search` matches the name or description.",[2536],[2691,2694,2696],{"in":2514,"name":2692,"required":2516,"description":2693},"search","Text the name or description contains.",{"in":2514,"name":2515,"required":2516,"description":2695},"1-based page. Default 1.",{"in":2514,"name":2519,"required":2516,"description":2697},"Rows per page, 1-100. Default 50.",{"200":2699,"401":2701},{"description":2700},"JSON { list: [{ id, name, description, type, width, height, updatedOn }], count, page, perPage, pagesCount }",{"description":2639},"integrationsListTemplates",{"path":2704,"method":2491,"summary":2705,"description":2706,"tags":2707,"group":2708,"parameters":2709,"responses":2722,"actionName":2729},"\u002Fapi\u002Fv1\u002Fpublic\u002Fcontent\u002F:collection\u002F:slug","Get an entry","Read a single PUBLISHED entry by slug. Authenticate with a content.read API key (Authorization: Bearer …). The slug is matched against the collection's configured preview.slugField (defaults to \"slug\"). Only liveData is returned; use ?depth= to resolve references and ?variants= for personalization.",[2708],"Content",[2710,2713,2716,2719],{"in":2498,"name":2711,"required":2482,"description":2712},"collection","The collection's API name",{"in":2498,"name":2714,"required":2482,"description":2715},"slug","The entry slug",{"in":2514,"name":2717,"required":2516,"description":2718},"depth","Resolve reference fields to this depth (default 0)",{"in":2514,"name":2720,"required":2516,"description":2721},"variants","Comma-separated variant ids; returns personalization-resolved values",{"200":2723,"401":2725,"404":2727},{"description":2724},"JSON { doc } — the published entry",{"description":2726},"Missing or invalid API token",{"description":2728},"Collection or entry not found","publicGetContentBySlug",{"path":2731,"method":2491,"summary":2732,"description":2733,"tags":2734,"group":2708,"parameters":2735,"responses":2742,"actionName":2748},"\u002Fapi\u002Fv1\u002Fpublic\u002Fcontent\u002F:collection\u002Findex","List entries","List PUBLISHED entries in a collection. Authenticate with a content.read API key (Authorization: Bearer …). Only liveData is returned — never drafts. Values under `data` are keyed by field API name. Supports pagination, reference resolution (?depth=), and personalization (?variants=).",[2708],[2736,2737,2738,2740,2741],{"in":2498,"name":2711,"required":2482,"description":2712},{"in":2514,"name":2515,"required":2516,"description":2517},{"in":2514,"name":2519,"required":2516,"description":2739},"Items per page (default 20)",{"in":2514,"name":2717,"required":2516,"description":2718},{"in":2514,"name":2720,"required":2516,"description":2721},{"200":2743,"401":2745,"404":2746},{"description":2744},"JSON { list, count, pagesCount } of published entries",{"description":2726},{"description":2747},"Collection not found","publicListContent",{"path":2750,"method":2565,"summary":2751,"description":2752,"tags":2753,"parameters":2755,"requestBody":2757,"responses":2816,"actionName":2829},"\u002Fapi\u002Fv1\u002Ftemplates\u002F:id\u002Fbulk","Bulk render","Render one file per row of `rows` (each row is variable values by name) and pack them into a ZIP — or, with `format: \"pdf\"` and `output: \"pdf\"`, merge every row into one PDF. Queued: the response is a job id — poll `GET \u002Fapi\u002Fv1\u002Ftemplates\u002Fbulk\u002F{jobId}` for progress and the download URL. Bearer API key with the `template.render` scope; credits for every row are reserved up front.",[2754],"Creatives",[2756],{"in":2498,"name":2499,"required":2482,"description":2648},{"required":2482,"content":2758},{"application\u002Fjson":2759},{"schema":2760},{"type":2573,"required":2761,"properties":2763},[2762],"rows",{"rows":2764,"format":2767,"pages":2777,"output":2781,"dpi":2785,"scale":2790,"size":2793,"fit":2795,"fps":2800,"quality":2803,"variation":2808,"variants":2810,"brand":2814},{"type":2619,"items":2765,"description":2766},{"type":2573},"One object per output: variable values by name. Optional `id` \u002F `name` keys name the file; a reserved `_filename` key sets the file name exactly (no extension, never passed to the template). Reserved `_variation` (a saved variation id or name, or several comma-separated) renders that row with its own variation in place of the run's; `_scene` (still formats, counted from 0) renders that page of the row instead of the first. A dotted key fills part of an object or list variable (`to.name`, `items.0.qty`) and keeps the template's saved values for the rest; a string holding JSON (`{…}` \u002F `[…]`) fills an object or list variable. Max 500.",{"type":2579,"enum":2768,"description":2776},[2769,2770,2771,2772,2773,2774,2775],"png","webp","svg","pdf","mp4","webm","gif","Output format for every row. Default png.",{"type":2579,"enum":2778,"description":2780},[2779],"all","`all`: every page of a still template as its own file, per row (`\u003Crow>-01-\u003Cpage>.png`, …), each page costing a still's credits. png, webp or svg only, and not with a row `_scene`.",{"type":2579,"enum":2782,"description":2784},[2783,2772],"zip","`zip` (default): one file per row in a ZIP. `pdf`: every row's pages merged, in row order, into one PDF — only with `format: \"pdf\"` (VALIDATION otherwise). Rows that fail are left out and listed in `errors`.",{"type":2786,"minimum":2787,"maximum":2788,"description":2789},"integer",72,1200,"PDF only: page size = pixels × 72 \u002F dpi. Unset: the template's export default, else 300 on a print size (A4, Letter, business card, 4×6 label…) so the PDF comes out at paper size, else 72 (1 px = 1 pt).",{"type":2615,"minimum":2791,"maximum":990,"description":2792},0.1,"Resolution multiplier. Default 1.",{"type":2579,"description":2794},"Render every row at another size: a size preset id or WIDTHxHEIGHT (see the single render's `size`). A row may override it with a reserved `_size` field (and `_fit`), e.g. one record as a story and another as a square in the same run.",{"type":2579,"enum":2796,"description":2799},[2797,2798],"reflow","scale","How the design adapts to `size`. Default reflow.",{"type":2786,"minimum":938,"maximum":2801,"description":2802},60,"Video formats only.",{"type":2579,"enum":2804},[2805,2806,2807],"low","medium","high",{"type":2579,"description":2809},"Saved variation (id, or its name as the editor shows it) to apply to every row — or several, as a JSON array or comma-separated string, stacked in order (at most one per single-select group). A row's `_variation` replaces it.",{"type":2619,"maxItems":2334,"items":2811,"description":2813},{"type":2579,"description":2812},"A variation id or name; a list of them (or a comma-separated string) to combine in one file; or \"\" for the row as it is set.","Render every row once per look: N rows × M looks = N × M files (at most 1000). Each entry is a variation id or name, or several to combine in one file (an array, or comma-separated), stacked on top of the row's `_variation` (else the run's `variation`); `\"\"` is the row as it is set. Files are named `\u003Crow>-\u003Clook name>` (the `\"\"` look keeps `\u003Crow>`), each costing a render.",{"type":2579,"description":2815},"Render every row under another brand of the key's space — a brandId, brand name or website URL. The template keeps its own brand. Another space's brand is BRAND_NOT_FOUND.",{"200":2817,"401":2819,"402":2821,"404":2823,"409":2825,"422":2827},{"description":2818},"JSON { jobId, total }",{"description":2820},"Missing or invalid API key, or the key lacks the template.render scope",{"description":2822},"Not enough credits for the batch",{"description":2824},"Template not found in the key's space, or `brand` names no brand of it (BRAND_NOT_FOUND)",{"description":2826},"`brand` matches several brands (BRAND_AMBIGUOUS)",{"description":2828},"Invalid body (VALIDATION), e.g. `output: \"pdf\"` with a format other than pdf","creativeBulkApi",{"path":2831,"method":2491,"summary":2832,"description":2833,"tags":2834,"parameters":2835,"responses":2891,"actionName":2902},"\u002Fapi\u002Fv1\u002Ftemplates\u002F:id\u002Frender","Render a template (GET)","Render a template by ID from the URL alone: options and variables as query parameters, the file streamed back by default (`output=json` stores it and returns `{ url }`). Every query key that is not a render option is a template variable, e.g. `?title=Hello&count=3`; `variables` may also be a JSON object string, and `var.\u003Cname>` \u002F `variables[\u003Cname>]` name a variable that collides with an option. Auth: `Authorization: Bearer` or `?api_token=` — a key in the URL must be scoped to the Template Render API only (a render-only key), so leaking the URL leaks nothing else.",[2754],[2836,2837,2840,2843,2846,2849,2852,2855,2857,2860,2862,2865,2868,2871,2874,2877,2880,2883,2886,2889],{"in":2498,"name":2499,"required":2482,"description":2648},{"in":2514,"name":2838,"description":2839},"api_token","A render-only API key (endpoint scope exactly template.render, no MCP tools). Alternative to the Authorization header.",{"in":2514,"name":2841,"description":2842},"format","png (default), webp, svg, pdf, webm, mp4, gif, zip, html5",{"in":2514,"name":2844,"description":2845},"clickUrl","Required for html5: absolute HTTP(S) destination URL",{"in":2514,"name":2847,"description":2848},"loops","HTML5 repetitions: 1–10, default 1",{"in":2514,"name":2850,"description":2851},"network","HTML5 network preset: generic (default), google-ads, dv360, cm360, amazon-dsp, adroll",{"in":2514,"name":2853,"description":2854},"output","`json` to store the file and return { url, timings } instead of the bytes",{"in":2514,"name":2798,"description":2856},"Resolution multiplier 0.25–4",{"in":2514,"name":2858,"description":2859},"quality","standard | high",{"in":2514,"name":1318,"description":2861},"Still formats: scene index. Omit on a pdf of a still (non-animated) template to get every scene as a page.",{"in":2514,"name":2863,"description":2864},"frame","Still formats: frame index within the scene",{"in":2514,"name":2866,"description":2867},"nodeId","Still formats: render one layer",{"in":2514,"name":2869,"description":2870},"variation","Saved variation id, or several comma-separated (stacked in order; at most one per single-select group)",{"in":2514,"name":2872,"description":2873},"brand","Render with another brand of the key's space for this render only: a brandId, brand name or the brand's website URL. The template keeps its own brand. Another space's brand is BRAND_NOT_FOUND (404); a name matching several brands is BRAND_AMBIGUOUS (409).",{"in":2514,"name":2875,"description":2876},"brandVariant","Brand campaign variant id(s), comma-separated",{"in":2514,"name":2878,"description":2879},"draft","`true` renders the current document instead of the published version",{"in":2514,"name":2881,"description":2882},"size","Another output size: a preset id (og, story, leaderboard, …) or WIDTHxHEIGHT; the template is not changed",{"in":2514,"name":2884,"description":2885},"fit","reflow (default) | scale — how the design adapts to `size`",{"in":2514,"name":2887,"description":2888},"dpi","PDF only: print resolution 72–1200 (page = pixels × 72 \u002F dpi points). Default: the template's exportDefaults.dpi, else 300 on a print-size template, else 72",{"in":2514,"name":1829,"description":2890},"JSON object of variables (optional — bare keys work too)",{"200":2892,"401":2894,"403":2896,"404":2898,"409":2900},{"description":2893},"The rendered file (default; `x-credits-charged` \u002F `x-credits-balance` headers carry what it cost), or JSON { ok, templateId, format, url, timings, creditsCharged, balanceAfter, brand? } with output=json",{"description":2895},"Missing or invalid API key",{"description":2897},"The key lacks the template.render scope, or a URL key is not render-only",{"description":2899},"Template not found in the key's space, or `brand` names no brand of the key's space (BRAND_NOT_FOUND)",{"description":2901},"`brand` matches several brands of the space (BRAND_AMBIGUOUS)","creativeRenderApiGet",{"path":2831,"method":2565,"summary":2904,"description":2905,"tags":2906,"parameters":2907,"requestBody":2909,"responses":2976,"actionName":3026},"Render a template","Render a creative template by ID to png, webp, svg, pdf, webm, mp4, gif, zip (frame sequence), or html5 (standalone ad ZIP), with variable overrides. Bearer API key with the `template.render` scope. `{{ brand.* }}` resolves against `brand` when given (another brand of the key's space, for this render only), else the template's brand, else the space default. Returns `{ url, creditsCharged, balanceAfter }` with the uploaded render; `raw: true` (or `?format=binary`) streams the bytes instead.",[2754],[2908],{"in":2498,"name":2499,"required":2482,"description":2648},{"required":2516,"content":2910},{"application\u002Fjson":2911},{"schema":2912},{"type":2573,"properties":2913},{"format":2914,"clickUrl":2918,"loops":2920,"network":2922,"variables":2931,"scale":2933,"fps":2935,"quality":2937,"scene":2941,"frame":2943,"nodeId":2945,"variation":2947,"brandVariant":2949,"brandVariantMode":2952,"brandTokens":2957,"brand":2959,"draft":2961,"size":2964,"fit":2966,"pages":2969,"dpi":2972,"raw":2974},{"type":2579,"enum":2915,"description":2917},[2769,2770,2771,2772,2774,2773,2775,2783,2916],"html5","Output format. Default png.",{"type":2579,"description":2919},"Required for html5: HTTP(S) click-through URL.",{"type":2786,"minimum":938,"maximum":2334,"description":2921},"HTML5 playback repetitions. Default 1.",{"type":2579,"enum":2923,"description":2930},[2924,2925,2926,2927,2928,2929],"generic","google-ads","dv360","cm360","amazon-dsp","adroll","HTML5 ad network preset the report is judged against. Default generic.",{"type":2573,"description":2932},"Variable overrides by name.",{"type":2615,"minimum":2934,"maximum":990,"description":2792},0.25,{"type":2786,"minimum":938,"maximum":2801,"description":2936},"Frames per second for video formats. Default 30.",{"type":2579,"enum":2938,"description":2940},[2939,2807],"standard","Render quality tier. Default from the template, else high.",{"type":2786,"description":2942},"Still formats: scene index to render. Omit on a pdf of a still (non-animated) template to get every scene as a page.",{"type":2786,"description":2944},"Still formats: frame index within the scene.",{"type":2579,"description":2946},"Still formats: render one layer instead of the artboard.",{"type":2579,"description":2948},"Saved variation id to apply before rendering — or several, as a JSON array or a comma-separated string, stacked in order: later wins on the same property; at most one per single-select group (VARIATION_CONFLICT).",{"type":2619,"items":2950,"description":2951},{"type":2579},"Brand campaign variant ids to render under. Replaces whatever the brand currently has active, so the result is deterministic. Accepts a single id or a comma-separated string too.",{"type":2579,"enum":2953,"description":2956},[2954,2955],"replace","add","How brandVariant combines with the brand's active set. Default replace.",{"type":2573,"description":2958},"Brand token values to render with, REPLACING the resolved brand. Use it to render exactly what a preview shows, unsaved edits included. Bounded in size and depth. Exclusive with `brand`.",{"type":2579,"description":2960},"Render with another brand of the key's space for this render only — a brandId, brand name or the brand's website URL (matched, never fetched). The template keeps its own brand, so concurrent renders under different brands do not race. Another space's brand (public catalog included) is BRAND_NOT_FOUND; a name matching several brands is BRAND_AMBIGUOUS with `data.candidates`.",{"type":2962,"description":2963},"boolean","Render the current (unpublished) document instead of the published version. Default false: a published template renders its published snapshot; a never-published one renders its draft.",{"type":2579,"description":2965},"Render at another size without changing the template: a size preset id (e.g. \"og\", \"story\", \"leaderboard\") or \"WIDTHxHEIGHT\" (16–8192 px a side, 64 MP max); an object { preset } or { width, height } is accepted too. The response echoes `size: { width, height, fit, preset?, from }`.",{"type":2579,"enum":2967,"description":2968},[2797,2798],"How the design adapts to `size`: reflow (layer constraints + auto-layout, default) or scale (uniform scale to fit, letterboxed).",{"type":2579,"enum":2970,"description":2971},[2779],"Every page of a still template as one still each — one page per scene, a scene repeated over data one page per item, resolved with this request's variables. Still formats only (png, webp, svg; a pdf already holds every page), exclusive with scene and nodeId, at most 50 pages (PAGE_LIMIT_EXCEEDED). Costs one still per page, reserved up front. The JSON answer is `{ pages: \u003Ccount>, pageUrls: [{ index, name, url, fileId }], zipUrl }`; with `raw` the body is a ZIP (`application\u002Fzip`) of `01-\u003Cpage name>.\u003Cext>`, `02-…`.",{"type":2786,"minimum":2787,"maximum":2788,"description":2973},"PDF only: print resolution. Page size = pixels × 72 \u002F dpi points, so a 1200 × 1800 px label at 300 is a 4 × 6 in page. Default: the template's exportDefaults.dpi, else 300 on a print-size template (A4, Letter, business card, 4×6 label…), else 72 (1 px = 1 pt). Out of range is VALIDATION (422).",{"type":2962,"description":2975},"Stream the file bytes instead of returning JSON.",{"200":2977,"401":3020,"404":3021,"409":3022,"422":3024},{"description":2978,"content":2979},"JSON { ok, templateId, format, url, timings, creditsCharged, balanceAfter, brand?, variation?, still?, pages? (pdf), size?, warnings? ([{ nodeId, name, reason }] — layers skipped or drawn as a fallback, SVG\u002FPDF fallbacks, text caught mid-textAnimate, pagination and soundtrack notes) } — or the raw file when `raw`\u002Fbinary is requested (then `x-credits-charged` \u002F `x-credits-balance` headers carry the credits). With `pages: \"all\"`: { ok, templateId, format, pages (count), pageUrls: [{ index, name, url, fileId }], zipUrl, timings, creditsCharged, balanceAfter, … } — or, raw, a ZIP of the numbered stills (`x-page-count` header).",{"application\u002Fjson":2980},{"schema":2981},{"type":2573,"properties":2982},{"ok":2983,"templateId":2984,"format":2985,"url":2986,"creditsCharged":2988,"balanceAfter":2990,"brand":2992,"pages":2997,"pageUrls":2999,"zipUrl":3011,"warnings":3013},{"type":2962},{"type":2579},{"type":2579},{"type":2579,"description":2987},"The uploaded render.",{"type":2615,"description":2989},"Credits this render cost the key's space (a still 1, a clip 5, a PDF 1 per page by default).",{"type":2615,"description":2991},"The space's spendable credits once this render's charge lands. Read when the credits were reserved, so other renders in the same space can move it.",{"type":2573,"properties":2993,"description":2996},{"id":2994,"name":2995},{"type":2579},{"type":2579,"nullable":2482},"Present when `brand` picked the brand for this render.",{"type":2786,"description":2998},"How many pages the output holds: a PDF's page count, or the number of stills a `pages: \"all\"` render produced.",{"type":2619,"description":3000,"items":3001},"`pages: \"all\"` only: the rendered pages, in order.",{"type":2573,"properties":3002},{"index":3003,"name":3005,"url":3007,"fileId":3009},{"type":2786,"description":3004},"0-based page (scene) index — the `scene` a single render takes",{"type":2579,"description":3006},"the page's name (a templated scene name is filled in)",{"type":2579,"description":3008},"the page's still",{"type":2579,"description":3010},"the page's media library file id — what a social post's `fileIds` take (order = slide order)",{"type":2579,"description":3012},"`pages: \"all\"` only: a ZIP of every page as `01-\u003Cname>.\u003Cext>`, `02-…`.",{"type":2619,"items":3014,"description":3019},{"type":2573,"properties":3015},{"nodeId":3016,"name":3017,"reason":3018},{"type":2579,"nullable":2482},{"type":2579,"nullable":2482},{"type":2579},"Where the output differs from the editor, and why: layers skipped or drawn as a fallback (a source that failed to load, a raster past the GPU limit, SVG\u002FPDF layers rasterized or approximated, fonts or images not embedded), text exported mid-textAnimate, PDF pagination notes and video soundtrack notes. nodeId and name are null for document-wide notes.",{"description":2820},{"description":2899},{"description":3023},"`brand` matches several brands of the space (BRAND_AMBIGUOUS, see data.candidates)",{"description":3025},"`pages: \"all\"` with a pdf or video format, with scene\u002FnodeId, or on an animated template, or `dpi` outside 72–1200 (VALIDATION); or the set is over 50 pages (PAGE_LIMIT_EXCEEDED)","creativeRenderApi",{"path":3028,"method":2565,"summary":3029,"description":3030,"tags":3031,"parameters":3032,"requestBody":3034,"responses":3063,"actionName":3073},"\u002Fapi\u002Fv1\u002Ftemplates\u002F:id\u002Fsigned-urls","Sign render URLs","Return signed image URLs (`\u002Fr\u002F:id?…&sig=…`) for one variable set or up to 500 rows. A signed URL needs no key or session: the signature covers the template id and every parameter, so it can sit in an email, a CRM field, an OG tag or an `\u003Cimg>` on any site. Each distinct URL renders once (charged like one still) and is served from cache after; republishing the template refreshes them. Still formats only (png, webp), scale ≤ 2, published version only. Requires the template.render scope.",[2754],[3033],{"in":2498,"name":2499,"required":2482,"description":2648},{"required":2516,"content":3035},{"application\u002Fjson":3036},{"schema":3037,"example":3053},{"type":2573,"properties":3038},{"variables":3039,"rows":3041,"options":3049,"pages":3050},{"type":2573,"additionalProperties":2482,"description":3040},"Variables for ONE URL",{"type":2619,"maxItems":3042,"description":3043,"items":3044},500,"Many URLs — one per row; each row may override `options`",{"type":2573,"properties":3045},{"variables":3046,"options":3047},{"type":2573,"additionalProperties":2482},{"$ref":3048},"#\u002Fcomponents\u002Fschemas\u002FSignedRenderOptions",{"$ref":3048},{"type":2579,"enum":3051,"description":3052},[2779],"One URL per PAGE for every row: a still template's scenes (a scene repeated over data is one page per item, resolved with the row's variables), each signed with its `scene` index — so a carousel's keyless links exist before anything renders. Exclusive with `options.scene` and `nodeId`; at most 50 pages a row and 500 URLs a call (PAGE_LIMIT_EXCEEDED \u002F VALIDATION). Each returned row then carries `scene` and `page: { index, name }`.",{"rows":3054,"options":3062},[3055,3059],{"variables":3056},{"name":3057,"plan":3058},"Ada","Team",{"variables":3060},{"name":3061,"plan":657},"Grace",{"format":2770},{"200":3064,"401":3066,"403":3067,"404":3069,"422":3071},{"description":3065},"JSON { templateId, published, urls: [{ url, path, variables, scene?, page? }] } — `published: false` means the URLs will 404 until the template is published; `scene` and `page: { index, name }` appear with `pages: \"all\"`",{"description":2895},{"description":3068},"The key lacks the template.render scope",{"description":3070},"Template not found in the key's space, or `options.brand` names no brand of it (BRAND_NOT_FOUND)",{"description":3072},"A variable name collides with a render option, an option is out of range, `pages: \"all\"` is combined with `options.scene` \u002F `nodeId` or signs more than 500 URLs (VALIDATION), or a row resolves to more than 50 pages (PAGE_LIMIT_EXCEEDED)","signTemplateRenderUrlsApi",{"path":3075,"method":2491,"summary":3076,"description":3077,"tags":3078,"parameters":3079,"responses":3083,"actionName":3088},"\u002Fapi\u002Fv1\u002Ftemplates\u002Fbulk\u002F:jobId","Bulk render status","Progress of a bulk render started with `POST \u002Fapi\u002Fv1\u002Ftemplates\u002F{id}\u002Fbulk`: state, per-row counts, and on completion the download — `zipUrl` for a ZIP run, `fileUrl` for an `output: \"pdf\"` run (one merged PDF); `output` says which. Poll every few seconds until `state` is `completed` or `failed`.",[2754],[3080],{"in":2498,"name":3081,"required":2482,"description":3082},"jobId","Job id from the bulk request",{"200":3084,"404":3086},{"description":3085},"JSON { jobId, state, total, completed, succeeded, failed, currentItem?, errors, output, zipUrl?, fileUrl? }",{"description":3087},"No such job in the key's space","creativeBulkStatusApi",{"path":3090,"method":2491,"summary":3091,"description":3092,"tags":3093,"parameters":3094,"responses":3130,"actionName":3133},"\u002Fapi\u002Fv1\u002Ftemplates\u002Fpublic","List public templates","List published community\u002Fgallery templates from their published snapshots. No authentication required.",[2433],[3095,3097,3100,3109,3110,3114,3118,3122,3124],{"in":2514,"name":2692,"required":2516,"description":3096},"Semantic + keyword search over name, description and each template's design digest (format, palette, fonts, layout), ranked by relevance (\"job application\" finds the hiring posts, \"dark editorial portrait\" finds the look); max 80 chars. Falls back to a substring match when search is unavailable.",{"in":2514,"name":3098,"required":2516,"description":3099},"category","Category filter, or \"featured\" for the curated list",{"in":2514,"name":2841,"required":2516,"description":3101,"schema":3102},"Output format filter: creative (designs — also matches templates with no format set), video, doc, html-ad, mockups, backgrounds",{"type":2579,"enum":3103},[3104,3105,3106,3107,12,3108],"creative","video","doc","html-ad","backgrounds",{"in":2514,"name":2515,"required":2516,"description":2517},{"in":2514,"name":3111,"required":2516,"description":3112,"schema":3113},"usesBrandVariables","Filter published designs: true uses brand-kit variables, false uses none",{"type":2962},{"in":2514,"name":3115,"required":2516,"description":3116,"schema":3117},"isPremium","Filter by access: true lists premium templates only, false lists free ones (anything not flagged premium)",{"type":2962},{"in":2514,"name":3119,"required":2516,"description":3120,"schema":3121},"features","Comma-separated feature tags the published snapshot must ALL carry, from its `features.tags` (e.g. data.loops, data.computation, data.class.fillable, motion.animated, layout.pagination); 1-8 tags. See the Template features section of the templates guide.",{"type":2579},{"in":2514,"name":2519,"required":2516,"description":3123},"Items per page (max 100)",{"in":2514,"name":3125,"required":2516,"description":3126,"schema":3127},"view","Row shape. `card` returns only what a gallery card shows: `_id`, `slug`, `name`, `type`, `format`, `category`, `isPremium` (when true), `createdBy`, `thumbnail` (URLs only, variants up to 960 px wide; `src` is omitted when variants exist, use the largest), `thumbnailCurrent`, `contentHash`, `usesBrandVariables`, `width`, `height`, `sampleCount` (stored sample sets), `pages` (page count of a still template whose `templateSettings.pageView` is `carousel`, when above 1: its scenes after scene `repeat` \u002F `if` resolve against the default values, so one scene repeated over a 4-item list counts 4) and, for videos, `video` \u002F `meta` poster URLs, plus `_lean: true`. No document, variables or design digest; fetch one template with GET \u002Fapi\u002Fv1\u002Ftemplates\u002Fpublic\u002F{id} for those. Omit for the full published row.",{"type":2579,"enum":3128},[3129],"card",{"200":3131},{"description":3132},"JSON { list, count, pagesCount }. Each row is the template as published, or a card row with view=card","listPublicTemplates",{"path":3135,"method":2491,"summary":3136,"description":3137,"tags":3138,"parameters":3139,"responses":3141,"actionName":3146},"\u002Fapi\u002Fv1\u002Ftemplates\u002Fpublic\u002F:id","Get a public template","Fetch one published template by ID, as published. Only templates with publicOn are returned; private IDs 404. No authentication required.",[2433],[3140],{"in":2498,"name":2499,"required":2482,"description":2648},{"200":3142,"404":3144},{"description":3143},"JSON { doc } — the template as published (creative doc under templateSettings.creative)",{"description":3145},"Template not found or not public","getPublicTemplateDoc",{"path":3148,"method":2491,"summary":3149,"description":3150,"tags":3151,"parameters":3153,"responses":3169,"actionName":3174},"\u002Fapi\u002Fv1\u002Fworkflows\u002F:id\u002Fprocess","Run a workflow (GET)","Embed a workflow output. Auth is Authorization: Bearer or ?api_token=, with the workflow.process scope. GET cannot upload files. With cacheId, serves the cached output (run once via POST, then embed). Otherwise runs from query text inputs (text_\u003CnodeId> or textInputs JSON). Workflows that need an image can only be served from cache. Raw bytes by default; format=json returns metadata. See \u002Fdocs\u002Fworkflows.",[3152],"Workflows",[3154,3156,3161,3164,3167],{"in":2498,"name":2499,"required":2482,"description":3155},"Workflow ID",{"in":2514,"name":2841,"required":2516,"schema":3157,"description":3160},{"type":2579,"enum":3158},[1067,3159],"binary","binary (default) streams the image; json returns metadata.",{"in":2514,"name":3162,"required":2516,"description":3163},"cacheId","Serve this cached output. The usual path for an \u003Cimg src>.",{"in":2514,"name":3165,"required":2516,"description":3166},"textInputs","JSON object of { nodeId: value } when there is no cacheId.",{"in":2514,"name":2838,"required":2516,"description":3168},"API key, for embedding where a header cannot be set. Same workflow.process scope as Bearer.",{"200":3170,"403":3172},{"description":3171},"Raw image bytes, or JSON metadata when format=json.",{"description":3173},"API key missing the workflow.process scope, or not scoped to a space.","processWorkflowGet",{"path":3148,"method":2565,"summary":3176,"description":3177,"tags":3178,"parameters":3179,"requestBody":3191,"responses":3204,"actionName":3212},"Run a workflow","Run a workflow and return its output. Bearer API key with the `workflow.process` scope, belonging to the workflow's space. Body is multipart\u002Fform-data. Omit `format` or pass `json` for metadata, base64 and a file URL; `format=binary` streams the raw bytes (`x-workflow-run-id`, `x-workflow-cache`). `cacheId` stores the output and later calls with the same key return it without re-running. `async=true` returns a job id immediately — poll GET \u002Fapi\u002Fv1\u002Fworkflows\u002F:id\u002Fprocess\u002Fjobs\u002F:jobId. A synchronous call waits about 55 seconds, then returns 202 while the run continues. See \u002Fdocs\u002Fworkflows.",[3152],[3180,3181,3185,3187],{"in":2498,"name":2499,"required":2482,"description":3155},{"in":2514,"name":2841,"required":2516,"schema":3182,"description":3184},{"type":2579,"enum":3183},[1067,3159],"json (default) returns metadata; binary streams the output bytes.",{"in":2514,"name":3162,"required":2516,"description":3186},"Opt-in output cache key, 1–128 chars (A–Z a–z 0–9 . _ -).",{"in":2514,"name":3188,"required":2516,"schema":3189,"description":3190},"async",{"type":2962},"If true, enqueue the run and return a jobId.",{"required":2516,"content":3192},{"multipart\u002Fform-data":3193},{"schema":3194},{"type":2573,"properties":3195},{"file":3196,"nodeFile_\u003CnodeId>":3198,"text_\u003CnodeId>":3200,"textInputs":3202},{"type":2579,"format":3159,"description":3197},"Primary image input.",{"type":2579,"format":3159,"description":3199},"File for one input node (image or document). Replace \u003CnodeId> with that node's id.",{"type":2579,"description":3201},"Text for one text-input node. Replace \u003CnodeId> with that node's id.",{"type":2579,"description":3203},"JSON object of { nodeId: value } for every text input at once.",{"200":3205,"202":3207,"400":3209,"403":3211},{"description":3206},"JSON { ok, workflowId, runId, status, cached, durationMs, output: { url, base64, mimeType, width, height } }, or the raw bytes when format=binary.",{"description":3208},"JSON { ok, runId, status: \"running\", workflowId } when a synchronous run is still going. The run finishes in the background and workflow.executed fires.",{"description":3210},"Missing workflow id, or a cacheId that fails the key rules.",{"description":3173},"processWorkflow",{"path":3214,"method":2491,"summary":3215,"description":3216,"tags":3217,"parameters":3218,"responses":3222,"actionName":3228},"\u002Fapi\u002Fv1\u002Fworkflows\u002F:id\u002Fprocess\u002Fjobs\u002F:jobId","Workflow run status","Poll a job enqueued with POST \u002Fapi\u002Fv1\u002Fworkflows\u002F:id\u002Fprocess?async=true. Bearer API key with the workflow.process scope. The job must belong to the key's space and this workflow. state moves waiting, then active, then completed or failed. See \u002Fdocs\u002Fworkflows.",[3152],[3219,3220],{"in":2498,"name":2499,"required":2482,"description":3155},{"in":2498,"name":3081,"required":2482,"description":3221},"Job id returned by the async process call.",{"200":3223,"403":3225,"404":3226},{"description":3224},"JSON { jobId, workflowId, state, progress, result, failedReason }. result is set when state is completed.",{"description":3173},{"description":3227},"Job not found for this workflow and space.","getWorkflowProcessJob",22,"2026-11-14T17:41:46.371Z",[3232,3233,3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244],"i-ph:caret-down","i-ph:list","i-ph:caret-right","i-ph:copy","i-ph:x-logo","i-ph:youtube-logo","i-ph:instagram-logo","i-ph:linkedin-logo","i-tabler:brand-producthunt","i-ph:desktop","i-ph:sun","i-ph:moon","i-ph:translate",1794678125469]