SMART Health Check-in over W3C Digital Credentials API
A clinic asks for check-in information. The patient chooses what to share.
This page explains the JSON model: who asks, what can be requested, how the wallet replies, and how every requested item gets an outcome.
Who asks, who answers
During check-in, a clinic system, front-desk kiosk, or patient portal asks for information such as demographics, insurance, medications, or an intake form. The patient's wallet shows that request and returns what the patient approves.
Clinic, kiosk, or portal
The app asking for information. It explains the reason for the request, lists the information it needs, and names the formats it can read.
- Prepares the check-in request.
- Starts wallet review of the request.
- Checks the response against the original request.
Patient wallet or health app
A patient wallet or health app. It knows what data is available, shows the request to the patient, and creates the response.
- Finds matching information it can offer.
- Shows the patient what will be shared.
- Returns shared information plus an outcome for every item.
The patient stays in control
The request describes what would help with check-in. The wallet shows it to the patient, and the patient chooses what to share. The response can include all requested items, only some items, no items, or other helpful records the patient approves.
- The app explains why it is asking. Example: clinic check-in, billing, visit intake, or prior authorization.
- The app lists the information it wants. Examples: patient demographics, insurance card, health summary, intake form.
- The wallet checks what it can provide. The wallet decides what it can offer and how each item should be shown.
- The patient chooses what to share. The patient may approve, decline, or fill out a form when asked.
-
The wallet reports what happened.
Shared records cite item ids in
fulfills[]. Outcome rows cite item ids inrequestStatus[].
Core rule: every requested item gets exactly one
response.requestStatus[] row. Shared records point back to
one or more item ids using fulfills[].
What the app sends to the wallet
A request has an id, a reason for asking, the FHIR versions the app can read, and the list of items to present for patient review.
{
"type": "smart-health-checkin-request",
"version": "1",
"id": "demo-us-core-checkin",
"purpose": "Clinic check-in",
"fhirVersions": ["4.0.1"],
"items": [
{ "...": "request item" }
]
}
- type
- Fixed label:
smart-health-checkin-request. - version
- Model version. Current value is
"1". - id
- Request id echoed by
response.requestId. - purpose
- Reason shown to the patient, such as
Clinic check-in. - fhirVersions
- FHIR versions the app can read.
- items
- The named pieces of information being requested.
Implementer trust note: request text helps the patient understand why sharing is being requested. Identity and trust decisions come from the browser, wallet, reader authentication, and local policy.
Each item asks for one kind of information
Each item is one thing to show the patient. It has a stable id, display text, a description of the requested content, and the response formats the app can accept.
{
"id": "insurance",
"title": "Insurance card",
"summary": "Insurance card for billing",
"required": true,
"content": { "...": "what is being requested" },
"accept": ["application/fhir+json"]
}
- id
- Short stable name. The response uses this id when reporting results.
- title / summary
- Text shown to the patient.
- required
- Marks an item as important to the app asking. The patient still chooses what to share.
- content
- The information being requested.
- accept
- Response formats the app can read.
Exact FHIR profile
Use profiles to ask for resources conforming to exact
StructureDefinition canonicals, such as US Core Patient.
{
"id": "patient",
"title": "Patient demographics",
"content": {
"kind": "selection.fhir",
"profiles": [
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"
]
},
"accept": ["application/fhir+json"]
}
Questionnaire
Use kind: "form.fhir" when the wallet should render a
FHIR Questionnaire, accept user input, and return a
QuestionnaireResponse.
{
"id": "intake",
"title": "Migraine intake",
"content": {
"kind": "form.fhir",
"questionnaire": {
"resourceType": "Questionnaire",
"title": "Migraine Check-in",
"item": [
{
"linkId": "severity",
"text": "Pain severity (0-10)",
"type": "integer"
}
]
}
},
"accept": ["application/fhir+json"]
}
Asking for FHIR records
The app can ask for a specific FHIR profile, such as US Core Patient, or
for a broader family of records, such as anything the wallet can share
from US Core. It can also name FHIR resource types like
Condition, MedicationRequest, or
Observation.
{
"id": "us-core-records",
"title": "US Core records",
"summary": "Patient records your app can share that conform to US Core profiles.",
"content": {
"kind": "selection.fhir",
"profilesFrom": ["http://hl7.org/fhir/us/core"]
},
"accept": ["application/fhir+json"]
}
US Core family, narrowed by resource type
{
"id": "us-core-problems-meds-labs",
"title": "Problems, medications, and labs",
"content": {
"kind": "selection.fhir",
"profilesFrom": ["http://hl7.org/fhir/us/core"],
"resourceTypes": ["Condition", "MedicationRequest", "Observation"]
},
"accept": ["application/fhir+json", "application/smart-health-card"]
}
- profiles
- Exact StructureDefinition canonicals, such as US Core Patient.
- profilesFrom
- Publication, implementation guide, or profile-collection canonical URLs, such as US Core as a family.
- resourceTypes
- Optional official FHIR resourceType narrowing within the profile family.
- no FHIR filters
- Ask for any patient-specific FHIR resources the wallet can offer and the user chooses to share.
Version rule: preserve the original canonical string
exactly. Versioned canonicals require resolver or FHIR-search semantics
that verify the requested version; do not satisfy them by stripping
|version and directly dereferencing the bare URL.
What the wallet sends back
The response tells the app what was shared and what happened for every requested item. It also links each shared record back to the item or items it answers.
{
"type": "smart-health-checkin-response",
"version": "1",
"requestId": "demo-us-core-checkin",
"artifacts": [
{ "...": "shared clinical content" }
],
"requestStatus": [
{ "...": "one outcome per item" }
]
}
- requestId
- Must equal the original request
id. - artifacts
- Shared records or forms the patient approved.
- requestStatus
- One outcome for every requested item.
Shared records are what the patient approved
In the JSON, each shared record is called an artifact. It
has its own id, a media type, and a fulfills[] list that
maps it back to one or more request items.
FHIR JSON resource or bundle
{
"id": "artifact-us-core",
"mediaType": "application/fhir+json",
"fhirVersion": "4.0.1",
"fulfills": ["clinical-history"],
"value": {
"resourceType": "Bundle",
"entry": [ ... ]
}
}
SMART Health Card
{
"id": "artifact-clinical-shc",
"mediaType": "application/smart-health-card",
"fulfills": ["clinical-history"],
"value": {
"verifiableCredential": ["shc:/567629..."]
}
}
SMART Health Cards do not use outer fhirVersion; the app
inspects the signed SMART Health Card data.
| JSON field | Meaning | Important rule |
|---|---|---|
id |
Wallet-chosen record identifier. | Unique inside the response. |
mediaType |
How the receiving app should read the record. | Must be accepted by every item in fulfills[]. |
fulfills |
Request item ids this record answers. | Must be non-empty and reference real request item ids. |
| Content fields | Defined by mediaType. |
Raw FHIR uses value plus fhirVersion; SMART Health Cards use value.verifiableCredential[]; extensions define typed fields explicitly. |
Every requested item gets an outcome
The status list tells the app what happened even when no record is returned for an item.
{
"item": "insurance",
"status": "fulfilled",
"message": "Shared digital insurance card"
}
| Status | Meaning |
|---|---|
fulfilled | Information for this item was shared. |
partial | Some, but not all, useful content was shared. |
unavailable | The wallet has no matching data. |
declined | The user chose not to share it. |
unsupported | The wallet does not understand that kind of request. |
error | The wallet tried but failed. |
A complete example
This simplified example asks for any US Core records and an intake form, then returns a FHIR Bundle and QuestionnaireResponse.
{
"type": "smart-health-checkin-request",
"version": "1",
"id": "demo-us-core-and-intake",
"purpose": "Clinic check-in",
"fhirVersions": ["4.0.1"],
"items": [
{
"id": "us-core-records",
"title": "US Core records",
"content": {
"kind": "selection.fhir",
"profilesFrom": ["http://hl7.org/fhir/us/core"]
},
"accept": ["application/fhir+json"]
},
{
"id": "intake",
"title": "Migraine intake",
"content": {
"kind": "form.fhir",
"questionnaire": { "resourceType": "Questionnaire", "title": "Migraine Check-in" }
},
"accept": ["application/fhir+json"]
}
]
}
{
"type": "smart-health-checkin-response",
"version": "1",
"requestId": "demo-us-core-and-intake",
"artifacts": [
{
"id": "artifact-us-core",
"mediaType": "application/fhir+json",
"fhirVersion": "4.0.1",
"fulfills": ["us-core-records"],
"value": { "resourceType": "Bundle", "entry": [ ... ] }
},
{
"id": "artifact-intake",
"mediaType": "application/fhir+json",
"fhirVersion": "4.0.1",
"fulfills": ["intake"],
"value": { "resourceType": "QuestionnaireResponse" }
}
],
"requestStatus": [
{ "item": "us-core-records", "status": "fulfilled" },
{ "item": "intake", "status": "fulfilled" }
]
}
For implementers: message details
This page explains what the app and wallet exchange. CBOR, direct mdoc namespaces, HPKE encryption, SessionTranscript binding, MSO digests, COSE signatures, and fixture annotations live in the wire protocol explainer.