[{"data":1,"prerenderedAt":841},["ShallowReactive",2],{"\u002Fdocs\u002Fgenerate-video-via-api":3},{"id":4,"title":5,"body":6,"category":831,"date":832,"description":833,"extension":834,"heroImage":835,"meta":836,"navigation":329,"path":837,"readingMinutes":134,"seo":838,"stem":839,"tool":831,"__hash__":840},"docs\u002Fdocs\u002Fgenerate-video-via-api.md","Generate video via API",{"type":7,"value":8,"toc":824},"minimark",[9,14,27,37,54,58,73,168,172,184,190,201,727,731,799,803,820],[10,11,13],"h2",{"id":12},"the-whole-loop","The whole loop",[15,16,17,18,22,23,26],"p",{},"Generating video with Bluepic is one request. You POST the ",[19,20,21],"code",{},"templateId"," of an animated template plus the data to fill it, ask for a video ",[19,24,25],{},"format",", and the API renders it and hands back a hosted MP4.",[28,29,34],"pre",{"className":30,"code":32,"language":33},[31],"language-text","POST https:\u002F\u002Fapi.bluepic.io\u002Fapi\u002Frender\n{ \"templateId\": \"…\", \"data\": { … }, \"format\": \"mp4\" }\n","text",[19,35,32],{"__ignoreMap":36},"",[15,38,39,40,43,44,47,48,53],{},"An animated template is just a normal template with an ",[19,41,42],{},"animation"," (a duration and a frame rate) whose properties move over a ",[19,45,46],{},"TIME"," clock. If you have not built one yet, see ",[49,50,52],"a",{"href":51},"\u002Fdocs\u002Fhow-to-video-templates","how to build a video template in Studio",".",[10,55,57],{"id":56},"try-it-with-no-key","Try it with no key",[15,59,60,61,64,65,68,69,72],{},"There is a public demo video template you can render with no API key and no credit cost. Its inputs are a photo (",[19,62,63],{},"image4_image",") and two lines of text (",[19,66,67],{},"text2_text",", ",[19,70,71],{},"text1_text",").",[28,74,78],{"className":75,"code":76,"language":77,"meta":36,"style":36},"language-bash shiki shiki-themes github-dark","curl -N -X POST \"https:\u002F\u002Fapi.bluepic.io\u002Fapi\u002Frender\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"templateId\": \"7ccf097c-10f2-4efc-bd03-8abe967c4711\",\n    \"data\": {\n      \"text2_text\": \"HEAR ME SPEAK AT\",\n      \"text1_text\": \"THE BLUEPIC EVENT!\"\n    },\n    \"format\": \"mp4\"\n  }'\n","bash",[19,79,80,106,117,126,132,138,144,150,156,162],{"__ignoreMap":36},[81,82,85,89,93,96,100,103],"span",{"class":83,"line":84},"line",1,[81,86,88],{"class":87},"svObZ","curl",[81,90,92],{"class":91},"sDLfK"," -N",[81,94,95],{"class":91}," -X",[81,97,99],{"class":98},"sU2Wk"," POST",[81,101,102],{"class":98}," \"https:\u002F\u002Fapi.bluepic.io\u002Fapi\u002Frender\"",[81,104,105],{"class":91}," \\\n",[81,107,109,112,115],{"class":83,"line":108},2,[81,110,111],{"class":91},"  -H",[81,113,114],{"class":98}," \"Content-Type: application\u002Fjson\"",[81,116,105],{"class":91},[81,118,120,123],{"class":83,"line":119},3,[81,121,122],{"class":91},"  -d",[81,124,125],{"class":98}," '{\n",[81,127,129],{"class":83,"line":128},4,[81,130,131],{"class":98},"    \"templateId\": \"7ccf097c-10f2-4efc-bd03-8abe967c4711\",\n",[81,133,135],{"class":83,"line":134},5,[81,136,137],{"class":98},"    \"data\": {\n",[81,139,141],{"class":83,"line":140},6,[81,142,143],{"class":98},"      \"text2_text\": \"HEAR ME SPEAK AT\",\n",[81,145,147],{"class":83,"line":146},7,[81,148,149],{"class":98},"      \"text1_text\": \"THE BLUEPIC EVENT!\"\n",[81,151,153],{"class":83,"line":152},8,[81,154,155],{"class":98},"    },\n",[81,157,159],{"class":83,"line":158},9,[81,160,161],{"class":98},"    \"format\": \"mp4\"\n",[81,163,165],{"class":83,"line":164},10,[81,166,167],{"class":98},"  }'\n",[10,169,171],{"id":170},"the-response-is-a-stream","The response is a stream",[15,173,174,175,179,180,183],{},"A video takes longer than a still to produce (render every frame, then encode), so the endpoint does not make you wait blind. It returns a ",[176,177,178],"strong",{},"Server-Sent Events"," stream: live progress while it works, then a final event with the hosted URL. That is what ",[19,181,182],{},"-N"," is for, so curl does not buffer the events.",[28,185,188],{"className":186,"code":187,"language":33},[31],"data: {\"type\":\"init\",\"sessionId\":\"…\"}\ndata: {\"type\":\"keyframe\",\"frame\":48,\"totalFrames\":192}\ndata: {\"type\":\"encode_video\",\"frame\":140,\"totalFrames\":192}\ndata: {\"type\":\"end\",\"result\":\"https:\u002F\u002F…\u002Fresult.mp4\"}\n",[19,189,187],{"__ignoreMap":36},[15,191,192,193,196,197,200],{},"Read the stream until the ",[19,194,195],{},"end"," event and take its ",[19,198,199],{},"result",". That is your video's URL.",[28,202,206],{"className":203,"code":204,"language":205,"meta":36,"style":36},"language-js shiki shiki-themes github-dark","const res = await fetch(\"https:\u002F\u002Fapi.bluepic.io\u002Fapi\u002Frender\", {\n  method: \"POST\",\n  headers: { Authorization: \"\u003Cyour API key>\", \"Content-Type\": \"application\u002Fjson\" },\n  body: JSON.stringify({\n    templateId: \"7ccf097c-10f2-4efc-bd03-8abe967c4711\",\n    data: { text1_text: \"THE BLUEPIC EVENT!\" },\n    format: \"mp4\",\n  }),\n});\n\nconst reader = res.body.getReader();\nconst decoder = new TextDecoder();\nlet buffer = \"\";\nlet url = \"\";\nfor (;;) {\n  const { value, done } = await reader.read();\n  if (value) buffer += decoder.decode(value, { stream: true });\n  let i;\n  while ((i = buffer.indexOf(\"\\n\\n\")) !== -1) {\n    const line = buffer.slice(0, i).split(\"\\n\").find((l) => l.startsWith(\"data:\"));\n    buffer = buffer.slice(i + 2);\n    if (!line) continue;\n    const evt = JSON.parse(line.slice(5).trim());\n    if (evt.type === \"end\") url = evt.result;\n    \u002F\u002F otherwise evt.frame \u002F evt.totalFrames drives a progress bar\n  }\n  if (done) break;\n}\n\u002F\u002F `url` is your rendered MP4\n","js",[19,207,208,236,247,269,285,295,305,315,320,325,331,350,368,386,400,409,441,468,477,519,587,611,631,667,689,696,702,715,721],{"__ignoreMap":36},[81,209,210,214,217,220,223,226,230,233],{"class":83,"line":84},[81,211,213],{"class":212},"snl16","const",[81,215,216],{"class":91}," res",[81,218,219],{"class":212}," =",[81,221,222],{"class":212}," await",[81,224,225],{"class":87}," fetch",[81,227,229],{"class":228},"s95oV","(",[81,231,232],{"class":98},"\"https:\u002F\u002Fapi.bluepic.io\u002Fapi\u002Frender\"",[81,234,235],{"class":228},", {\n",[81,237,238,241,244],{"class":83,"line":108},[81,239,240],{"class":228},"  method: ",[81,242,243],{"class":98},"\"POST\"",[81,245,246],{"class":228},",\n",[81,248,249,252,255,257,260,263,266],{"class":83,"line":119},[81,250,251],{"class":228},"  headers: { Authorization: ",[81,253,254],{"class":98},"\"\u003Cyour API key>\"",[81,256,68],{"class":228},[81,258,259],{"class":98},"\"Content-Type\"",[81,261,262],{"class":228},": ",[81,264,265],{"class":98},"\"application\u002Fjson\"",[81,267,268],{"class":228}," },\n",[81,270,271,274,277,279,282],{"class":83,"line":128},[81,272,273],{"class":228},"  body: ",[81,275,276],{"class":91},"JSON",[81,278,53],{"class":228},[81,280,281],{"class":87},"stringify",[81,283,284],{"class":228},"({\n",[81,286,287,290,293],{"class":83,"line":134},[81,288,289],{"class":228},"    templateId: ",[81,291,292],{"class":98},"\"7ccf097c-10f2-4efc-bd03-8abe967c4711\"",[81,294,246],{"class":228},[81,296,297,300,303],{"class":83,"line":140},[81,298,299],{"class":228},"    data: { text1_text: ",[81,301,302],{"class":98},"\"THE BLUEPIC EVENT!\"",[81,304,268],{"class":228},[81,306,307,310,313],{"class":83,"line":146},[81,308,309],{"class":228},"    format: ",[81,311,312],{"class":98},"\"mp4\"",[81,314,246],{"class":228},[81,316,317],{"class":83,"line":152},[81,318,319],{"class":228},"  }),\n",[81,321,322],{"class":83,"line":158},[81,323,324],{"class":228},"});\n",[81,326,327],{"class":83,"line":164},[81,328,330],{"emptyLinePlaceholder":329},true,"\n",[81,332,334,336,339,341,344,347],{"class":83,"line":333},11,[81,335,213],{"class":212},[81,337,338],{"class":91}," reader",[81,340,219],{"class":212},[81,342,343],{"class":228}," res.body.",[81,345,346],{"class":87},"getReader",[81,348,349],{"class":228},"();\n",[81,351,353,355,358,360,363,366],{"class":83,"line":352},12,[81,354,213],{"class":212},[81,356,357],{"class":91}," decoder",[81,359,219],{"class":212},[81,361,362],{"class":212}," new",[81,364,365],{"class":87}," TextDecoder",[81,367,349],{"class":228},[81,369,371,374,377,380,383],{"class":83,"line":370},13,[81,372,373],{"class":212},"let",[81,375,376],{"class":228}," buffer ",[81,378,379],{"class":212},"=",[81,381,382],{"class":98}," \"\"",[81,384,385],{"class":228},";\n",[81,387,389,391,394,396,398],{"class":83,"line":388},14,[81,390,373],{"class":212},[81,392,393],{"class":228}," url ",[81,395,379],{"class":212},[81,397,382],{"class":98},[81,399,385],{"class":228},[81,401,403,406],{"class":83,"line":402},15,[81,404,405],{"class":212},"for",[81,407,408],{"class":228}," (;;) {\n",[81,410,412,415,418,421,423,426,429,431,433,436,439],{"class":83,"line":411},16,[81,413,414],{"class":212},"  const",[81,416,417],{"class":228}," { ",[81,419,420],{"class":91},"value",[81,422,68],{"class":228},[81,424,425],{"class":91},"done",[81,427,428],{"class":228}," } ",[81,430,379],{"class":212},[81,432,222],{"class":212},[81,434,435],{"class":228}," reader.",[81,437,438],{"class":87},"read",[81,440,349],{"class":228},[81,442,444,447,450,453,456,459,462,465],{"class":83,"line":443},17,[81,445,446],{"class":212},"  if",[81,448,449],{"class":228}," (value) buffer ",[81,451,452],{"class":212},"+=",[81,454,455],{"class":228}," decoder.",[81,457,458],{"class":87},"decode",[81,460,461],{"class":228},"(value, { stream: ",[81,463,464],{"class":91},"true",[81,466,467],{"class":228}," });\n",[81,469,471,474],{"class":83,"line":470},18,[81,472,473],{"class":212},"  let",[81,475,476],{"class":228}," i;\n",[81,478,480,483,486,488,491,494,496,499,502,504,507,510,513,516],{"class":83,"line":479},19,[81,481,482],{"class":212},"  while",[81,484,485],{"class":228}," ((i ",[81,487,379],{"class":212},[81,489,490],{"class":228}," buffer.",[81,492,493],{"class":87},"indexOf",[81,495,229],{"class":228},[81,497,498],{"class":98},"\"",[81,500,501],{"class":91},"\\n\\n",[81,503,498],{"class":98},[81,505,506],{"class":228},")) ",[81,508,509],{"class":212},"!==",[81,511,512],{"class":212}," -",[81,514,515],{"class":91},"1",[81,517,518],{"class":228},") {\n",[81,520,522,525,528,530,532,535,537,540,543,546,548,550,553,555,557,560,563,567,570,573,576,579,581,584],{"class":83,"line":521},20,[81,523,524],{"class":212},"    const",[81,526,527],{"class":91}," line",[81,529,219],{"class":212},[81,531,490],{"class":228},[81,533,534],{"class":87},"slice",[81,536,229],{"class":228},[81,538,539],{"class":91},"0",[81,541,542],{"class":228},", i).",[81,544,545],{"class":87},"split",[81,547,229],{"class":228},[81,549,498],{"class":98},[81,551,552],{"class":91},"\\n",[81,554,498],{"class":98},[81,556,72],{"class":228},[81,558,559],{"class":87},"find",[81,561,562],{"class":228},"((",[81,564,566],{"class":565},"s9osk","l",[81,568,569],{"class":228},") ",[81,571,572],{"class":212},"=>",[81,574,575],{"class":228}," l.",[81,577,578],{"class":87},"startsWith",[81,580,229],{"class":228},[81,582,583],{"class":98},"\"data:\"",[81,585,586],{"class":228},"));\n",[81,588,590,593,595,597,599,602,605,608],{"class":83,"line":589},21,[81,591,592],{"class":228},"    buffer ",[81,594,379],{"class":212},[81,596,490],{"class":228},[81,598,534],{"class":87},[81,600,601],{"class":228},"(i ",[81,603,604],{"class":212},"+",[81,606,607],{"class":91}," 2",[81,609,610],{"class":228},");\n",[81,612,614,617,620,623,626,629],{"class":83,"line":613},22,[81,615,616],{"class":212},"    if",[81,618,619],{"class":228}," (",[81,621,622],{"class":212},"!",[81,624,625],{"class":228},"line) ",[81,627,628],{"class":212},"continue",[81,630,385],{"class":228},[81,632,634,636,639,641,644,646,649,652,654,656,659,661,664],{"class":83,"line":633},23,[81,635,524],{"class":212},[81,637,638],{"class":91}," evt",[81,640,219],{"class":212},[81,642,643],{"class":91}," JSON",[81,645,53],{"class":228},[81,647,648],{"class":87},"parse",[81,650,651],{"class":228},"(line.",[81,653,534],{"class":87},[81,655,229],{"class":228},[81,657,658],{"class":91},"5",[81,660,72],{"class":228},[81,662,663],{"class":87},"trim",[81,665,666],{"class":228},"());\n",[81,668,670,672,675,678,681,684,686],{"class":83,"line":669},24,[81,671,616],{"class":212},[81,673,674],{"class":228}," (evt.type ",[81,676,677],{"class":212},"===",[81,679,680],{"class":98}," \"end\"",[81,682,683],{"class":228},") url ",[81,685,379],{"class":212},[81,687,688],{"class":228}," evt.result;\n",[81,690,692],{"class":83,"line":691},25,[81,693,695],{"class":694},"sAwPA","    \u002F\u002F otherwise evt.frame \u002F evt.totalFrames drives a progress bar\n",[81,697,699],{"class":83,"line":698},26,[81,700,701],{"class":228},"  }\n",[81,703,705,707,710,713],{"class":83,"line":704},27,[81,706,446],{"class":212},[81,708,709],{"class":228}," (done) ",[81,711,712],{"class":212},"break",[81,714,385],{"class":228},[81,716,718],{"class":83,"line":717},28,[81,719,720],{"class":228},"}\n",[81,722,724],{"class":83,"line":723},29,[81,725,726],{"class":694},"\u002F\u002F `url` is your rendered MP4\n",[10,728,730],{"id":729},"formats-keys-and-credits","Formats, keys, and credits",[732,733,734,766,788],"ul",{},[735,736,737,740,741,744,745,748,749,68,752,68,755,68,758,761,762,53],"li",{},[176,738,739],{},"Formats."," ",[19,742,743],{},"mp4"," and ",[19,746,747],{},"mov"," produce video. The image formats (",[19,750,751],{},"png",[19,753,754],{},"jpeg",[19,756,757],{},"pdf",[19,759,760],{},"svg",") render the same template as a still. See ",[49,763,765],{"href":764},"\u002Fdocs\u002Fone-template-two-outputs","one template, two outputs",[735,767,768,771,772,775,776,779,780,784,785,787],{},[176,769,770],{},"Your own templates."," Pass your API key as a raw ",[19,773,774],{},"Authorization"," header (no ",[19,777,778],{},"Bearer"," prefix). Issue one on the ",[49,781,783],{"href":782},"\u002Fidml\u002Faccount","account page",". Any template with an ",[19,786,42],{}," renders as video.",[735,789,790,793,794,798],{},[176,791,792],{},"Credits."," A still is 1 credit; a video is metered by length and resolution, at 1 credit per second of 2K at 24fps (",[49,795,797],{"href":796},"\u002Fdocs\u002Fvideo-credits","how video credits work","). The public demo templates are free.",[10,800,802],{"id":801},"next","Next",[732,804,805,812],{},[735,806,807,808,53],{},"Personalize and ",[49,809,811],{"href":810},"\u002Fdocs\u002Fbatch-animate-videos","batch many videos from one template",[735,813,814,815,819],{},"Understand ",[49,816,818],{"href":817},"\u002Fdocs\u002Fexpression-engine-over-time","the expression engine"," that drives the motion.",[821,822,823],"style",{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":36,"searchDepth":108,"depth":108,"links":825},[826,827,828,829,830],{"id":12,"depth":108,"text":13},{"id":56,"depth":108,"text":57},{"id":170,"depth":108,"text":171},{"id":729,"depth":108,"text":730},{"id":801,"depth":108,"text":802},"platform","2026-07-26","How to generate an MP4 from a Bluepic template with one API call. POST a templateId and your data, read the streamed render, and get a hosted video URL back. Includes a free public demo you can call with no key.","md","\u002Fdocs-images\u002Fgenerate-video-via-api.svg",{},"\u002Fdocs\u002Fgenerate-video-via-api",{"title":5,"description":833},"docs\u002Fgenerate-video-via-api","nd5mtlC-nnUxDpFennX1iW-m8vDt-mWoFOiP52SpZ78",1785414150375]