Skip to main content
edit_document applies a list of edits in one call, each recorded as a Word tracked change. Nothing is overwritten silently: every applied edit stays visible as a redline until a human accepts or rejects it.

Parameters

array
required
The edits to apply. Maximum 20 per call.
The document and the tracked-change author travel in _meta, under com.vespper/document and com.vespper/author. See Attaching the document.

Returns

boolean
true whenever the document changed — including a batch where only some edits landed.
integer
How many edits actually applied.
string
The patched .docx, base64-encoded. Thread it forward as the next call’s document, or decode it to save the file.
integer
Size of the patched document.
array
Present only on a partial batch. Each entry is { index, reason }, where index is 1-based over the edits you sent.
string
Agent-facing summary of what landed and what didn’t.
number
Metered cost of this call.

Edits succeed or fail individually

A batch can apply in part. The edits counted in count are already saved in the returned document, so never resend the whole batch after a partial result — that re-applies them and duplicates the text. Resend only the indexes named in failed_edits, fixed, or tell the user what could not be changed.
When nothing applies you get an error instead and the document is untouched; then fix the listed edits and resend the whole batch.

Example

Anchoring rules

Make old unique

If a block is identical to another in the document — two blank Print Name ____ lines, repeated checkbox rows, a lone [MAILING ADDRESS] — it matches several spots and the edit fails with multiple matches. Disambiguate by extending old to include a neighbouring block that is unique: a run of consecutive blocks copied verbatim in order, with every change in new. Non-adjacent blocks cannot share one old; give them separate edits.

Lazy classes

Write class="..." — literally three dots — for every class attribute in both old and new. It means “keep this class”, and saves you pasting real class lists. Spell a class out only when changing the class is the edit, to break a multiple matches tie, or on a brand-new inserted block: it has no counterpart in old to inherit from, so it must spell its class out.
class="..." is all-or-nothing. It stands for the entire class value, so it must be the whole attribute with nothing else inside or after the quotes. class="..." bg-[#F6F4EF]" is invalid and fails to locate — to keep a distinguishing class, spell the whole class out for that element instead.

What you cannot anchor on

Batching

Send all of a request’s edits in one call when it makes sense — they reconcile in parallel, so a 10-edit call takes about as long as one edit, while 10 separate calls are roughly 10× slower. Every edit must target a different block. Two edits touching the same block, or the same consecutive span, overlap and both are dropped — combine those changes into a single old / new pair. Keep each edit small. One edit carrying a huge new — beyond roughly 10,000 characters — risks truncation or a timeout and fails the whole edit. When writing a lot of new content, break it into several edits of a few blocks each, anchored on different neighbouring blocks.

Tracked changes stay visible

Each applied edit is a redline that stays until it is accepted: inserted text shows underlined, deleted text shows struck through rather than removed. Re-reading the document after a successful edit still shows both — that is correct, not a failure. Don’t repeat the edit, and don’t re-read just to verify it.

Resolving an existing tracked change

read_document renders pending changes as <ins> and <del> elements carrying a data-author. To act on one, copy its whole block verbatim into old, keeping the wrappers and their data-author, then write new as the block’s final state. Two rules constrain this. First, resolve only the change you were asked about: a block often carries several pending changes, and every one you were not asked about must appear in new exactly as it stands in old. Pending is the default state, so clearing a change nobody mentioned is a wrong edit even when the resulting words look right. Second, the only <ins> and <del> allowed in new are the ones already in old — never write one of your own, since your redline is derived and stamped with the author from _meta. Rejecting Jane’s insertion:
Accepting Jane’s insertion, where Sam’s was not mentioned and so stays exactly as it was:
Modifying Jane’s insertion to drop “brown”. Her text is edited in place, and the deletion is recorded inside her insertion automatically: