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.

  1. The app explains why it is asking. Example: clinic check-in, billing, visit intake, or prior authorization.
  2. The app lists the information it wants. Examples: patient demographics, insurance card, health summary, intake form.
  3. The wallet checks what it can provide. The wallet decides what it can offer and how each item should be shown.
  4. The patient chooses what to share. The patient may approve, decline, or fill out a form when asked.
  5. The wallet reports what happened. Shared records cite item ids in fulfills[]. Outcome rows cite item ids in requestStatus[].

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.

Any US Core resource the wallet can share
{
  "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
fulfilledInformation for this item was shared.
partialSome, but not all, useful content was shared.
unavailableThe wallet has no matching data.
declinedThe user chose not to share it.
unsupportedThe wallet does not understand that kind of request.
errorThe 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.