kimo_apply_ops cookbook
On this page6 sections
{ "docId": "d_…", "baseRevision": {"epoch": "…", "seq": 12}, "label": "Pricing card","ops": [ … up to 500 … ] }
One transaction (any failure: nothing changes), one undo step. Max 40 inserts per call, 150
streamed (BATCH_TOO_LARGE), a ceiling; copy is free. A failure returns retryId:
{docId, retryId, edits:[{find, replace, all?}]} patches the call (compact JSON), reruns it.
References. Any id, parent, instance, component, frame or node field takes a node id
or @key of a node created earlier in the call. After {"op":"copy","key":"v2",…},
@v2/<original id> is the copy of that node, so one call can copy a page and insert into the
copy's sections. created[] also lists the copies of the copied root's first two levels as
v2/<original id> → new id, for later calls. parent: "root" = top level. index = position
among siblings (0 first; omit to append).
Clearing fields. {"op":"update",, or null in set
("set":{"effects":null}). Never put unset inside set or a node body.
Features (layout/wrap, text/runs, …) are declared for you by the edit that needs them.
Build a subtree
[{"op":"insert","key":"card","parent":"root","node":{"type":"frame","name":"Card","x":0,"y":0,"w":320,"fill":"#FFFFFF","radius":12,"layout":{"dir":"column","gap":8,"pad":20}}},{"op":"insert","key":"title","parent":"@card","node":{"type":"text","content":"Pro","style":{"size":20,"weight":600}}},{"op":"insert","parent":"@card","node":{"type":"text","content":"$49/mo"}}]
Children are separate inserts, never in a body.
Edit
| Op | Shape | Notes |
|---|---|---|
update | {id, set?:{field:value}, unset?:[field]} | Shallow: set.layout replaces the whole layout object |
replace | {id, node} | New body, same id and position. Destructive |
move | {id, parent, index?, at?} | Reparent or reorder |
delete | {id} | Removes the subtree. Destructive |
copy | {id, parent, key?, index?, set?} | Deep copy with fresh ids, optional root fields |
update{id, set?:{field:value}, unset?:[field]}set.layout replaces the whole layout objectreplace{id, node}move{id, parent, index?, at?}delete{id}copy{id, parent, key?, index?, set?}{"op":"update","id":"@title","set":{"content":"Team","style":{"size":24,"weight":700}}}{"op":"update","id":"Hq3Lm9aZ1x","unset":["effects"]}{"op":"copy","id":"@card","key":"card2","parent":"root","set":{"x":360}}
Components and instances (details: components)
{"op":"make_component","ids":["@card"],"name":"PriceCard"}{"op":"instantiate","of":"@card","key":"c1","parent":"@row"}{"op":"set_override","instance":"@c1","path":"Title00001","kind":"set","set":{"content":"Team"}}{"op":"set_args","instance":"@c1","args":[{"name":"label","value":"Buy"}]}
Also swap_instance, reset_override, detach, declare_prop, remove_prop, set_slot.
Variables and themes (details: tokens)
{"op":"theme_axis","action":"create","axis":"mode","values":["light","dark"]}{"op":"create_variable","name":"surface","variable":{"type":"color","value":[{"when":{"mode":"light"},"value":"#FFFFFF"},{"when":{"mode":"dark"},"value":"#111111"}]}}{"op":"update","id":"@card","set":{"fill":{"$ref":"surface"}}}{"op":"set_theme_pin","node":"@card","axis":"mode","value":"dark"}
Also update_variable, rename_variable, delete_variable {detach?}, set_variables, set_theme_axes.
Pages
{"op":"page","action":"add","name":"Checkout","key":"checkout"}{"op":"insert","parent":"root","node":{"type":"frame","name":"Cart","w":390,"h":844,"page":"<page id>"}}{"op":"page","action":"move","id":"<page id>","index":0}
Also rename {id, name}.
created[] maps the add's key to the page id. A top-level insert without page lands on the
first page. delete removes a page and its top-level nodes (never the last page).
Habits that work
- Pass
baseRevisionfrom your last result (REVISION_CONFLICTinstead of overwriting). - New top-level frame: x/y from the outline's boxes or
kimo_find_space. - Mark work in progress with
placeholder: trueon the frame;unsetit at the end.