editedVersionId); publishing makes a version live in an environment.
A version’s authorable body is exposed as a stable representation — the same
shape you read and write — rather than Usertour’s internal builder model. You
read it with expand, and write it with
PATCH content/{contentId}/versions/{id} (drafts only).
A version’s body
Both also carry version-level start / hide rules (
startRules, hideRules)
and a themeId.
Steps (flow)
content[]): text (markdown), image, button, embed,
question (nps / rating / text / choice), and columns (a row of nested blocks).
Full payload per block type: Blocks.
Rich text is a small markdown subset: paragraphs, # /## headings (h1/h2
only — no h3+), -/* and 1. lists, ``` code fences; inline **bold**,
*italic*, [text](url) (append {target=_blank} right after a link to open
it in a new tab), and a Liquid-style user-attribute placeholder
{{ attribute | default: "fallback" }}. Emphasis applies to placeholders too:
**Hi {{ name }}!** renders the whole greeting — the interpolated value
included — in bold.
Step identifiers: id, cvid, key
id— server-owned write handle. Echo a step’sidto update it; omitidto create a new step. Steps you omit from the list are deleted.cvid— server-owned, version-stable reference. Returned on read; survives version copies. You never set one.key— your handle, write-only (not stored, not returned). Give a step akeyand agoto_stepaction elsewhere in the same write can target it with"step": "<key>"— so you can author a whole flow, including forward and cyclic links, in one request without knowing cvids yet.
goto_step step resolves to a key you sent in this request, or an existing
cvid — both map to the same step, so you don’t have to choose. The stored value
is always the cvid (reads return cvids).
Rules
Conditions and actions are reused everywhere (step triggers, button/question actions, version start/hide rules):- Conditions — a recursive tree (
attributewith ascope,current_url,segment,element,content_state,event,text_input,text_filled,time_window, nestedgroupwithall/any). - Actions —
goto_step,start_content,navigate,dismiss. (run_javascriptis echo-only: builder-authored scripts appear on reads and are preserved by echoing them back unchanged; authoring one is rejected.) - Start rules (
startRules) — when the content auto-starts, plus frequency / priority / wait. Hide rules (hideRules) — when to hide it.
Type-specific data (non-flow)
For the non-flow types, the body lives indata (read with ?expand=data):
checklist items, launcher target/tooltip/behavior, banner placement/content,
tracker event, or the resource-center block tree. Nested rich content reuses the
same blocks, and conditions/actions reuse the same rules.
A newly created non-flow content is seeded with its type’s default data, so you
only send the fields you want to change — the write is a field-level merge. Full
payload per type: Type-specific data.
Writing
PATCH /v2/projects/{projectId}/content/{contentId}/versions/{id} — send only the
fields you want to change:
- Writes target draft versions only.
- It is a field-level merge: styling, layout, and other details the representation doesn’t express are preserved from the existing version.
- Omitted top-level fields are left untouched.
POST content/{contentId}/versions (forks the edited
version), or POST content/{contentId}/versions/{id}/restore (forks a historical
version forward).
Publishing is a separate, explicit step — see the Publish a version endpoint.