Skip to main content
Resources that can be edited from multiple channels (API + NT24 web app) carry an integer version that bumps on every modification. The API surfaces it as an ETag header; writes that modify the resource must include If-Match with the last-seen ETag. Mismatch = 409 Conflict with the current resource.

Read → ETag

Response headers include:
Body also carries "version": 5 — same value, two surfaces.

Write → If-Match

Conflict resolution

409 responses carry the full current resource in the body. You don’t need a separate GET to reconcile.
Merge your intended change with the current state and retry with the new ETag:

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 append-only; 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 — immutable once set

Pickup and delivery confirmations are not optimistically concurrent. They are immutable once set:
  • POST /transport/pickup twice → second call returns 409 with milestone-already-set problem type.
  • To reverse, use the explicit POST /transport/pickup/revoke endpoint.
  • Same for delivery.
This is stricter than optimistic concurrency because pickup/delivery have legal consequences (VAT applicability) and should not be “fixed up” via a silent merge.

Under the hood

Versions are backed by Hibernate’s @Version column — platform-wide on all audited entities. Envers captures every revision for audit trail (who/when); @Version prevents concurrent overwrites at commit time.

Next

Error reference

409 version-mismatch detail.

Idempotency

Safe retries on writes.