ETag; writes that modify the resource must include If-Match
with the last-seen tag. Mismatch = 409 Conflict.
Treat the tag as opaque. It is not the version integer and it is not
built from it the same way on every resource — an order’s covers its whole
published body, bar the one field named below; a buyer’s combines the version
with the block flag. Parse nothing out of it and compare it only for equality.
Echo back exactly the tag you were sent; deriving If-Match from version
refuses every write.
Read → ETag
"version": 5. The two are not interchangeable:
version counts writes to the order row, while the tag covers everything the
response publishes about the order — including each VIN’s complianceStatus
and the responsible contact’s details, both of which move without the order row
being written. So If-None-Match tells you the order progressed, not merely
that someone edited it. Send the tag; version is not one and building an
If-Match out of it refuses every write.
One published field is deliberately outside the tag: notApplied describes the
request you sent rather than the order, so a write that reports drift and any
read of the same order still agree on the tag. Without that exclusion, the
writer’s stored tag would be one no read could reproduce and its every
If-None-Match would answer 200 instead of 304.
Write → If-Match
The write precondition is narrower than the tag.
If-Match guards the
order record — the two fields a PATCH may change and everything else stored
on it. The rest of the body is projected on every read from shipments,
transports and the buyer’s contact record, and none of it is something your
PATCH could overwrite, so none of it refuses one. A colleague of yours
correcting a contact person’s phone number in the NT24 web app does not cost
you the tag you are holding. Their email does: responsibleContact is matched
by email, so a body echoing the old address would name somebody else, and the
409 sends you to re-read the order first.
If-Match is compared strongly, per RFC 9110 §13.1.1, so a weakened tag
(W/"...") is refused even when the tag inside it is current. If-None-Match
on the read is compared weakly, as §13.1.2 requires — good enough to confirm a
cached copy, not good enough to authorise overwriting a row.
On a buyer, “someone” is not always you. One KYC record per buyer means the
record is held by every partner that has its KYC result, and any of them can
edit it. A 409 there usually means another partner moved the row, not that
your own copy was built wrong: re-read the buyer and retry.
Conflict resolution
A409 is a problem document and carries no copy of the resource, so
re-read before retrying.
Which resources are versioned
Any resource that NT24 staff can also edit in the web app:- Buyer (
TradePartner) - Order
- Invoice (sub-resource on order)
- Payment (sub-resource on order)
- Transport (pickup/delivery milestones are not versioned; see note)
Transport milestones: repeatable, not versioned
Pickup and delivery confirmations are not optimistically concurrent. They carry noversion and take no If-Match:
POST /transport/pickuptwice → the second call replaces the recordedpickupDate. Same fordelivery.- There is no revoke endpoint and no immutable-once-set rule. NT24 records steps of a compliance process that have already happened, so a pickup that happened cannot be reversed; what a repeat call corrects is the date it was recorded under.
- The
409these operations declare is a different refusal: an order split across several shipments, where the request does not identify which transport to record against.
GET /transport reports.
Next
Error reference
The
409 and 428 problem documents in full.Idempotency
Safe retries on writes.