Identifiers & natural keys
Every record has a server-assigned GUID Id, but the API is designed so
integrators rarely need to store or look up GUIDs: most entities also carry
natural keys that create/update/bulk operations can resolve directly. This
page explains which key wins when several are supplied, and how deletions
propagate to systems that sync by key.
The identifier kinds
| Identifier | Assigned by | Purpose |
|---|---|---|
Id (GUID) | Server, on create | Primary key. Returned in every response DTO; required by Get/Update/Delete by-id endpoints. |
ExternalRef | You (the integrator) | Your system's key. Bulk upserts match rows by (Organisation, ExternalRef) — this is the idempotency key for IMS/ERP sync. |
Code (e.g. PlaceCode, department/season codes) | You | Short business code. For merchandise departments and seasons the natural key is Code, not name. |
Name | You | Display name; unique within its type for most reference data. Lowest-precedence lookup key. |
EntityVersionNo | Server | Increments on every update — use it to detect concurrent modification. |
Precedence: which key wins
When an operation accepts multiple ways to reference a related entity, the resolution order is most-specific first:
- SKU dimension references (brand/category/colour/… on a SKU):
Id→ExternalRef/Code→Name. If you send anId, the other fields are ignored. - Bulk place resolution (e.g. external stock-count feeds):
PlaceId→ExternalRef→PlaceCode. NoteExternalRefbeatsPlaceCode. - SKU resolution in ERP-facing endpoints: SKU number, external ref, or any barcode — see below.
Send exactly one key per reference where you can; mixed keys resolve by the
precedence above, which can mask typos (a wrong ExternalRef alongside a
correct Name resolves to the ExternalRef match or fails — the Name is
never consulted).
Tags and barcodes
- Tag numbers are stored uppercase. The server upper-cases every tag number on write, so treat tag comparison as case-insensitive and send uppercase to be safe.
- SKUs carry several scannable identifiers:
SkuNumber, a primaryBarcodeNumber, and any number of additional barcodes. Lookup by any of a SKU's barcodes is supported viagetskuwithbarcode. - SKUs also carry GS1 component fields (
CompanyPrefix,ItemReference,Indicator) used for RFID tag-number (EPC) construction.
Uniqueness is scoped to non-deleted rows
Deletes are soft (an IsDeleted flag) platform-wide, and natural-key
uniqueness checks only consider live rows. Consequences:
- Deleting a record frees its
Name/ExternalRef/Codefor reuse — a re-create with the same natural key succeeds and produces a newId. - If your integration assumes
ExternalRef → Idis stable forever, re-creates break that assumption. Re-resolve ids after any delete/re-create cycle.
Syncing deletions: the ticks watermark
Offline devices and mirror integrations track deletions with the
getdeleted<entity>/{ticks} family (items, SKUs, places, collections, users,
reasons, …):
- Store the timestamp of your last sync as .NET ticks (100-nanosecond intervals since 0001-01-01 — not a Unix epoch).
- Call e.g.
getdeletedskus/{ticks}to get every record soft-deleted since that watermark. - Advance your watermark and repeat.
Results are scoped to your organisation. Pair the deleted feed with the normal filtered list endpoints to mirror creates/updates.
Related
- Errors & response conventions — duplicate natural keys surface as 400 validation failures.
BulkUpsertendpoints — the(Organisation, ExternalRef)idempotent sync pattern.