Appearance
IDs, Codes, and Canonicalization
This page defines the identifier types used across services, how they are formatted, how they are canonicalized, and how to obtain them. Treat all identifiers as opaque unless a specific rule is documented.
Canonical identifier table
| Identifier | Format | Canonicalization | Used in | How to obtain |
|---|---|---|---|---|
orgcode | String (org-scoped code) | Trim + uppercase (canonical) | Headers, OFM, all org-scoped services | OFM org create → orgcode; OFM resolve (/resolve/orgcode). |
org_guid | UUID-like string | Case-insensitive; treat as opaque | Legacy OFM identity field (see Naming standard) | OFM resolve (/resolve/orgcode). |
cccode | ^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$ | Uppercase | Cost attribution + OFM cost centre | OFM cost-centre create/list/resolve. |
logical_guid | UUID-like string | Opaque | Legacy facility identity field (see Naming standard) | OFM logical create/list/resolve. |
channel_code | Lowercase snake_case (registry) | Lowercase | Sales channel taxonomy | OFM sales-channel declaration create/list; registry in OFM. |
channel_guid | UUID-like string | Opaque | Legacy sales-channel identity field (see Naming standard) | OFM sales-channel create/list/resolve. |
user_id | Opaque string | Opaque | UAS/USM user identity | UAS user create/snapshot. |
user_guid | Opaque string | Opaque | Legacy user identity in OFM edges (see Naming standard) | OFM member/resolve; UAS user snapshot (if returned). |
style_id / variant_id | Opaque string | Opaque | PVM styles/variants | PVM create/list/get endpoints. |
vendor_id / manufacturer_id | Opaque string | Opaque | PVM supplier layer | PVM vendor/manufacturer create/list/get. |
product_id | Opaque string | Opaque | PMC published product identity | PMC publish run outputs; PMC product get/list. |
order_id | Opaque string | Opaque | SCM orders | SCM order create/get/list. |
po_id / receipt_id / invoice_id | Opaque string | Opaque | PCM procurement lifecycle | PCM worksheet/PO/receipt/invoice endpoints. |
If a format is UNCONFIRMED, the identifier is still treated as opaque and must be stored/echoed exactly as returned.
Naming standard (preferred going forward)
- Canonical field name: use
*_idfor opaque record identifiers, even when the underlying value is a GUID/UUID. - Legacy
*_guid: some existing surfaces still use*_guidas the canonical field name. Do not add*_idaliases and do not return dual fields. Renaming a*_guidfield to*_idis a breaking change and must be explicit. - Codes remain
*_code/orgcode/cccodeand are never used as primary record identities.
No migration window: responses must never include both *_id and *_guid for the same record. Each surface exposes exactly one canonical identifier field.
Read-surface policy (anti-enumeration safe)
- Direct GET/UPDATE/STATUS calls: require
*_id(GUID/UUID value) and are org-gated. If the caller is not associated with the org, services return 404 to avoid existence leakage. - Resolve/lookups: non‑GUID identifiers (codes, barcodes, aliases, emails) are allowed only via explicit resolve or search endpoints, and must still enforce org membership.
- Exceptions (by design):
- UAS email subrecords are keyed by email (human identifier) and remain supported.
- PVM resolve endpoints (barcode/alias/identifier) are required for integrations.
- MRS
container+record_idare string namespaces by contract.
This policy is about minimizing enumeration risk while keeping integration‑friendly resolve endpoints.
Codes vs IDs
Some endpoints accept code fields (human-friendly) and some require IDs (opaque):
- Codes are stable, human-facing identifiers (examples:
orgcode,cccode,channel_code,codefields for taxonomy). - IDs are opaque record identifiers (
*_id,*_guid) returned by create/list/get calls.
Rules:
- If an endpoint accepts both a code and an ID, they must refer to the same record or the request fails (
validation-errorornot-found, per service). - If you provide the wrong type (code in an ID field), expect
validation-errorornot-found.
Canonicalization rules (baseline)
- Trim leading/trailing whitespace for all codes.
- Uppercase:
orgcode,cccode, mostcodefields unless the service explicitly states lowercase. - Lowercase:
channel_code(registry-defined). - Emails: trim + lowercase (UAS/USM).
When in doubt, use the canonical form returned by the service.
How to obtain each ID (quick map)
- Org:
POST /ofm/org/create→org_guid,orgcode. Resolve by code:POST /ofm/resolve/orgcode. - Facility:
POST /ofm/facility/logical/create→logical_guid. - Sales channel:
POST /ofm/sales-channel/create→channel_guid;channel_codeis provided by the caller but validated against the registry. - User:
POST /uas/user/create(direct Lambda) →user_id;POST /uas/stat(API Gateway) for snapshots. - Product model:
POST /pvm/style→style_id,POST /pvm/variant→variant_id. - Publish:
POST /pmc/publish/run/start→run_idand resultingproduct_idin manifests.
See each service’s Surfaces and Calls pages for concrete examples.