Spinrun Docs
Build

Concurrency with updated_at and If-Match

A replace without If-Match is refused, and a stale write gets the current document back.

Every document the server returns carries updated_at. It is the version stamp, and it travels twice when you replace a document:

  • inside the document, unchanged from the one you read — a body whose updated_at differs from the header is rejected with 400;
  • as the If-Match header, quoted: If-Match: "2026-09-01T10:00:00.000Z". A replace without it is refused with 428.

If the document changed since you read it, the reply is 409 with three fields: error, current — the document as it is now, including its new updated_at — and applied, the list of stages that had already been written if the conflict surfaced part way through (normally empty). To recover, merge your change into current, keep its updated_at, and put again. Never retry with the stale document: the conflict exists because someone else's edit is in it.

A create is a PUT on the collection (/api/build/agents, /api/build/workflows) with no updated_at; it answers 201. A replace is a PUT on the item, by id or slug.

spinrun agent get triage-bot > agent.json
spinrun agent put --file agent.json

The CLI sends the document's updated_at as If-Match for you.

On this page