Create edits
Edits an existing Hyperframe composite or its layer stack (POST /v1/frame/edits): pass background_b64 and layers (or headline, layout, theme, terminal, instruction, or layer_patches) to redesign text, reposition panels, swap themes (light, glass, dark), or add custom card/HTML layers in ~15ms with zero diffusion cost; or set edit_background=true (with qwen-image-edit or iro) to redo the visual background while keeping all typography and UI layers intact.
POST /v1/frame/edits
| Address | https://api.hanzo.ai/v1/frame/edits |
| Method | POST |
| Operation | aiFrameEdit |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Edits an existing Hyperframe composite or its layer stack (POST /v1/frame/edits): pass background_b64 and layers (or headline, layout, theme, terminal, instruction, or layer_patches) to redesign text, reposition panels, swap themes (light, glass, dark), or add custom card/HTML layers in ~15ms with zero diffusion cost; or set edit_background=true (with qwen-image-edit or iro) to redo the visual background while keeping all typography and UI layers intact.
Request
95 fields, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
accent | body | string | — | Accent is the secondary muted headline line. |
background_b64 | body | string | — | BackgroundB64 is an existing text-free diffusion background (base64 PNG/JPEG) passed to /v1/frame/edits to re-composite text/layers without re-running diffusion. |
copy_box | body | aiFrameBox | — | |
copy_box.height | body | number (double) | — | |
copy_box.left | body | number (double) | — | |
copy_box.top | body | number (double) | — | |
copy_box.width | body | number (double) | — | |
edit_background | body | boolean | — | EditBackground forces /v1/frame/edits to regenerate or edit the diffusion background via Model while preserving all text and UI layers. |
eyebrow | body | string | — | Eyebrow is the mono eyebrow label above the headline (default "HANZO DEV"). |
headline | body | string | — | Headline is the primary @hanzo/font Zen headline copy. |
instruction | body | string | — | Instruction is an optional natural-language edit directive on /v1/frame/edits (e.g. Redesign text to "Zero-config Cloud." with glass theme and split-right layout). |
layer_patches | body | aiFrameLayer[] | — | LayerPatches applies partial updates (by layer id) or appends custom text/card/html layers. |
layer_patches[].accent | body | string | — | |
layer_patches[].box | body | aiFrameBox | — | |
layer_patches[].box.height | body | number (double) | — | |
layer_patches[].box.left | body | number (double) | — | |
layer_patches[].box.top | body | number (double) | — | |
layer_patches[].box.width | body | number (double) | — | |
layer_patches[].color | body | string | — | |
layer_patches[].css | body | string | — | |
layer_patches[].eyebrow | body | string | — | |
layer_patches[].font | body | string | — | |
layer_patches[].font_size | body | number (double) | — | |
layer_patches[].headline | body | string | — | |
layer_patches[].html | body | string | — | |
layer_patches[].id | body | string | — | |
layer_patches[].layout | body | string | — | |
layer_patches[].model | body | string | — | |
layer_patches[].pills | body | string[] | — | |
layer_patches[].prompt | body | string | — | |
layer_patches[].subhead | body | string | — | |
layer_patches[].terminal | body | aiFrameTerminal | — | |
layer_patches[].terminal.badge | body | string | — | |
layer_patches[].terminal.command | body | string | — | |
layer_patches[].terminal.diff | body | string[] | — | |
layer_patches[].terminal.file | body | string | — | |
layer_patches[].terminal.header | body | string | — | |
layer_patches[].terminal.status | body | string | — | |
layer_patches[].terminal.title | body | string | — | |
layer_patches[].theme | body | string | — | |
layer_patches[].type | body | string | — | |
layer_patches[].visible | body | boolean | — | |
layer_patches[].z_index | body | integer (int64) | — | |
layers | body | aiFrameLayer[] | — | Layers is the full composable layer stack from a prior frame response. |
layers[].accent | body | string | — | |
layers[].box | body | aiFrameBox | — | |
layers[].box.height | body | number (double) | — | |
layers[].box.left | body | number (double) | — | |
layers[].box.top | body | number (double) | — | |
layers[].box.width | body | number (double) | — | |
layers[].color | body | string | — | |
layers[].css | body | string | — | |
layers[].eyebrow | body | string | — | |
layers[].font | body | string | — | |
layers[].font_size | body | number (double) | — | |
layers[].headline | body | string | — | |
layers[].html | body | string | — | |
layers[].id | body | string | — | |
layers[].layout | body | string | — | |
layers[].model | body | string | — | |
layers[].pills | body | string[] | — | |
layers[].prompt | body | string | — | |
layers[].subhead | body | string | — | |
layers[].terminal | body | aiFrameTerminal | — | |
layers[].terminal.badge | body | string | — | |
layers[].terminal.command | body | string | — | |
layers[].terminal.diff | body | string[] | — | |
layers[].terminal.file | body | string | — | |
layers[].terminal.header | body | string | — | |
layers[].terminal.status | body | string | — | |
layers[].terminal.title | body | string | — | |
layers[].theme | body | string | — | |
layers[].type | body | string | — | |
layers[].visible | body | boolean | — | |
layers[].z_index | body | integer (int64) | — | |
layout | body | string | — | Layout selects the copy layer placement: "split-left" (default), "split-right", "center", or "bottom-left". |
model | body | string | — | Model is the image SKU for the text-free diffusion background (default "iro"; also accepts "qwen-image", "qwen-image-edit", "z-image-turbo", "flux-3"). |
pills | body | string[] | — | Pills are the mono badge pills rendered beneath the subhead. |
prompt | body | string | — | Prompt describes the visual scene. |
size | body | string | — | Size is the pixel dimension string, e.g. "1344x768" (default) or "1024x1024". |
subhead | body | string | — | Subhead is the supporting paragraph copy below the headline. |
terminal | body | aiFrameTerminal | — | |
terminal.badge | body | string | — | |
terminal.command | body | string | — | |
terminal.diff | body | string[] | — | |
terminal.file | body | string | — | |
terminal.header | body | string | — | |
terminal.status | body | string | — | |
terminal.title | body | string | — | |
terminal_box | body | aiFrameBox | — | |
terminal_box.height | body | number (double) | — | |
terminal_box.left | body | number (double) | — | |
terminal_box.top | body | number (double) | — | |
terminal_box.width | body | number (double) | — | |
theme | body | string | — | Theme selects the copy layer styling: "light" (default), "glass", or "dark". |
Response
| Status | Body | Meaning |
|---|---|---|
200 | aiFrameOut | ok |
default | problem-details | refused |
200 body — 54 fields.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
created | body | integer (int64) | — | |
data | body | aiFrameItem[] | — | |
data[].b64_json | body | string | — | |
data[].background_b64 | body | string | — | |
data[].html | body | string | — | |
data[].layers | body | aiFrameLayer[] | — | |
data[].layers[].accent | body | string | — | |
data[].layers[].box | body | aiFrameBox | — | |
data[].layers[].box.height | body | number (double) | — | |
data[].layers[].box.left | body | number (double) | — | |
data[].layers[].box.top | body | number (double) | — | |
data[].layers[].box.width | body | number (double) | — | |
data[].layers[].color | body | string | — | |
data[].layers[].css | body | string | — | |
data[].layers[].eyebrow | body | string | — | |
data[].layers[].font | body | string | — | |
data[].layers[].font_size | body | number (double) | — | |
data[].layers[].headline | body | string | — | |
data[].layers[].html | body | string | — | |
data[].layers[].id | body | string | — | |
data[].layers[].layout | body | string | — | |
data[].layers[].model | body | string | — | |
data[].layers[].pills | body | string[] | — | |
data[].layers[].prompt | body | string | — | |
data[].layers[].subhead | body | string | — | |
data[].layers[].terminal | body | aiFrameTerminal | — | |
data[].layers[].terminal.badge | body | string | — | |
data[].layers[].terminal.command | body | string | — | |
data[].layers[].terminal.diff | body | string[] | — | |
data[].layers[].terminal.file | body | string | — | |
data[].layers[].terminal.header | body | string | — | |
data[].layers[].terminal.status | body | string | — | |
data[].layers[].terminal.title | body | string | — | |
data[].layers[].theme | body | string | — | |
data[].layers[].type | body | string | — | |
data[].layers[].visible | body | boolean | — | |
data[].layers[].z_index | body | integer (int64) | — | |
data[].layout | body | string | — | |
data[].terminal_box | body | aiFrameBox | — | |
data[].terminal_box.height | body | number (double) | — | |
data[].terminal_box.left | body | number (double) | — | |
data[].terminal_box.top | body | number (double) | — | |
data[].terminal_box.width | body | number (double) | — | |
data[].theme | body | string | — | |
mode | body | string | — | |
model | body | string | — | |
receipt | body | aiReceipt | — | |
receipt.class | body | string | — | Class is the model's class as billed: premium, ours or free (X-Hanzo-Usage-Class). |
receipt.fallback | body | string | — | Fallback is the model that answered in place of the one asked, in limited mode (X-Hanzo-Fallback). |
receipt.paid_by | body | string | — | PaidBy is plan, credits or free (X-Hanzo-Paid-By); absent when the answer named no payer, as a free model's does. |
receipt.reason | body | string | — | Reason is the refusal code that sent the request to the fallback (X-Hanzo-Usage-Reason). |
receipt.routed | body | string | — | Routed is the model auto resolved to (X-Routed-Model). |
receipt.served | body | string | — | Served is the model that answered (X-Hanzo-Served). |
receipt.usage | body | string | — | Usage is where that class stands for the payer: ok, near or limited (X-Hanzo-Usage). |
Failure carries the platform error shape — see Errors.
Examples
hanzo frame editsimport { Configuration, AiApi } from 'hanzoai';
const api = new AiApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.aiFrameEdit({ accent: "<accent>", background_b64: "<background_b64>" });from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import AiApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = AiApi(client).ai_frame_edit(accent="<accent>", background_b64="<background_b64>")cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)
resp, _, err := client.AiAPI.AiFrameEdit(context.Background()).Execute()
if err != nil {
return err
}use hanzo_client::apis::{configuration::Configuration, ai_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = ai_api::ai_frame_edit(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.AiApi;
ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));
var result = new AiApi(client).aiFrameEdit();The method above is the one at the current release of the document. [email protected] (npm) and [email protected] (PyPI) were generated from an earlier release, where this operation carried a different id, so it spells the method differently — regenerating the clients is what makes the two agree. SDKs →
curl -X POST https://api.hanzo.ai/v1/frame/edits \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"accent": "<accent>",
"background_b64": "<background_b64>"
}'Tool ai, op aiFrameEdit — POST the JSON-RPC envelope to https://api.hanzo.ai/v1/mcp.
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "ai",
"arguments": {
"op": "aiFrameEdit",
"input": {
"accent": "<accent>",
"background_b64": "<background_b64>"
}
}
}
}'