Generate App
Generate a brand-new app from a plain-language instruction when no existing
app fits (check POST /v1/apps/discover first). A headless LLM planner
assembles a validated workflow graph from the node catalog and auto-publishes
it as a private, immediately-runnable app. The result is a normal app: run it
via POST /v1/apps/{appId}/runs with the returned parameter keys.
Pass baseAppId to EDIT an existing generated app in place: the planner starts
from that app’s current graph and applies the instruction as a targeted change,
keeping the same appId and run history. Requires creator or workspace owner/admin.
POST /v1/apps/discover first — if a suitable app already exists, run that instead.
A headless LLM planner reads your instruction, assembles a validated workflow graph from Lamina’s node catalog, and auto-publishes it as a private app. The result is a normal app: run it immediately with POST /v1/apps/{appId}/runs using the returned parameter keys, and share it with POST /v1/apps/{appId}/visibility.
One-shot generate + run
To build and execute in a single call — e.g. text → workflow → video — passrun: true with an inputs map keyed by the app’s parameter keys (media as URLs, options as labels). The response then includes a run object with the runId; poll GET /v1/runs/{runId} for the result. The app is always created; if inputs are invalid or a required input is missing, run.started is false and run.errors lists the problems so you can fix them and run the app directly.
On-brand generation
Generated apps are brand-aware by default. Before planning, Lamina resolves the workspace’s brand DNA — voice, visual anchors, and guardrails — and the planner seeds the generation nodes so the app produces on-brand output without you hand-writing brand instructions into every run. PassbrandProfileId to target a specific brand in a multi-brand workspace; omit it to use the workspace’s active brand. If no brand is configured, generation proceeds brand-agnostic — brand context is an enhancement, never a requirement.
Writing a good instruction
Describe what the app produces, the inputs the user will supply, and the desired output. The more concrete, the better the plan.- Good: “Product photo app: the user uploads a product image and types a background scene; output one 1:1 image.”
- Good: “Voiceover app: the user pastes a script; output an audio voiceover.”
Response
Returns the app schema —appId, name, parameters[] (the inputs to pass to a run), outputs[], and a runUrl. Feed the parameter keys straight into POST /v1/apps/{appId}/runs.
On the planner path the response may also include editability — a { score, subscores, notes[] } object measuring how tweakable the generated app is (parameter clarity, grouping, node granularity, whether a control steers the output). A low score with its notes tells you exactly what to improve; edit the app in place (pass baseAppId plus ops or a fresh instruction) to refine it.
If the planner cannot produce a valid app, the response is a 422 with error and details[] describing the unresolved problems.
Provider
Theprovider field (claude or openai) overrides the server default for a single request — useful for A/B comparison. Omit it to use the configured default.Authorizations
Workspace API key. Prefix: lma_. Example: lma_abc123...
Body
What the app should create (or, with baseAppId, the change to apply), including the user inputs it needs and the desired outputs.
Edit mode. The appId of a generated app to modify in place (same appId, run history preserved). Omit to build a new app.
Edit mode cheap path — explicit edit operations applied deterministically (no planner LLM call, no credit charge). Requires baseAppId; instruction becomes optional. Items are setNodeData / addNode / removeNode / addEdge / removeEdge / addParameter / removeParameter / setParameter.
Optional preferred app name.
App reach after creation.
private, shared, public Planner LLM provider. Defaults to the server setting (claude).
claude, openai Bake a specific brand profile's voice, visual anchors, and guardrails into the generated app so it produces on-brand output. Omit to use the workspace's active brand.
One-shot: after generating the app, immediately start a run using inputs. The response then includes a run object with the runId — poll GET /v1/runs/{runId}.
Input values keyed by the generated app's parameter key (media as URLs, options as labels). Used only when run is true.
Sandbox mode (or send header X-Lamina-Test: true): validate the request and return a stub app -- no planner LLM call, nothing persisted, no credits charged.
Response
App generated and published