GlyphfieldDocs
Documentation/System reference

Generation API

Generate template SVGs, background SVGs, element briefs and apply-ready Design Lab documents with POST /api/generate and its versioned JSON contract.

Maintained with source

POST /api/generate accepts a JSON body with Content-Type: application/json. The kind field selects one of four generators: template (the default), background, element-brief and design-sequence. GET /api/generate returns the current contract (schemaVersion 3) with the request schema, value ranges and examples. Read it before building a request. A top-level field that the contract does not define is rejected with unknown_field.

Output

  • template and background return a JSON envelope by default (output: "json"). The SVG is in artifact.content.
  • output: "raw" returns the SVG itself as image/svg+xml.
  • element-brief and design-sequence always return JSON.

Successful responses send Cache-Control: no-store and a Content-Disposition header with the file name.

Design sequence

A design-sequence request builds a document for Design Lab, the Studio's layered composition tool. The document holds a shader sequence: a series of cuts through other materials that ends on the chosen material and holds it. The composition can also include the identity's brand mark, text layers and one converter effect.

{
  "kind": "design-sequence",
  "identity": { "preset": "gt" },
  "ratio": "wide",
  "backgroundColor": "#111216",
  "shader": {
    "materialId": "paper-gem-smoke",
    "shaderSize": 1
  },
  "sequence": {
    "cutCount": 10,
    "finalHoldMs": 5000,
    "pace": "accelerating"
  },
  "effect": {
    "kind": "bayer",
    "opacity": 0.76,
    "foreground": "#F5F5F2",
    "background": "#111216"
  },
  "texts": [{ "value": "Open Source", "weight": 500 }],
  "export": { "width": 1920, "fps": 30, "quality": "best" }
}
FieldValues
shader.materialIdAny ID listed by /api/materials (default paper-gem-smoke). Retired material IDs are rejected
shader.shaderSizeMaterial zoom from 0.1 to 10 (default 1)
shader.opacity, shader.blendMode0–1; normal, multiply, overlay or screen
shader.settingsShared material controls from /api/materials, and effectProps for Shaders.com materials
sequence.cutCount8–12 cuts (default 10)
sequence.finalHoldMs3000–6000 ms (default 5000)
sequence.paceaccelerating (default) or even
effect.kindbayer (default), ascii, halftone or posterize, with opacity, foreground, background and converter settings
textsUp to 32 text layers, each with a value of up to 1000 characters
includeBrandMarktrue by default. An identity without a mark gets a monogram
ratiowide (default), square or opengraph
backgroundColorSix-digit HEX (default #111216)
exportwidth 320–3840, fps 12, 15, 24 or 30, quality fast, balanced or best, durationMs 1200–4000, gifLoop raw or seamless

Image effects are not part of this request. Add them in the browser with design.effects.add after the document is applied.

The response is JSON with these fields:

  • schemaVersion: 1: the version of the response envelope.
  • document: an apply-ready Design Lab compatibility source with version: 3.
  • sequence.timeline and sequence.durationMs: the resolved material IDs and cut boundaries.
  • automation: the browser global and the exact apply and export commands.

document.version is not the active canvas schema. applySource(response.document) validates and migrates the compatibility source. The Design Lab adapter then exposes the normalized result as CanvasDocument schema 2 with Design Lab metadata source version 4. Read the source again after applying it and before making targeted CanvasDocument edits. When the document is applied, Design Lab keeps export.durationMs only if it is 1200, 1600, 2400 or 4000 and uses 1600 otherwise.

Apply and render inside /studio?tool=material:

await window.glyphfield.studio.applySource(response.document);
const artifact = await window.glyphfield.studio.invoke(
  'design.export',
  { format: 'mp4', mode: 'shader-sequence', download: true }
);

Choose png, jpg, gif or mp4. mode: 'shader-sequence' works with GIF and MP4 only. The export action resolves to the same artifact object that the UI produces, rendered with the live shader canvases, composition effects, text, marks, layer order and output settings. download: true also saves the file.

Templates

The template kind renders the Studio's brand templates as standalone SVG: OpenGraph images, terminal cards, slides, blog covers and partnership lockups. It uses the same layouts and renderer as the Studio and embeds the brand's font files and images, so the SVG renders in the brand typeface inside a plain <img> element. A font whose data URL is longer than 560,000 characters is not embedded. Each request renders one page.

When a request leaves out copy, the identity fills it in. Proof figures fill metrics slides, strategy pillars fill agenda slides, and the identity's own proof partner fills lockups. A lockup without a partner shows the placeholder text “Partner”.

{
  "kind": "template",
  "template": "slides",
  "slideLayout": "agenda",
  "texture": "white",
  "title": "One system, every market.",
  "body": "Foundation\nExpression\nApplication\nDelivery",
  "identity": { "preset": "gt" },
  "output": "raw"
}
FieldValues
templateslides (default), blog, partnership, opengraph or terminal
slideLayoutSlides only: title, section, agenda, split, metrics, quote, timeline, statement, comparison, process, chart, team, image or closing
layoutopengraph: split, statement, media, centered, editorial. blog: editorial, feature, statement, centered, ledger. terminal: card, split, focus, caption. partnership: lockup, centered, hero, announcement. Slides also accept layout, and sending both layout and slideLayout is an error
formatopengraph, wide, square, portrait, story, linkedin or lockup. Slides use 16x9, 4x3 or square
texturewhite, dark, grid or noise
languageTerminal only: typescript, tsx, javascript, python, bash, json, html or css
title1–240 characters
body1–1000 characters, or 4000 for terminal. Slides read one list item per line, terminal cards read it as code, and other layouts use it as supporting copy where they have a slot for it
background, foregroundSix-digit HEX colors for the page surface and for every text layer
backgroundImageDataUrl, partnerLogoDataUrlBase64 image data URLs of up to 5,000,000 characters
partnerIdFor partnership: a proof asset ID of the identity, another built-in identity ID, or template-northstar
outputjson (default) or raw

The default size is 1600 × 900 for slides, 1200 × 630 for OpenGraph, terminal and blog, and 1200 × 600 for partnership. format changes it. The file name is <identity slug>-<template>-<width>x<height>.svg.

identity accepts { preset } with optional overrides, { id } with an ID from /api/identities, or a complete identity object from /api/identities (custom identities included). The default preset is starter. An unknown id returns unknown_identity, and an invalid complete identity returns invalid_identity. A field next to preset that is not an override is rejected with unknown_field. See Identities and custom assets.

Background

The background kind generates gradient, grain-gradient, dither, pattern and tactile surface SVGs. For a built-in identity, the colors default to its palette. Tactile backgrounds lists every setting, including the surface* fields and the CC0 surface references.

{
  "kind": "background",
  "identity": { "preset": "gt" },
  "settings": {
    "width": 1200,
    "height": 630,
    "style": "grain-gradient",
    "gradient": "mesh",
    "angle": 32,
    "colorA": "#FFFFFF",
    "colorB": "#181818",
    "colorC": "#737373",
    "focalX": 42,
    "focalY": 38,
    "relief": 24,
    "grain": 18,
    "pattern": "dots",
    "patternOpacity": 14,
    "spacing": 24,
    "logoTone": "black",
    "logoScale": 24,
    "logoOpacity": 100,
    "logoX": 0,
    "logoY": 0
  },
  "output": "raw"
}

settings.width and settings.height must each be an integer from 64 to 4096 (invalid_dimensions). Width × height may not exceed 12,000,000 pixels (pixel_limit). Unknown keys inside settings are ignored, so check their spelling against the contract.

Element brief

The element-brief kind resolves one record from /api/elements against an identity. elementId is required.

{
  "kind": "element-brief",
  "elementId": "email-signature",
  "identity": {
    "preset": "custom",
    "name": "Acme",
    "website": "acme.test",
    "tagline": "Tools for careful teams."
  }
}

The response is { element, generation: { previewFamily, source: '/api/elements' }, identity, schemaVersion: 1 }. element is the catalog record with its ID, name, category, description, dimensions, format, symbol, keywords and preview family. identity holds the resolved colors, description, ID, name, positioning, short name, tagline, typography, voice and website. The HTTP brief has no editor settings and does not render an image. The Brand elements menu item Download element brief adds the element's current settings.

JSON artifact envelope

{
  "schemaVersion": 1,
  "artifact": {
    "content": "<svg ...>...</svg>",
    "filename": "general-translation-slides-1600x900.svg",
    "mimeType": "image/svg+xml",
    "width": 1600,
    "height": 900
  }
}

Check schemaVersion, mimeType and the dimensions before storing the content.

Studio source and generation requests

The Studio source drawer (File → Edit source code) shows the complete JSON state of the active browser tool. Design Lab source is CanvasDocument schema 2 with Design Lab metadata source version 4. Each tool's source has its own shape, and none of them is a valid POST /api/generate body.

design-sequence is the one bridge between the two. It returns a compact document that the browser converts to current Studio source. For other tools, read and apply source or operate the controls through window.glyphfield.studio.

Errors

Errors return { error: { code, field, message }, schemaVersion: 1 }. The codes are invalid_json, unknown_field, invalid_request, unknown_identity, invalid_identity, invalid_dimensions and pixel_limit (400), request_too_large (413, a body over 5,250,000 bytes), unsupported_media_type (415) and generation_failed (500). See API errors and limits.

On this page