[{"data":1,"prerenderedAt":516},["ShallowReactive",2],{"pricing-plans":3,"api-docs-metadata":4,"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,{"success":5,"routes":6,"total":514,"generatedAt":515,"canViewAllApiDocs":82},true,[7,55,67,127,184,205,226,241,257,269,281,298,326,352,371,383,394,405,414,420,438,449,464,476,489],{"path":8,"method":9,"summary":10,"description":11,"tags":12,"group":13,"requestBody":14,"responses":47,"actionName":54},"\u002Fapi\u002Fcode-to-image","POST","Render code snippets as images","Render source code with syntax highlighting to PNG, WebP, or JPEG. No API token required.",[13],"Rendering",{"content":15},{"application\u002Fjson":16},{"schema":17},{"type":18,"required":19,"properties":21},"object",[20],"code",{"code":22,"lang":25,"theme":27,"format":29,"width":35,"height":38,"quality":40,"showLineNumbers":42,"style":45},{"type":23,"description":24},"string","Source code to render",{"type":23,"description":26},"Language for highlighting (e.g. js, ts). Default: js",{"type":23,"description":28},"Shiki theme. Default: github-dark",{"type":23,"enum":30,"description":34},[31,32,33],"png","webp","jpeg","Output format. Default: png (lossless)",{"type":36,"description":37},"number","Optional width",{"type":36,"description":39},"Optional height",{"type":36,"description":41},"Optional quality",{"type":43,"description":44},"boolean","Show 1-based line numbers in a left gutter. Default: false",{"type":18,"description":46},"Optional style options",{"200":48,"400":50,"500":52},{"description":49},"Image (data URL or binary depending on format)",{"description":51},"Missing or invalid code",{"description":53},"Failed to generate code image","codeToImage",{"path":56,"method":9,"summary":57,"description":58,"tags":59,"group":60,"responses":61,"actionName":66},"\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.",[60],"Authentication",{"200":62,"429":64},{"description":63},"Demo token created",{"description":65},"Per-IP demo token quota reached","createDemoToken",{"path":68,"method":69,"summary":70,"description":71,"tags":72,"group":13,"parameters":73,"responses":119,"actionName":126},"\u002Fapi\u002Frender\u002F:pageId","GET","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).",[13],[74,79,89,93,100,104,108,114],{"in":75,"name":76,"required":5,"schema":77,"description":78},"path","pageId",{"type":23},"Page ID to render",{"in":80,"name":81,"required":82,"schema":83,"description":88},"query","format",false,{"type":23,"enum":84},[31,85,32,86,87],"svg","pdf","pptx","Output format. Default: png",{"in":80,"name":90,"required":82,"schema":91,"description":92},"draft",{"type":43},"If true, load from database instead of publish cache. Default: false",{"in":80,"name":94,"required":82,"schema":95,"description":99},"output",{"type":23,"enum":96},[97,98],"json","binary","Response shape: omit or json for metadata + file URL; binary for raw bytes",{"in":80,"name":101,"required":82,"schema":102,"description":103},"pageIds",{"type":23},"Comma-separated page IDs for merged PDF (format=pdf only)",{"in":80,"name":105,"required":82,"schema":106,"description":107},"gt",{"type":23},"GET render secret when Bearer is not used",{"in":80,"name":109,"required":82,"schema":110,"description":113},"scale",{"type":36,"minimum":111,"maximum":112},1,4,"Output resolution multiplier for png\u002Fwebp. Overrides the template's renderScale. Default 2.",{"in":80,"name":115,"required":82,"schema":116,"description":118},"quality",{"type":36,"minimum":111,"maximum":117},100,"WebP encode quality (webp only). Overrides the template's webpQuality. Default 90.",{"200":120,"401":122,"404":124},{"description":121},"Binary image\u002FPDF or application\u002Fjson with file metadata",{"description":123},"Missing or invalid API token",{"description":125},"Page or template not found","renderPage",{"path":128,"method":9,"summary":129,"description":130,"tags":131,"group":13,"requestBody":132,"responses":176,"actionName":183},"\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.",[13],{"content":133},{"application\u002Fjson":134},{"schema":135},{"type":18,"description":136,"properties":137},"For raster formats use pageId. For PDF use pageId (single) or pageIds (merged in order).",{"pageId":138,"pageIds":140,"tweaksPerPage":144,"templateId":147,"draft":149,"format":151,"tweaks":155,"brandTweaks":157,"emojiType":159,"output":161,"binary":166,"renderType":168,"scale":173,"quality":175},{"type":23,"description":139},"Page ID to render (required for png\u002Fsvg\u002Fwebp; optional for pdf when pageIds is set)",{"type":141,"items":142,"description":143},"array",{"type":23},"Multiple pages for merged PDF (format pdf only)",{"type":141,"items":145,"description":146},{"type":18},"Per-page tweaks aligned with pageIds when rendering PDF",{"type":23,"description":148},"Optional; when set, validated against the page's template (parallel fetch)",{"type":43,"description":150},"If true, load page and template from database instead of publish cache. Default: false",{"type":23,"enum":152,"description":154},[31,85,32,86,87,153],"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":18,"description":156},"Variable overrides; keys may use dot paths for nested values. For Variable[] sources, use \"varId.nested.path\" when patching object values.",{"type":18,"description":158},"Brand token overrides by dot path (e.g. logos.icon or brand.logos.icon). Merged into resolved brand tokens before render.",{"type":23,"description":160},"e.g. twemoji, openmoji. Default from template",{"type":23,"enum":162,"description":165},[97,98,163,164],"image","raw","Response shape: omit or json for application\u002Fjson (default); binary, image, or raw for raw body",{"type":43,"description":167},"If true, same as output binary (raw body)",{"type":23,"enum":169,"description":172},[170,171],"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":36,"minimum":111,"maximum":112,"description":174},"Output resolution multiplier for png\u002Fwebp (logical layout unchanged, pixels multiplied). Overrides the template's renderScale. Default 2.",{"type":36,"minimum":111,"maximum":117,"description":118},{"200":177,"400":179,"401":181,"404":182},{"description":178},"Default: application\u002Fjson with render metadata and file.url. With output binary: image\u002Fpng, image\u002Fsvg+xml, image\u002Fwebp, or application\u002Fpdf.",{"description":180},"Invalid body (e.g. missing pageId)",{"description":123},{"description":125},"render",{"path":185,"method":69,"summary":186,"description":187,"tags":188,"parameters":189,"responses":199,"actionName":204},"\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.",[13],[190,193,196],{"in":80,"name":191,"required":82,"description":192},"templateId","Only logs for this template's pages",{"in":80,"name":194,"required":82,"description":195},"page","Page number",{"in":80,"name":197,"required":82,"description":198},"perPage","Items per page (default 50)",{"200":200,"401":202},{"description":201},"JSON { list, count, pagesCount } of render log entries",{"description":203},"Not logged in","listRenderLogs",{"path":206,"method":69,"summary":207,"description":208,"tags":209,"parameters":211,"responses":222,"actionName":225},"\u002Fapi\u002Ftemplates\u002Fpublic","List public templates","List published community\u002Fgallery templates with their cached pages. No authentication required.",[210],"Templates",[212,215,218,220],{"in":80,"name":213,"required":82,"description":214},"search","Search name + description (max 80 chars)",{"in":80,"name":216,"required":82,"description":217},"category","Category filter, or \"featured\" for the curated list",{"in":80,"name":194,"required":82,"description":219},"Page number (default 1)",{"in":80,"name":197,"required":82,"description":221},"Items per page (max 100)",{"200":223},{"description":224},"JSON { list, count, pagesCount } — templates include their published pages","listPublicTemplates",{"path":227,"method":69,"summary":228,"description":229,"tags":230,"parameters":231,"responses":235,"actionName":240},"\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.",[210],[232],{"in":75,"name":233,"required":5,"description":234},"id","Template ID",{"200":236,"404":238},{"description":237},"JSON { doc } — the template including published pages",{"description":239},"Template not found or not public","getPublicTemplateDoc",{"path":242,"method":243,"summary":244,"description":245,"tags":246,"parameters":248,"responses":251,"actionName":256},"\u002Fapi\u002Fv1\u002Fbrands\u002F:id","DELETE","Delete a brand","Soft-delete a brand by ID. Session-authenticated (dashboard login; owner\u002Fadmin\u002Feditor).",[247],"Brands",[249],{"in":75,"name":233,"required":5,"description":250},"Brand ID",{"200":252,"404":254},{"description":253},"JSON { success: true, id }",{"description":255},"Brand not found in your space","deleteBrand",{"path":242,"method":69,"summary":258,"description":259,"tags":260,"parameters":261,"responses":263,"actionName":268},"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).",[247],[262],{"in":75,"name":233,"required":5,"description":250},{"200":264,"404":266},{"description":265},"JSON { doc } — the brand with its token sets",{"description":267},"Not found or not accessible","getBrand",{"path":242,"method":270,"summary":271,"description":272,"tags":273,"parameters":274,"responses":276,"actionName":280},"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).",[247],[275],{"in":75,"name":233,"required":5,"description":250},{"200":277,"404":279},{"description":278},"JSON { doc } — the updated brand",{"description":255},"updateBrand",{"path":282,"method":69,"summary":283,"description":284,"tags":285,"parameters":286,"responses":292,"actionName":297},"\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).",[247],[287,288,289],{"in":80,"name":194,"required":82,"description":219},{"in":80,"name":197,"required":82,"description":198},{"in":80,"name":290,"required":82,"description":291},"public","\"true\" to list public brands without auth",{"200":293,"401":295},{"description":294},"JSON { list, count, pagesCount } of brands",{"description":296},"Not logged in (when public is not set)","listBrands",{"path":282,"method":9,"summary":299,"description":300,"tags":301,"requestBody":302,"responses":321,"actionName":325},"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).",[247],{"content":303},{"application\u002Fjson":304},{"schema":305},{"type":18,"required":306,"properties":308},[307],"name",{"name":309,"draftTokens":311,"liveTokens":313,"tokens":315,"variants":317,"extra":319},{"type":23,"description":310},"Brand name",{"type":18,"description":312},"Token kit being edited (logos, colors, typography, …)",{"type":18,"description":314},"Token kit used by published renders",{"type":18,"description":316},"Resolved token set",{"type":18,"description":318},"Named variations of the kit",{"type":18,"description":320},"Free-form extras",{"200":322,"401":324},{"description":323},"JSON { doc } — the created brand",{"description":203},"createBrand",{"path":327,"method":69,"summary":328,"description":329,"tags":330,"group":331,"parameters":332,"responses":345,"actionName":351},"\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.",[331],"Content",[333,336,339,342],{"in":75,"name":334,"required":5,"description":335},"collection","The collection's API name",{"in":75,"name":337,"required":5,"description":338},"slug","The entry slug",{"in":80,"name":340,"required":82,"description":341},"depth","Resolve reference fields to this depth (default 0)",{"in":80,"name":343,"required":82,"description":344},"variants","Comma-separated variant ids; returns personalization-resolved values",{"200":346,"401":348,"404":349},{"description":347},"JSON { doc } — the published entry",{"description":123},{"description":350},"Collection or entry not found","publicGetContentBySlug",{"path":353,"method":69,"summary":354,"description":355,"tags":356,"group":331,"parameters":357,"responses":364,"actionName":370},"\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=).",[331],[358,359,360,362,363],{"in":75,"name":334,"required":5,"description":335},{"in":80,"name":194,"required":82,"description":219},{"in":80,"name":197,"required":82,"description":361},"Items per page (default 20)",{"in":80,"name":340,"required":82,"description":341},{"in":80,"name":343,"required":82,"description":344},{"200":365,"401":367,"404":368},{"description":366},"JSON { list, count, pagesCount } of published entries",{"description":123},{"description":369},"Collection not found","publicListContent",{"path":372,"method":243,"summary":373,"description":374,"tags":375,"responses":377,"actionName":382},"\u002Fapi\u002Fv1\u002Fshaders\u002F:id","Delete a shader","Permanently remove a shader from the current space.",[376],"Shaders",{"200":378,"404":380},{"description":379},"JSON { deleted: true }",{"description":381},"No such shader","deleteShader",{"path":372,"method":69,"summary":384,"description":385,"tags":386,"responses":387,"actionName":393},"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.",[376],{"200":388,"404":390,"410":391},{"description":389},"JSON { doc }",{"description":381},{"description":392},"Shader is quarantined or revoked","getShader",{"path":372,"method":270,"summary":395,"description":396,"tags":397,"responses":398,"actionName":404},"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.",[376],{"200":399,"404":401,"422":402},{"description":400},"JSON { doc, report }",{"description":381},{"description":403},"Rejected by vetting; the stored shader is unchanged","updateShader",{"path":406,"method":9,"summary":407,"description":408,"tags":409,"responses":410,"actionName":413},"\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.",[376],{"200":411,"404":412},{"description":389},{"description":381},"setShaderStatus",{"path":415,"method":9,"summary":416,"description":417,"tags":418,"actionName":419},"\u002Fapi\u002Fv1\u002Fshaders\u002F:id\u002Ftelemetry","Report a client watchdog trip","Called by a viewer whose frame watchdog disabled this shader. Enough independent trips ",[376],"reportShaderTrip",{"path":421,"method":69,"summary":422,"description":423,"tags":424,"parameters":425,"responses":433,"actionName":437},"\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.",[376],[426,427,428,431],{"in":80,"name":194,"required":82,"description":219},{"in":80,"name":197,"required":82,"description":198},{"in":80,"name":429,"required":82,"description":430},"status","approved | quarantined | revoked",{"in":80,"name":290,"required":82,"description":432},"\"true\" to list public shaders without auth",{"200":434,"401":436},{"description":435},"JSON { list, count, pagesCount }",{"description":296},"listShaders",{"path":421,"method":9,"summary":439,"description":440,"tags":441,"responses":442,"actionName":448},"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.",[376],{"200":443,"401":445,"422":446},{"description":444},"JSON { doc, report } — the stored shader and its vetting report",{"description":203},{"description":447},"Rejected by vetting; data.report explains which stage refused","createShader",{"path":450,"method":243,"summary":451,"description":452,"tags":453,"parameters":455,"responses":458,"actionName":463},"\u002Fapi\u002Fv1\u002Ftokens\u002Fapi-keys\u002F:id","Delete an API key","Revoke an API key immediately. Session-authenticated (dashboard login; owner\u002Fadmin).",[454],"Tokens",[456],{"in":75,"name":233,"required":5,"description":457},"Token ID",{"200":459,"404":461},{"description":460},"JSON { message } confirmation",{"description":462},"Token not found in your space","deleteApiKey",{"path":450,"method":465,"summary":466,"description":467,"tags":468,"parameters":469,"responses":471,"actionName":475},"PATCH","Update an API key","Rename, change expiry, or adjust scopes of an API key. Session-authenticated (dashboard login; owner\u002Fadmin).",[454],[470],{"in":75,"name":233,"required":5,"description":457},{"200":472,"404":474},{"description":473},"JSON { doc } — the updated key",{"description":462},"updateApiKey",{"path":477,"method":69,"summary":478,"description":479,"tags":480,"parameters":481,"responses":484,"actionName":488},"\u002Fapi\u002Fv1\u002Ftokens\u002Fapi-keys\u002Findex","List API keys","List API keys for the current space. Session-authenticated (dashboard login; owner\u002Fadmin).",[454],[482,483],{"in":80,"name":194,"required":82,"description":219},{"in":80,"name":197,"required":82,"description":361},{"200":485,"401":487},{"description":486},"JSON { list, count, pagesCount } of API keys",{"description":203},"listApiKeys",{"path":477,"method":9,"summary":490,"description":491,"tags":492,"requestBody":493,"responses":509,"actionName":513},"Create an API key","Create a space-scoped API key. The plain token is returned once, on creation. Session-authenticated (dashboard login; owner\u002Fadmin).",[454],{"content":494},{"application\u002Fjson":495},{"schema":496},{"type":18,"required":497,"properties":498},[307],{"name":499,"expiresAt":501,"neverExpires":503,"shortToken":505,"scopes":507},{"type":23,"description":500},"Key name (max 200 chars)",{"type":23,"description":502},"ISO datetime expiry",{"type":43,"description":504},"No expiry. Default: false",{"type":43,"description":506},"Shorter ~96-bit token instead of ~256-bit. Default: false",{"type":18,"description":508},"Optional restrictions: { mcpTools?: string[], apiEndpoints?: string[] }. Omit a list to allow all; [] denies all.",{"200":510,"401":512},{"description":511},"JSON { doc } including the plain token (shown only once)",{"description":203},"createApiKey",25,"2026-08-19T19:21:11.342Z",1787167272954]