FHIR has two id-shaped fields on almost every resource, and they do different jobs. Resource.id is the server's logical id — where the resource lives. Resource.identifier[] is the business identity — the MRN, order number, or external system id. Confusing the two produces payloads that look consistent and are silently wrong. The site's fullUrl UUID spinner generates ids that fit Resource.id. For the wider FHIR framing, our FHIR tool reviews has more.
Resource.id: The Server-Owned Address
Resource.id is:
- Assigned by the server on POST, or supplied by the client on PUT
- Unique per resource type per server
- The key used by every Reference
- Part of the URL:
Patient/{id}
That is a lot of responsibility for one string. Servers usually assign UUIDs; clients using PUT sometimes supply ids they chose.
For the choice-of-shape question, when to use a UUID for a FHIR resource id vs a natural identifier is the entry.
Resource.identifier[]: The Business-Owned Identity
Resource.identifier[] is:
- A repeating list of identifiers from various namespaces
- Each with a
system(URL identifying the namespace) andvalue(the identifier string) - Optional
use(usual, official, temp, secondary) - Optional
type(a coded classification of the identifier)
A Patient can carry an MRN identifier, an SSN identifier, and an external system's Patient identifier all in identifier[]. Each has a system URL that scopes its meaning.
The Difference In One Sentence
Resource.id says "where I live." Resource.identifier[] says "who I am, in different systems' books."
Both matter. Neither substitutes for the other.
Reference.reference vs Reference.identifier
Both id shapes appear on the reference side too:
Reference.reference— points atResource.id(URL form)Reference.identifier— points atResource.identifier[](namespace + value)
Use Reference.reference when you know where the target lives. Use Reference.identifier when you know the target's business identity but not its location. Federated deployments often use both.
For the wider mechanic, urn:uuid: in Bundle.entry.fullUrl and why it matters covers cross-entry references specifically.
What Not To Do
- Do not put an MRN in
Resource.id— that leaks business identity into the URL - Do not omit
identifier[]when the business identity matters — downstream consumers cannot find the target - Do not treat
Resource.idas stable across servers — it is per-server - Do not use
identifier[]alone in URLs — the spec expectsResource.idin the URL path
Stability
Resource.id is stable for the lifetime of the resource on that server. identifier[] values are usually stable because they represent external business identity, but the identifier list can grow — adding a new identifier for a new system is normal.
For the environment-stability side, keeping UUIDs stable across environments is the entry.
The Common Pattern
Modern FHIR deployments:
Resource.id— server-assigned UUIDidentifier[]— one or more business identifiers with system URLs
Consumers use Resource.id for internal navigation and identifier[] for cross-system correlation. Both are populated on every resource that has an external identity.
The Short Version
Resource.id is where the resource lives. identifier[] is who the resource is in the outside world. Both are populated. UUIDs work for id; business keys go in identifier[]. For the choice-of-shape question, when to use a UUID for a FHIR resource id vs a natural identifier is the entry.
Sources
- HL7 canonical FHIR Identifier datatype specification - HL7 canonical FHIR Identifier datatype specification