Apply a delta batch to a branch (OCC)
const url = 'https://api.hydrate.sh/v1/branches/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/deltas';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"deltas":[{"node":{"data":{"aliases":["example"],"config":[{"contract_name":null,"description":"","external":false,"id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","name":"","type":""}],"constraints":["example"],"description":"","documentation_url":null,"external_kind":null,"inputs":[{"contract_name":null,"description":"","external":false,"id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","name":"","type":""}],"is_external":false,"is_test_node":false,"kind":null,"language":null,"name":"","outputs":[{"contract_name":null,"description":"","external":false,"id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","name":"","type":""}],"parent_id":null,"path_prefix":null,"protocol":null,"source_decisions":["2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"],"status":"idle","user_kind":null,"verifications":[{"author":"user","id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","text":"example","type":null}]},"id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","kind":"behavior","parent_id":null},"type":"add_node"}],"expected_version":1,"positions":{"additionalProperty":{"x":1,"y":1}}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.hydrate.sh/v1/branches/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/deltas \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "deltas": [ { "node": { "data": { "aliases": [ "example" ], "config": [ { "contract_name": null, "description": "", "external": false, "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "name": "", "type": "" } ], "constraints": [ "example" ], "description": "", "documentation_url": null, "external_kind": null, "inputs": [ { "contract_name": null, "description": "", "external": false, "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "name": "", "type": "" } ], "is_external": false, "is_test_node": false, "kind": null, "language": null, "name": "", "outputs": [ { "contract_name": null, "description": "", "external": false, "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "name": "", "type": "" } ], "parent_id": null, "path_prefix": null, "protocol": null, "source_decisions": [ "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" ], "status": "idle", "user_kind": null, "verifications": [ { "author": "user", "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "text": "example", "type": null } ] }, "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "kind": "behavior", "parent_id": null }, "type": "add_node" } ], "expected_version": 1, "positions": { "additionalProperty": { "x": 1, "y": 1 } } }'Apply an ordered batch of structural changes to a branch under optimistic concurrency. Pass the version from the branch read as expected_version; a 409 with current_version is returned if the branch moved underneath you. Pair with the Idempotency-Key header for at-most-once apply across retries.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The branch to apply to.
The branch to apply to.
Request Bodyrequired
Section titled “Request Bodyrequired”Request body for POST /v1/branches/{bid}/deltas.
object
Ordered list of delta operations to apply. Each must carry a type field in the closed write-surface vocabulary (add_node / delete_node / update_node_data / reparent_node / add_edge / delete_edge / flatten_boundary). Empty list returns 200 with applied: false and no version bump.
Insert a node.
object
A behavior or boundary node.
object
A node’s data payload; its shape varies by kind and whether the node is external.
On update, key-presence semantics apply: a field present with a null value is
set to null, while an omitted field is left unchanged. All fields are optional
at the type level — cross-field rules (e.g. behavior nodes reject user_kind;
external nodes require external_kind) are enforced server-side, so a partial
update is not blocked by “missing required field” errors that don’t apply to it.
object
Cascade-delete a node and its descendant subtree.
object
Update a node’s data, with key-presence partial semantics.
after may be empty; whether a field is present in after distinguishes
“set this field” from “leave it unchanged”.
object
A node’s data payload; its shape varies by kind and whether the node is external.
On update, key-presence semantics apply: a field present with a null value is
set to null, while an omitted field is left unchanged. All fields are optional
at the type level — cross-field rules (e.g. behavior nodes reject user_kind;
external nodes require external_kind) are enforced server-side, so a partial
update is not blocked by “missing required field” errors that don’t apply to it.
object
Move a node to a new parent (or to top-level).
parent_id must be present on the wire (use null for top-level); an absent key
is rejected, so a client bug surfaces as a clean parse error rather than an
ambiguous no-op.
Insert an edge.
object
An edge connecting two nodes’ ports.
Endpoints are given as source_handle / target_handle, each a port
id. Unknown keys are ignored rather than rejected.
Remove an edge.
object
Flatten a boundary node: delete it and promote its children to its parent.
object
The branch.version the client believes is current. If it doesn’t match the server’s view at commit time, the route 409s with the actual current_version in the detail.
Responses
Section titled “Responses”Successful Response
object
Example
{ "positions_applied": null}No credentials, malformed credentials, or revoked credentials. The envelope is leak-parity (same shape across all 401 paths) so an attacker cannot distinguish revoked vs. unknown via the body.
object
Example
{ "detail": "unauthenticated"}Credentials are valid but lack the scope required for this route, or the principal lacks membership in the target project.
object
object
Examplegenerated
{ "detail": { "code": "example", "message": "example" }}Branch/project not found or not accessible, OR a delta targets a node that doesn’t exist.
object
object
Returned when a delta targets a node that doesn’t exist (404). node_id
identifies the missing target.
object
Example
{ "detail": { "error": "not_found" }}OCC version conflict, or the branch is not active.
object
object
object
Example
{ "detail": { "error": "version_conflict" }}Request body failed validation, OR a delta is malformed / unknown / not an object.
object
object
object
object
The 7-key per-delta envelope (always all keys present) the frontend
auto-recovery consumes. Shared by every 422 delta error; error
discriminates the cause.
object
The finite set of recovery hints a client may receive in
ApiError.recovery_hint:
- "regenerate_uuid" — mint a new UUID at `field` and retry
- "drop_field" — delete `field` and retry
- null — not auto-recoverable; user intervention needed
A closed set, so integrations can switch over the value; a new hint is added here deliberately, giving clients a chance to handle it.
Example
{ "detail": { "error": "malformed_delta_field", "recovery_hint": "regenerate_uuid" }}Per-bucket rate limit exceeded. The response carries Retry-After and the standard X-RateLimit-* headers (Limit / Remaining / Reset).
object
Example
{ "detail": "rate_limited"}