Edit a facsimile document template by OPERATIONS against the ids from get_svg_template — never markup. Applies the ops server-side, re-sanitizes, and saves the draft; a refused op returns the problems and saves nothing. Ops (each an object with "op" plus its params): bindField {id, slug, wrap?, lineHeight?, grow?} replaces the run’s text ENTIRELY with the field’s value at render — wrap (points) soft-wraps a long value into that column width; replaceText {id, text, wrap?, lineHeight?, grow?} rewrites literal text ({{slug}} tokens merge inline, and with wrap the whole rewritten paragraph flows as one unit). For a source paragraph pre-wrapped into several line runs: never delete constant wording — rewrite the first run with replaceText carrying the FULL paragraph ({{slug}} where values go) plus wrap, then remove only the other line runs the rewrite absorbed. grow = the height (points) the layout already reserves for the block; rendering beyond it pushes everything below down and stretches the row’s spanning shapes, so long values never overlap the next row; insertText {page, x, y, text, fontSizePt?, fontFamily?, bold?, italic?, fill?, anchor?} adds text (y is the baseline); insertRect {page, x, y, width, height, fill?} adds a white-out (default white) — emit before the insertText that overlays it; setCondition {id, expression?} / setPageCondition {page, expression?} include only when the backtick-quoted expression holds (omit expression to clear); setExpression {id, expression} and setFormat {id, format: FORMAT_TO_CURRENCY|FORMAT_TO_INTEGER} compute and present a value; insertGroup {ids, source?, alias?, strideY?, max?} wraps same-parent elements — with source it repeats per item of that list field, clones offset strideY points down, alias.part readable inside (alias defaults to "item"); setRepeat/clearRepeat configure an existing group; setAttrs {id, x?, y?, fontSizePt?, fill?, bold?, italic?, fontFamily?, anchor?, width?, height?} nudges; remove {id} deletes. Requires document:write.