[{"data":1,"prerenderedAt":996},["ShallowReactive",2],{"pricing-plans":3,"content-page-\u002Fdocs\u002Fvariables":4,"api-docs-metadata":499,"i-ph:list":3,"i-ph:caret-right":3,"i-ph:copy":3,"i-ph:caret-down":3,"i-ph:twitter-logo":3,"i-ph:youtube-logo":3},null,{"id":5,"title":6,"body":7,"description":489,"extension":490,"meta":491,"navigation":494,"path":495,"seo":496,"stem":497,"__hash__":498},"all\u002Fdocs\u002Fvariables.md","Variables",{"type":8,"value":9,"toc":476},"minimark",[10,14,26,31,93,104,111,115,118,140,146,150,159,167,183,186,196,199,205,212,225,228,232,243,248,287,292,377,381,389,393,400,472],[11,12,6],"h1",{"id":13},"variables",[15,16,17,18,21,22,25],"p",{},"Templates and pages use ",[19,20,13],"strong",{}," to make content dynamic (e.g. title, count, date). When rendering, you can override variable values with ",[19,23,24],{},"tweaks"," so the same template produces different output.",[27,28,30],"h2",{"id":29},"variable-scopes","Variable scopes",[32,33,34,50],"table",{},[35,36,37],"thead",{},[38,39,40,44,47],"tr",{},[41,42,43],"th",{},"Scope",[41,45,46],{},"Where defined",[41,48,49],{},"When used",[51,52,53,67,80],"tbody",{},[38,54,55,61,64],{},[56,57,58],"td",{},[19,59,60],{},"Page variables",[56,62,63],{},"On each page in the editor",[56,65,66],{},"For that page only",[38,68,69,74,77],{},[56,70,71],{},[19,72,73],{},"Template variables",[56,75,76],{},"On the template",[56,78,79],{},"Shared by all pages of the template",[38,81,82,87,90],{},[56,83,84],{},[19,85,86],{},"Global variables",[56,88,89],{},"Space settings (global variables)",[56,91,92],{},"Available to all templates in the space",[15,94,95,96,99,100,103],{},"The same ",[19,97,98],{},"name"," in different scopes can have different values; overrides are applied by name when you pass ",[101,102,24],"code",{},".",[15,105,106],{},[107,108],"img",{"alt":109,"src":110},"The editor's form panel: template variables (brand name, speaker, event details) edited beside the live canvas","\u002Fimages\u002Fdocs\u002Feditor\u002Fvariables-panel.png",[27,112,114],{"id":113},"variable-shape","Variable shape",[15,116,117],{},"Variables can be in two forms:",[119,120,121,131],"ol",{},[122,123,124,127,128],"li",{},[19,125,126],{},"Array form"," (legacy): ",[101,129,130],{},"[{ id, name, schema, value }, ...]",[122,132,133,136,137],{},[19,134,135],{},"Object form"," (JSON Schema style): ",[101,138,139],{},"{ schema: { type: \"object\", properties: { ... } }, values: { key: value } }",[15,141,142,143,145],{},"Stored pages and templates may use either form; the renderer applies ",[19,144,24],{}," against the loaded variable payloads.",[27,147,149],{"id":148},"overriding-with-tweaks","Overriding with tweaks",[15,151,152,154,155,158],{},[19,153,24],{}," is a flat object: keys are variable ",[19,156,157],{},"names"," (or IDs), values are the override values. Tweaks apply to page, template, and global variables (by name).",[160,161,163,164],"h3",{"id":162},"get-apirenderpageid","GET ",[101,165,166],{},"\u002Fapi\u002Frender\u002F:pageId",[168,169,170],"ul",{},[122,171,172,175,176,178,179,182],{},[19,173,174],{},"Query:"," ",[101,177,24],{}," as a JSON string, or multiple ",[101,180,181],{},"tweak:\u003Cname>=\u003Cvalue>"," query params.",[15,184,185],{},"Example (JSON):",[187,188,193],"pre",{"className":189,"code":191,"language":192},[190],"language-text","\u002Fapi\u002Frender\u002FPAGE_ID?format=png&tweaks={\"title\":\"Hello\",\"count\":5}\n","text",[101,194,191],{"__ignoreMap":195},"",[15,197,198],{},"Example (per-param):",[187,200,203],{"className":201,"code":202,"language":192},[190],"\u002Fapi\u002Frender\u002FPAGE_ID?format=png&tweak:title=Hello&tweak:count=5\n",[101,204,202],{"__ignoreMap":195},[160,206,208,209],{"id":207},"post-apirender","POST ",[101,210,211],{},"\u002Fapi\u002Frender",[168,213,214],{},[122,215,216,175,219,221,222,103],{},[19,217,218],{},"Body:",[101,220,24],{}," object, e.g. ",[101,223,224],{},"\"tweaks\": { \"title\": \"Hello\", \"count\": 5 }",[15,226,227],{},"Tweaks are applied after loading the page (and template\u002Fglobal variables), so they override any existing value for that name.",[27,229,231],{"id":230},"example","Example",[15,233,234,235,238,239,242],{},"Template has a template variable ",[101,236,237],{},"title"," (default \"Welcome\") and a page variable ",[101,240,241],{},"count"," (default 10). To render with custom values:",[15,244,245],{},[19,246,247],{},"GET:",[187,249,253],{"className":250,"code":251,"language":252,"meta":195,"style":195},"language-bash shiki shiki-themes github-light github-dark","curl -H \"Authorization: Bearer YOUR_TOKEN\" \\\n  \"https:\u002F\u002Fyour-app.bannx.app\u002Fapi\u002Frender\u002FPAGE_ID?format=png&tweak:title=Summer%20Sale&tweak:count=3\" -o out.png\n","bash",[101,254,255,275],{"__ignoreMap":195},[256,257,260,264,268,272],"span",{"class":258,"line":259},"line",1,[256,261,263],{"class":262},"sScJk","curl",[256,265,267],{"class":266},"sj4cs"," -H",[256,269,271],{"class":270},"sZZnC"," \"Authorization: Bearer YOUR_TOKEN\"",[256,273,274],{"class":266}," \\\n",[256,276,278,281,284],{"class":258,"line":277},2,[256,279,280],{"class":270},"  \"https:\u002F\u002Fyour-app.bannx.app\u002Fapi\u002Frender\u002FPAGE_ID?format=png&tweak:title=Summer%20Sale&tweak:count=3\"",[256,282,283],{"class":266}," -o",[256,285,286],{"class":270}," out.png\n",[15,288,289],{},[19,290,291],{},"POST:",[187,293,297],{"className":294,"code":295,"language":296,"meta":195,"style":195},"language-json shiki shiki-themes github-light github-dark","{\n  \"pageId\": \"PAGE_ID\",\n  \"format\": \"png\",\n  \"tweaks\": {\n    \"title\": \"Summer Sale\",\n    \"count\": 3\n  }\n}\n","json",[101,298,299,305,319,332,341,354,365,371],{"__ignoreMap":195},[256,300,301],{"class":258,"line":259},[256,302,304],{"class":303},"sVt8B","{\n",[256,306,307,310,313,316],{"class":258,"line":277},[256,308,309],{"class":266},"  \"pageId\"",[256,311,312],{"class":303},": ",[256,314,315],{"class":270},"\"PAGE_ID\"",[256,317,318],{"class":303},",\n",[256,320,322,325,327,330],{"class":258,"line":321},3,[256,323,324],{"class":266},"  \"format\"",[256,326,312],{"class":303},[256,328,329],{"class":270},"\"png\"",[256,331,318],{"class":303},[256,333,335,338],{"class":258,"line":334},4,[256,336,337],{"class":266},"  \"tweaks\"",[256,339,340],{"class":303},": {\n",[256,342,344,347,349,352],{"class":258,"line":343},5,[256,345,346],{"class":266},"    \"title\"",[256,348,312],{"class":303},[256,350,351],{"class":270},"\"Summer Sale\"",[256,353,318],{"class":303},[256,355,357,360,362],{"class":258,"line":356},6,[256,358,359],{"class":266},"    \"count\"",[256,361,312],{"class":303},[256,363,364],{"class":266},"3\n",[256,366,368],{"class":258,"line":367},7,[256,369,370],{"class":303},"  }\n",[256,372,374],{"class":258,"line":373},8,[256,375,376],{"class":303},"}\n",[27,378,380],{"id":379},"bindings","Bindings",[15,382,383,385,386,388],{},[19,384,380],{}," link layer properties (e.g. text content, image URL) to variables. They are stored on the page (and sometimes derived from the template). You don't send bindings in the render request; you only send ",[19,387,24],{}," (variable overrides). The renderer resolves bindings using the final variable values (after tweaks).",[27,390,392],{"id":391},"bulk-generation","Bulk generation",[15,394,395,396,399],{},"For many variants (e.g. one image per row of a sheet), use ",[19,397,398],{},"bulk generation",":",[168,401,402,444,457,460],{},[122,403,404,175,407,410,411,414,415,418,419,422,423,426,427,430,431,430,434,430,437,440,441,103],{},[19,405,406],{},"POST",[101,408,409],{},"\u002Fapi\u002Fbulk-generate"," with the ",[19,412,413],{},"page",", a list of ",[19,416,417],{},"contents"," (each content's data is applied like tweaks for that variant), and optionally ",[101,420,421],{},"bulkModVariants"," (named modification sets — one output per content × variant), ",[101,424,425],{},"format"," (",[101,428,429],{},"png"," | ",[101,432,433],{},"webp",[101,435,436],{},"svg",[101,438,439],{},"pdf","), and ",[101,442,443],{},"emojiType",[122,445,446,447,450,451,175,454,103],{},"Returns ",[101,448,449],{},"{ jobId, total }","; follow progress via server-sent events at ",[19,452,453],{},"GET",[101,455,456],{},"\u002Fapi\u002Fbulk-generate\u002F:jobId\u002Fstream",[122,458,459],{},"Session-authenticated (dashboard login; owner\u002Fadmin\u002Feditor) and rate-limited to 6 jobs\u002Fminute per space. The editor's Bulk panel is built on this endpoint.",[122,461,462,463,466,467,103],{},"For ",[19,464,465],{},"video"," variants, see ",[468,469,471],"a",{"href":470},"\u002Fdocs\u002Fvideo","Video → Bulk generation",[473,474,475],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#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 .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 .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":195,"searchDepth":277,"depth":277,"links":477},[478,479,480,486,487,488],{"id":29,"depth":277,"text":30},{"id":113,"depth":277,"text":114},{"id":148,"depth":277,"text":149,"children":481},[482,484],{"id":162,"depth":321,"text":483},"GET \u002Fapi\u002Frender\u002F:pageId",{"id":207,"depth":321,"text":485},"POST \u002Fapi\u002Frender",{"id":230,"depth":277,"text":231},{"id":379,"depth":277,"text":380},{"id":391,"depth":277,"text":392},"Page, template, and global variables and how to override them when rendering.","md",{"layout":492,"updatedAt":493},"docs","2026-07-06",true,"\u002Fdocs\u002Fvariables",{"title":6,"description":489},"docs\u002Fvariables","PR_6WpaQFnXevPQLuZ5vdXq8RLmqX235eFYC26nc7Y8",{"success":494,"routes":500,"total":994,"generatedAt":995,"canViewAllApiDocs":569},[501,545,557,609,666,686,707,722,738,750,762,779,806,832,851,863,874,885,894,900,918,929,944,956,969],{"path":502,"method":406,"summary":503,"description":504,"tags":505,"group":506,"requestBody":507,"responses":537,"actionName":544},"\u002Fapi\u002Fcode-to-image","Render code snippets as images","Render source code with syntax highlighting to PNG, WebP, or JPEG. No API token required.",[506],"Rendering",{"content":508},{"application\u002Fjson":509},{"schema":510},{"type":511,"required":512,"properties":513},"object",[101],{"code":514,"lang":517,"theme":519,"format":521,"width":525,"height":528,"quality":530,"showLineNumbers":532,"style":535},{"type":515,"description":516},"string","Source code to render",{"type":515,"description":518},"Language for highlighting (e.g. js, ts). Default: js",{"type":515,"description":520},"Shiki theme. Default: github-dark",{"type":515,"enum":522,"description":524},[429,433,523],"jpeg","Output format. Default: png (lossless)",{"type":526,"description":527},"number","Optional width",{"type":526,"description":529},"Optional height",{"type":526,"description":531},"Optional quality",{"type":533,"description":534},"boolean","Show 1-based line numbers in a left gutter. Default: false",{"type":511,"description":536},"Optional style options",{"200":538,"400":540,"500":542},{"description":539},"Image (data URL or binary depending on format)",{"description":541},"Missing or invalid code",{"description":543},"Failed to generate code image","codeToImage",{"path":546,"method":406,"summary":547,"description":548,"tags":549,"group":550,"responses":551,"actionName":556},"\u002Fapi\u002Fdemo-token","Create a demo token","Mint a short-lived, IP-throttled demo token (stored only in Redis, ~1h TTL) that can render PUBLIC templates with tweaks — no account or API key required. Each client IP can mint up to 5 tokens per rolling hour. Use the token as `Authorization: Bearer demo_…` or `?demo=demo_…` against GET \u002Fapi\u002Frender\u002F:pageId.",[550],"Authentication",{"200":552,"429":554},{"description":553},"Demo token created",{"description":555},"Per-IP demo token quota reached","createDemoToken",{"path":166,"method":453,"summary":558,"description":559,"tags":560,"group":506,"parameters":561,"responses":601,"actionName":608},"Render a page by ID (GET)","Render by page ID with query parameters. Supports draft (database), publish cache, png\u002Fsvg\u002Fwebp\u002Fpdf, JSON or binary responses, tweaks, and brandTweaks — aligned with POST \u002Fapi\u002Frender. Auth depends on template requireGetRenderToken (Bearer or gt query).",[506],[562,567,574,578,584,588,592,596],{"in":563,"name":564,"required":494,"schema":565,"description":566},"path","pageId",{"type":515},"Page ID to render",{"in":568,"name":425,"required":569,"schema":570,"description":573},"query",false,{"type":515,"enum":571},[429,436,433,439,572],"pptx","Output format. Default: png",{"in":568,"name":575,"required":569,"schema":576,"description":577},"draft",{"type":533},"If true, load from database instead of publish cache. Default: false",{"in":568,"name":579,"required":569,"schema":580,"description":583},"output",{"type":515,"enum":581},[296,582],"binary","Response shape: omit or json for metadata + file URL; binary for raw bytes",{"in":568,"name":585,"required":569,"schema":586,"description":587},"pageIds",{"type":515},"Comma-separated page IDs for merged PDF (format=pdf only)",{"in":568,"name":589,"required":569,"schema":590,"description":591},"gt",{"type":515},"GET render secret when Bearer is not used",{"in":568,"name":593,"required":569,"schema":594,"description":595},"scale",{"type":526,"minimum":259,"maximum":334},"Output resolution multiplier for png\u002Fwebp. Overrides the template's renderScale. Default 2.",{"in":568,"name":597,"required":569,"schema":598,"description":600},"quality",{"type":526,"minimum":259,"maximum":599},100,"WebP encode quality (webp only). Overrides the template's webpQuality. Default 90.",{"200":602,"401":604,"404":606},{"description":603},"Binary image\u002FPDF or application\u002Fjson with file metadata",{"description":605},"Missing or invalid API token",{"description":607},"Page or template not found","renderPage",{"path":610,"method":406,"summary":611,"description":612,"tags":613,"group":506,"requestBody":614,"responses":658,"actionName":665},"\u002Fapi\u002Frender\u002Findex","Render by page ID","Render a page by ID from the publish cache, or from the database when draft: true. Requires API token. Does not accept full inline page payloads. Optional body field renderType (satori, takumi, html) overrides the template's rendererType. Use format pdf for the HTML + Chrome PDF pipeline (always uses the HTML renderer). For multi-page PDFs, send pageIds and optional tweaksPerPage (same length). Default response is application\u002Fjson with timings and a URL to the uploaded render; set output to binary (or binary: true) to return raw bytes.",[506],{"content":615},{"application\u002Fjson":616},{"schema":617},{"type":511,"description":618,"properties":619},"For raster formats use pageId. For PDF use pageId (single) or pageIds (merged in order).",{"pageId":620,"pageIds":622,"tweaksPerPage":626,"templateId":629,"draft":631,"format":633,"tweaks":637,"brandTweaks":639,"emojiType":641,"output":643,"binary":648,"renderType":650,"scale":655,"quality":657},{"type":515,"description":621},"Page ID to render (required for png\u002Fsvg\u002Fwebp; optional for pdf when pageIds is set)",{"type":623,"items":624,"description":625},"array",{"type":515},"Multiple pages for merged PDF (format pdf only)",{"type":623,"items":627,"description":628},{"type":511},"Per-page tweaks aligned with pageIds when rendering PDF",{"type":515,"description":630},"Optional; when set, validated against the page's template (parallel fetch)",{"type":533,"description":632},"If true, load page and template from database instead of publish cache. Default: false",{"type":515,"enum":634,"description":636},[429,436,433,439,572,635],"html5","Output format. Default: png. pdf and pptx use HTML + Chrome; pptx builds an editable slide per page. html5 returns a self-contained HTML5 display-ad ZIP (Google Ads) for a single page.",{"type":511,"description":638},"Variable overrides; keys may use dot paths for nested values. For Variable[] sources, use \"varId.nested.path\" when patching object values.",{"type":511,"description":640},"Brand token overrides by dot path (e.g. logos.icon or brand.logos.icon). Merged into resolved brand tokens before render.",{"type":515,"description":642},"e.g. twemoji, openmoji. Default from template",{"type":515,"enum":644,"description":647},[296,582,645,646],"image","raw","Response shape: omit or json for application\u002Fjson (default); binary, image, or raw for raw body",{"type":533,"description":649},"If true, same as output binary (raw body)",{"type":515,"enum":651,"description":654},[652,653],"takumi","html","Override rendering engine (takumi or html). Ignored when format is pdf (HTML pipeline). Legacy value 'satori' is accepted and treated as 'takumi'.",{"type":526,"minimum":259,"maximum":334,"description":656},"Output resolution multiplier for png\u002Fwebp (logical layout unchanged, pixels multiplied). Overrides the template's renderScale. Default 2.",{"type":526,"minimum":259,"maximum":599,"description":600},{"200":659,"400":661,"401":663,"404":664},{"description":660},"Default: application\u002Fjson with render metadata and file.url. With output binary: image\u002Fpng, image\u002Fsvg+xml, image\u002Fwebp, or application\u002Fpdf.",{"description":662},"Invalid body (e.g. missing pageId)",{"description":605},{"description":607},"render",{"path":667,"method":453,"summary":668,"description":669,"tags":670,"parameters":671,"responses":680,"actionName":685},"\u002Fapi\u002Frenders\u002Flogs","List render logs","Render request logs for the current space, optionally narrowed to one template. Session-authenticated (dashboard login) — not callable with an API key.",[506],[672,675,677],{"in":568,"name":673,"required":569,"description":674},"templateId","Only logs for this template's pages",{"in":568,"name":413,"required":569,"description":676},"Page number",{"in":568,"name":678,"required":569,"description":679},"perPage","Items per page (default 50)",{"200":681,"401":683},{"description":682},"JSON { list, count, pagesCount } of render log entries",{"description":684},"Not logged in","listRenderLogs",{"path":687,"method":453,"summary":688,"description":689,"tags":690,"parameters":692,"responses":703,"actionName":706},"\u002Fapi\u002Ftemplates\u002Fpublic","List public templates","List published community\u002Fgallery templates with their cached pages. No authentication required.",[691],"Templates",[693,696,699,701],{"in":568,"name":694,"required":569,"description":695},"search","Search name + description (max 80 chars)",{"in":568,"name":697,"required":569,"description":698},"category","Category filter, or \"featured\" for the curated list",{"in":568,"name":413,"required":569,"description":700},"Page number (default 1)",{"in":568,"name":678,"required":569,"description":702},"Items per page (max 100)",{"200":704},{"description":705},"JSON { list, count, pagesCount } — templates include their published pages","listPublicTemplates",{"path":708,"method":453,"summary":709,"description":710,"tags":711,"parameters":712,"responses":716,"actionName":721},"\u002Fapi\u002Ftemplates\u002Fpublic\u002F:id","Get a public template","Fetch one published template (with its pages) by ID. Only templates with publicOn are returned; private IDs 404. No authentication required.",[691],[713],{"in":563,"name":714,"required":494,"description":715},"id","Template ID",{"200":717,"404":719},{"description":718},"JSON { doc } — the template including published pages",{"description":720},"Template not found or not public","getPublicTemplateDoc",{"path":723,"method":724,"summary":725,"description":726,"tags":727,"parameters":729,"responses":732,"actionName":737},"\u002Fapi\u002Fv1\u002Fbrands\u002F:id","DELETE","Delete a brand","Soft-delete a brand by ID. Session-authenticated (dashboard login; owner\u002Fadmin\u002Feditor).",[728],"Brands",[730],{"in":563,"name":714,"required":494,"description":731},"Brand ID",{"200":733,"404":735},{"description":734},"JSON { success: true, id }",{"description":736},"Brand not found in your space","deleteBrand",{"path":723,"method":453,"summary":739,"description":740,"tags":741,"parameters":742,"responses":744,"actionName":749},"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).",[728],[743],{"in":563,"name":714,"required":494,"description":731},{"200":745,"404":747},{"description":746},"JSON { doc } — the brand with its token sets",{"description":748},"Not found or not accessible","getBrand",{"path":723,"method":751,"summary":752,"description":753,"tags":754,"parameters":755,"responses":757,"actionName":761},"PUT","Update a brand","Update a brand by ID (same fields as create, all optional). Session-authenticated (dashboard login; owner\u002Fadmin\u002Feditor). For API-key access use the MCP server (update_brand).",[728],[756],{"in":563,"name":714,"required":494,"description":731},{"200":758,"404":760},{"description":759},"JSON { doc } — the updated brand",{"description":736},"updateBrand",{"path":763,"method":453,"summary":764,"description":765,"tags":766,"parameters":767,"responses":773,"actionName":778},"\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).",[728],[768,769,770],{"in":568,"name":413,"required":569,"description":700},{"in":568,"name":678,"required":569,"description":679},{"in":568,"name":771,"required":569,"description":772},"public","\"true\" to list public brands without auth",{"200":774,"401":776},{"description":775},"JSON { list, count, pagesCount } of brands",{"description":777},"Not logged in (when public is not set)","listBrands",{"path":763,"method":406,"summary":780,"description":781,"tags":782,"requestBody":783,"responses":801,"actionName":805},"Create a brand","Create a brand in the current space. Session-authenticated (dashboard login; owner\u002Fadmin\u002Feditor). External image URLs inside tokens are re-uploaded to your space. For API-key access use the MCP server (create_brand).",[728],{"content":784},{"application\u002Fjson":785},{"schema":786},{"type":511,"required":787,"properties":788},[98],{"name":789,"draftTokens":791,"liveTokens":793,"tokens":795,"variants":797,"extra":799},{"type":515,"description":790},"Brand name",{"type":511,"description":792},"Token kit being edited (logos, colors, typography, …)",{"type":511,"description":794},"Token kit used by published renders",{"type":511,"description":796},"Resolved token set",{"type":511,"description":798},"Named variations of the kit",{"type":511,"description":800},"Free-form extras",{"200":802,"401":804},{"description":803},"JSON { doc } — the created brand",{"description":684},"createBrand",{"path":807,"method":453,"summary":808,"description":809,"tags":810,"group":811,"parameters":812,"responses":825,"actionName":831},"\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.",[811],"Content",[813,816,819,822],{"in":563,"name":814,"required":494,"description":815},"collection","The collection's API name",{"in":563,"name":817,"required":494,"description":818},"slug","The entry slug",{"in":568,"name":820,"required":569,"description":821},"depth","Resolve reference fields to this depth (default 0)",{"in":568,"name":823,"required":569,"description":824},"variants","Comma-separated variant ids; returns personalization-resolved values",{"200":826,"401":828,"404":829},{"description":827},"JSON { doc } — the published entry",{"description":605},{"description":830},"Collection or entry not found","publicGetContentBySlug",{"path":833,"method":453,"summary":834,"description":835,"tags":836,"group":811,"parameters":837,"responses":844,"actionName":850},"\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=).",[811],[838,839,840,842,843],{"in":563,"name":814,"required":494,"description":815},{"in":568,"name":413,"required":569,"description":700},{"in":568,"name":678,"required":569,"description":841},"Items per page (default 20)",{"in":568,"name":820,"required":569,"description":821},{"in":568,"name":823,"required":569,"description":824},{"200":845,"401":847,"404":848},{"description":846},"JSON { list, count, pagesCount } of published entries",{"description":605},{"description":849},"Collection not found","publicListContent",{"path":852,"method":724,"summary":853,"description":854,"tags":855,"responses":857,"actionName":862},"\u002Fapi\u002Fv1\u002Fshaders\u002F:id","Delete a shader","Permanently remove a shader from the current space.",[856],"Shaders",{"200":858,"404":860},{"description":859},"JSON { deleted: true }",{"description":861},"No such shader","deleteShader",{"path":852,"method":453,"summary":864,"description":865,"tags":866,"responses":867,"actionName":873},"Get a shader","Fetch one shader including its vetted `program` — the only source a client should compile. Status is enforced here on every request, which is what makes revoking a working kill switch: a quarantined or revoked shader returns 410 and stops loading everywhere immediately.",[856],{"200":868,"404":870,"410":871},{"description":869},"JSON { doc }",{"description":861},{"description":872},"Shader is quarantined or revoked","getShader",{"path":852,"method":751,"summary":875,"description":876,"tags":877,"responses":878,"actionName":884},"Update a shader","Editing source or the manifest re-runs the full vetting pipeline and produces a new content hash — an existing approval is never inherited by code that was not vetted. A rejected edit returns 422 and leaves the stored shader untouched.",[856],{"200":879,"404":881,"422":882},{"description":880},"JSON { doc, report }",{"description":861},{"description":883},"Rejected by vetting; the stored shader is unchanged","updateShader",{"path":886,"method":406,"summary":887,"description":888,"tags":889,"responses":890,"actionName":893},"\u002Fapi\u002Fv1\u002Fshaders\u002F:id\u002Fstatus","Set a shader status (kill switch)","Revoke, quarantine, or restore a shader. Because GET enforces status on every fetch, revoking stops the shader loading everywhere at once — there is no client deny-list to push and no cache to wait out. Restoring also clears the accumulated watchdog trips.",[856],{"200":891,"404":892},{"description":869},{"description":861},"setShaderStatus",{"path":895,"method":406,"summary":896,"description":897,"tags":898,"actionName":899},"\u002Fapi\u002Fv1\u002Fshaders\u002F:id\u002Ftelemetry","Report a client watchdog trip","Called by a viewer whose frame watchdog disabled this shader. Enough independent trips ",[856],"reportShaderTrip",{"path":901,"method":453,"summary":902,"description":903,"tags":904,"parameters":905,"responses":913,"actionName":917},"\u002Fapi\u002Fv1\u002Fshaders\u002Findex","List shaders","List the current space's shaders. Pass ?public=true to list published shaders anonymously. Program source is omitted from the listing — fetch a single shader to obtain it.",[856],[906,907,908,911],{"in":568,"name":413,"required":569,"description":700},{"in":568,"name":678,"required":569,"description":679},{"in":568,"name":909,"required":569,"description":910},"status","approved | quarantined | revoked",{"in":568,"name":771,"required":569,"description":912},"\"true\" to list public shaders without auth",{"200":914,"401":916},{"description":915},"JSON { list, count, pagesCount }",{"description":777},"listShaders",{"path":901,"method":406,"summary":919,"description":920,"tags":921,"responses":922,"actionName":928},"Create a shader","Submit a GLSL fragment body plus a typed input manifest. The shader is vetted before anything is stored: byte caps, a static policy scan, loop normalisation to constant bounds, a cost model, then a real compile and fuzz render inside a sandboxed child process. A rejected submission returns 422 with the stage-by-stage report and is not saved.",[856],{"200":923,"401":925,"422":926},{"description":924},"JSON { doc, report } — the stored shader and its vetting report",{"description":684},{"description":927},"Rejected by vetting; data.report explains which stage refused","createShader",{"path":930,"method":724,"summary":931,"description":932,"tags":933,"parameters":935,"responses":938,"actionName":943},"\u002Fapi\u002Fv1\u002Ftokens\u002Fapi-keys\u002F:id","Delete an API key","Revoke an API key immediately. Session-authenticated (dashboard login; owner\u002Fadmin).",[934],"Tokens",[936],{"in":563,"name":714,"required":494,"description":937},"Token ID",{"200":939,"404":941},{"description":940},"JSON { message } confirmation",{"description":942},"Token not found in your space","deleteApiKey",{"path":930,"method":945,"summary":946,"description":947,"tags":948,"parameters":949,"responses":951,"actionName":955},"PATCH","Update an API key","Rename, change expiry, or adjust scopes of an API key. Session-authenticated (dashboard login; owner\u002Fadmin).",[934],[950],{"in":563,"name":714,"required":494,"description":937},{"200":952,"404":954},{"description":953},"JSON { doc } — the updated key",{"description":942},"updateApiKey",{"path":957,"method":453,"summary":958,"description":959,"tags":960,"parameters":961,"responses":964,"actionName":968},"\u002Fapi\u002Fv1\u002Ftokens\u002Fapi-keys\u002Findex","List API keys","List API keys for the current space. Session-authenticated (dashboard login; owner\u002Fadmin).",[934],[962,963],{"in":568,"name":413,"required":569,"description":700},{"in":568,"name":678,"required":569,"description":841},{"200":965,"401":967},{"description":966},"JSON { list, count, pagesCount } of API keys",{"description":684},"listApiKeys",{"path":957,"method":406,"summary":970,"description":971,"tags":972,"requestBody":973,"responses":989,"actionName":993},"Create an API key","Create a space-scoped API key. The plain token is returned once, on creation. Session-authenticated (dashboard login; owner\u002Fadmin).",[934],{"content":974},{"application\u002Fjson":975},{"schema":976},{"type":511,"required":977,"properties":978},[98],{"name":979,"expiresAt":981,"neverExpires":983,"shortToken":985,"scopes":987},{"type":515,"description":980},"Key name (max 200 chars)",{"type":515,"description":982},"ISO datetime expiry",{"type":533,"description":984},"No expiry. Default: false",{"type":533,"description":986},"Shorter ~96-bit token instead of ~256-bit. Default: false",{"type":511,"description":988},"Optional restrictions: { mcpTools?: string[], apiEndpoints?: string[] }. Omit a list to allow all; [] denies all.",{"200":990,"401":992},{"description":991},"JSON { doc } including the plain token (shown only once)",{"description":684},"createApiKey",25,"2026-08-19T19:21:11.342Z",1787167272953]