https://api.decisionnode.com /v1/collections/{id}/items/{item_id}curl -X PATCH https://api.decisionnode.com/v1/collections/col_3f6c1a9e0b2d4c7f8a1e5d9b2c4f6a80/items/itm_9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d \
-H "Authorization: Bearer $DECISIONNODE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"label":"Anna, front desk","metadata":{"department":"front_desk","badge":1042}}'The SDK releases have no call to edit an item yet, so the samples call the route over HTTPS. Send an Idempotency-Key to make a retried edit run once.
Headers#
AuthorizationheaderrequiredBearer dn_live_.... A Full access key: every call acts for that key's workspace only, and a Decisions-only key gets403key_scope_denied, "This key may only make decisions."Content-Typeheaderapplication/json. Not checked: the body is read as JSON whatever its type.Idempotency-Keyheader- 1 to 255 printable ASCII characters of your choosing, sent once. A retry with the same key, route and body within 24 hours gets the first answer again; see Retrying.
Path parameters#
idstringrequired- The collection:
col_and 32 hex digits for your own. item_idstringrequired- The item:
itm_and 32 hex digits.
Request body#
referencestring- The new reference, as an enrollment's: 1 to 64 characters of
A-Z,a-z,0-9and_ . : -. labelstring or null- The new label, 1 to 128 characters;
nullclears it. metadataobject- The new metadata, replacing the whole object (
{}clears it), under the enrollment's rules.
Send any of the three; a field left out stays as it is. A body with none is a 422 at ["body"], "Send reference, label, metadata or any of them". The face's template never changes, and the body is at most 4 KiB.
Response#
200 OK with the item as it is now. An edit is never billed, and it stays open on an empty balance. The change is recorded in your workspace's audit log as the key's, naming the metadata keys that changed, never their values.
{
"id": "itm_9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d",
"reference": "emp-1042",
"label": "Anna, front desk",
"metadata": { "department": "front_desk", "badge": 1042 },
"created_at": "2026-10-12T09:00:00Z"
}Errors#
| Status | Type | When | What to do |
|---|---|---|---|
400 | api_usage_error | A malformed Idempotency-Key: "Idempotency-Key must be sent once, as 1 to 255 printable ASCII characters." | Send one key of 1 to 255 printable ASCII characters |
401 | authentication_error | The key is missing, unknown or revoked | Check the Authorization header |
403 | key_scope_denied | A Decisions-only key: "This key may only make decisions." | Use a Full access key on your server |
403 | collection_read_only | The collection is a public one: "<name> is a public collection and cannot be changed or listed." | Act on one of your own collections |
403 | workspace_suspended | The workspace is suspended: "This workspace is suspended. Contact hello@bynn.com." | Write to us |
404 | collection_not_found | No such collection for your workspace; another workspace's reads the same. "Collection not found: <id>.", the id repeated only when it has the form of one | Check the id |
404 | item_not_found | No such item in the collection: "Item not found: <id>." (likewise) | Check the item id |
409 | idempotency_key_reused, idempotency_in_progress | The key was used with another request, or its first request still runs (Retry-After: 1) | See Retrying |
408 | request_timeout_error | The request body did not arrive in time. | Send it again |
413 | request_too_large_error | The body is over 4 KiB. The message is the API's general one, which names 25 MiB | Send a smaller body |
422 | a detail list | A field out of bounds, as an enrollment's; no field to change | Fix the field; a 422 frees the Idempotency-Key |
422 | a detail list | The body is not JSON (json_invalid) | Send a JSON object |
429 | rate_limit_error | Over your request rate | Wait Retry-After, then send the same call again |
500 | api_error | A fault on our side | Retry with backoff |
529 | overloaded_error | The collections cannot take the call right now | Wait Retry-After (1 s, or 1 to 2 s when the key store is busy), then retry |
A refusal is {"detail": {"error_type": "...", "message": "..."}}; a 422 is {"detail": [...]}, one entry per field, each with type, loc, msg and input (a string cut to 64 characters, an object or array never echoed). Every 429 and 529 and the 409 idempotency_in_progress carry Retry-After (seconds) and retry-after-ms (milliseconds); enrollment_unpriced carries neither. The Collections API's own refusals (api_usage_error, collection_read_only, item_not_found, collections_region_unavailable, the limits, the idempotency 409s and image_url_refused) also carry x-decisionnode-error, the message in ASCII. Retry 408, 429, 529 and any 5xx after Retry-After; fix the call for the other 4xx.