Concurrency

What stops two updates to the same resource from silently losing one of them.

The problem

Two operators open the same issuer. One changes the display name, the other changes the status mechanism. Both save. Without concurrency control, whoever saved second wins entirely, and the first change is gone with nothing reporting it.

How the Management API handles it

A read returns an entity tag:

GET /management/issuers/workforce?api-version=2026-08-30

HTTP/1.1 200 OK
ETag: "AAAAAAAAB9E="

Quote it on the update:

PATCH /management/issuers/workforce?api-version=2026-08-30
If-Match: "AAAAAAAAB9E="

If the resource has changed since you read it, the tag no longer matches and the update is rejected:

HTTP/1.1 412 Precondition Failed
{ "error": { "code": "precondition_failed", "message": "Issuer 'workforce' has changed since the entity tag you supplied. Re-read it and retry." } }

The write does not happen. A 412 that still applied the change would be worse than no concurrency control, because you would believe you were protected.

Omitting If-Match

An update with no If-Match is unconditional and succeeds. That is the standard HTTP reading, and it keeps the operation usable for the many callers writing a value nobody else touches.

DiligenceID does not return 428 Precondition Required. Requiring If-Match everywhere would break every existing integration to provide a guarantee most of them do not need. Where a resource genuinely cannot tolerate a blind write, that is a decision for the resource, not for the whole plane.

If your own workflow needs the guarantee, always send If-Match. Nothing stops you.

If-Match: * means "only if it exists", which is already true by the time the check runs.

409 and 412 are different

Status Meaning What to do
409 Conflict The request cannot be reconciled with the resource's state Do not retry unchanged. Something is genuinely wrong
412 Precondition Failed Your copy is out of date Re-read, re-apply, retry

Collapsing them would tell a caller to give up when they should retry.

Which resources have entity tags

Resource ETag
Issuer Yes — and If-Match is honoured on update
Organisation Yes
Credential configuration No
Verification policy No

Verification policies carry no version token in storage, so no entity tag is emitted. One derived from a timestamp would be a concurrency guarantee the storage layer does not actually make. Suspend and reactivate are state transitions rather than blind writes, so the absence costs little.

The compatibility routes

/v1.0 and /v1 keep the older mechanism: send rowVersion in the request body, and a stale value returns 409.

Those routes deliberately ignore If-Match. A caller there may be sending it through a proxy or a generic client library, and honouring it would change behaviour under an integration that never opted in.

The canonical plane hides rowVersion behind the entity tag, because which storage column backs the version is not something an integrator should need to know.

Next

Edit this page on GitHub