Skip to main content
Every v2 error returns a stable JSON envelope with a machine-readable code — match on code, not on the message (messages may change):
Validation errors (E1017) may additionally carry an issues array with one entry per problem, so you can fix every field in a single round-trip instead of resubmitting once per error:
Each issue has a rule (which validation layer rejected it: schema, reactive_condition, action_not_allowed, step_shape, reference_target, auto_start, media_url), a message, and — when it maps to a request field — a path into the request body. HTTP status follows the usual conventions: 2xx success, 4xx your request, 5xx Usertour.

Codes

Write endpoints validate the request body against the schema and return E1017 with a message pointing at the offending field — for example, a malformed data body for a non-flow content type, or a step referencing an unknown value. Bodies are validated strictly: an unknown top-level key (e.g. isPrimary copied from a read response) is rejected with E1017, never silently dropped. A body that is not valid JSON at all is also E1017 (Invalid JSON body: ...).

Pagination cursors never error

An invalid or expired cursor does not return an error — the request succeeds with an empty final page:
This is deliberate: a cursor the server itself issued can stop matching rows when the underlying data is deleted mid-pagination, and from the server’s side that is indistinguishable from a mistyped cursor. Treating both as “you have reached the end” keeps a client that is iterating next links from crashing halfway through a sync. If you loop on next, an empty page with next: null is your termination signal — don’t probe cursors expecting a 4xx.