Skip to main content
Resources that can be edited from multiple channels (API + NT24 web app) carry an 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

Response headers include:
The body also carries "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

A 409 is a problem document and carries no copy of the resource, so re-read before retrying.
Merge your intended change with the current state and retry with the tag from that read:

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)
Append-only resources (documents, self-service invitations) don’t have versions. Their mutations create new records or set status fields exclusively, so concurrency conflicts don’t arise.

Transport milestones: repeatable, not versioned

Pickup and delivery confirmations are not optimistically concurrent. They carry no version and take no If-Match:
  • POST /transport/pickup twice → the second call replaces the recorded pickupDate. Same for delivery.
  • 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 409 these operations declare is a different refusal: an order split across several shipments, where the request does not identify which transport to record against.
Each milestone is a single date on a single row, so there is no merge for a concurrent write to get wrong — the last write is the recorded one, and it is the one GET /transport reports.

Next

Error reference

The 409 and 428 problem documents in full.

Idempotency

Safe retries on writes.