---
title: Revisions and conflicts
description: "A revision is a counter the server owns, six writes check the one you send, and a mismatch is refused rather than merged into whatever arrived last."
---

A **revision** is an integer the server increments on every change. Read it, send it back with your write, and the server refuses the write if anything changed in between. Nothing is locked while you think.

## What carries one

Fifteen responses report a revision. Records carry one, and so do objects, price books, saved reports, dashboards and the commercial policy.

**A field does not.** Fields are read through their object, and the object's revision moves when a field changes.

## What checks one

Reporting a revision and checking one are different things. Six writes take a `revision` in the body, and only those six can be refused for staleness:

| Write | What the revision pins |
| --- | --- |
| [`PUT /objects/{objectId}/records/{recordId}`](/reference/crm/put-api-v1-objects-by-object-id-records-by-record-id) | The record being updated |
| [`DELETE /objects/{objectId}/records/{recordId}`](/reference/crm/delete-api-v1-objects-by-object-id-records-by-record-id) | The record being archived |
| [`PATCH /objects/{objectId}`](/reference/crm/patch-api-v1-objects-by-object-id) | The object being renamed |
| [`PUT /settings/commercial`](/reference/commerce/put-api-v1-settings-commercial) | The commercial policy |
| [`POST /approvals`](/reference/approvals/post-api-v1-approvals) | The record being submitted |
| [`POST /documents`](/reference/documents/post-api-v1-documents) | The record being rendered |

The last two are not updates. They pin the version of a record that something else is built on: an approval **snapshots what the approvers will read**, and a document renders the record as it was at that revision. Sending a stale one there means approving or rendering something the author never saw, which is why it is refused rather than resolved to the newest.

## Handling the refusal

A stale revision answers `409`. There is nothing to merge, because the server does not know which of the two versions you meant:

1. Read the record again.
2. Decide what to do with the value that changed — ask the user, or recompute.
3. Send the write with the revision you just read.

Retrying with the same revision will fail the same way. Retrying with the _newest_ revision without looking at what changed is how an edit silently overwrites someone else's.

## Three things called a version

| Term | What it is |
| --- | --- |
| A record's `revision` | The optimistic-concurrency counter above |
| The `revision` on [`GET /capabilities`](/reference/crm/get-api-v1-capabilities) | The **module policy** revision the answer was read at. It moves when the workspace's modules or permissions change, not when a record does |
| A quote's `version` | A deliberate, numbered revision of a quote that a person created and can be read back on its own route |

Only the first is checked on a write.
