Edit a draft
patch_versionChange a DRAFT version's stored model with an RFC 6902 JSON Patch, merged on the server. Use it for targeted edits; any change to a clipped collection (__context.patchable: false) goes through download and upload instead (see next_steps in get_project).
BEFORE CALLING
The version must be a draft: use get_project's latest_draft. If it is null, ask the user to click New Version on the project page (it copies the live model), then call get_project again.
Call get_project with the draft's version_reference and build every path from that response. Pass its updated_at as base_updated_at.
Tell the user what you will change (old → new) and get their go-ahead.
PATHS (JSON Pointer)
Name steps, tests and other id'd array elements by id (else key) instead of index: /steps//... and /tests//... Ids survive other steps being inserted or removed in the same patch.
Model layout: /meta/..., /input/format//... (format is an object keyed by input key), /steps//..., /output/format//..., /tests//...
Collection rows by index. Compressed collection ([[col1, col2, ...], [v1, v2, ...], ...]): index 0 is the header row, so the first data row is /collection/1, and a cell is /collection//. Uncompressed collection (array of row objects): the first row is /collection/0, and a cell is /collection//. Check __context.shape and __context.columns.
Append with "-" (/steps/-, /steps//collection/-). Insert at a numeric index; step order is execution order, so a new step goes after the steps whose outputs it reads.
Escape "~" as ~0 and "/" as ~1 inside a segment.
EXAMPLES
Change a rate cell: {"op":"replace","path":"/steps/region_rates/collection/1/1","value":4.5}
Guard then change: [{"op":"test","path":"/steps/base_premium/formula","value":""},{"op":"replace","path":"/steps/base_premium/formula","value":""}]
Add a table row: {"op":"add","path":"/steps/type_factors/collection/-","value":["gravel",1.1]}
Change an input default: {"op":"replace","path":"/input/format/bike_value/def","value":2000}
Insert a step as the 5th: {"op":"add","path":"/steps/4","value":{ ...full step object... }}
Update a test's expected price: {"op":"replace","path":"/tests/t01/output/result","value":46.1}
Add a test: {"op":"add","path":"/tests/-","value":{"id":"young_rider","name":"Young rider","key":"young_rider","input":{ ...every input key... },"output":{"result":52.5,"valid":true}}}. Expectations go in output { result, valid }, even if older tests on the model keep them under result.
RULES
Smallest change: replace a field, not a whole step; never the whole model (path "" is refused).
New or replaced steps follow the config constraints in the server instructions (retain: true on transforms, unique id = key, {{}} references, ...).
Don't send __context (it's stripped anyway). A clipped collection must stay exactly as stored — no edits, no removal, no replacement with the sample you saw. A patched collection may hold at most 100 rows.
All operations apply or none do. At most 200 per call.
RESULT { saved, updated_at, validation, tests: { total, passed, failed, unchecked, failures: [{ test, problems }] }, version_url, next_steps }. saved: false = schema validation failed, nothing stored — fix from validation.errors and retry. A conflict error = the draft changed since you read it — call get_project again and rebuild. Tests are priced after saving and don't block it: report failures and ask whether their expected outputs should change. For every test's actual vs expected values, call run_version_tests. For another patch, use the returned updated_at. Never approves or publishes — the user does that in the UI.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| operations | Yes | RFC 6902 JSON Patch operations, applied in order to the full stored model, all or nothing. At most 200. | |
| base_updated_at | Yes | The draft's updated_at exactly as get_project (called with this version_reference) or the previous patch returned it. A mismatch means someone changed the draft since — the patch is refused. | |
| version_reference | Yes | UUID of the draft version to patch: get_project's latest_draft.version_reference. Never a published or approved version. |