Product Overview

The digital vaccination record ecosystem has three components:

  • Certified Issuers: Entities that are the source of verifiable vaccination data, e.g., vaccination sites, pharmacies, hospitals, registries, etc. and that issue a certified Credential of vaccination
  • Holders: Applications or individual recipients of a Credential from an Issuer.
  • Verifiers: Applications and entities that verify the Credential stored in the Holder for the purposes of providing access or other activities

In this ecosystem, Change Healthcare provides end-to-end, and selectable services, including:

  • Service provider to and aggregator of Certified Issuers, enabling broad consumer and verifier access to vaccination credentials based on consumer provided consent
  • Lightweight Wallet Application that allows consumers to request and share their vaccination credential
  • Scaled Verification system that enables multiple models of verification including casual and programmatic credential verification

Change Healthcare provides this solution via the following APIs

  • Vaccination Data Intake API: Change Healthcare’s API that enables data to be added to the Vaccine Record Product
  • Vaccination Credential Sharing API: This API that allows the sharing of credentials derived from the data provided by the Data Ingestion API
  • Vaccination Credential Verification API: Change Healthcare’s API that enables the verification of credentials retrieved using the Credential Sharing API

The Vaccination Record Credential APIs are conformant with the Vaccination Credential Initiative (VCI), a cross-industry consortium that includes Change Healthcare. VCI is working to define a set of standards to enable the secure issue, exchange, and verification of vaccination credentials. Change Healthcare’s Vaccination Record is conformant with the specifications defined by the Vaccination Credential Initiative.

What do these APIs do?

The Vaccination Credential Sharing API and Vaccination Credential Verification API allow authorized client applications to request and verify immunization credentials in the form of 'Smart Health Cards' from the Change Healthcare Vaccination Record solution. Authorized users may use these APIs to credibly manage proof of vaccination for individuals. The APIs are compliant with VCI specifications.

Vaccine Credential Initiative SMART Health Card

This API is conformant with the SMART Health Card Implementation Guide (IG) and uses terms and concepts from that IG; most notably, the API uses the following terms:

Adapted from Figure 1 of the W3C Verifiable Credentials specification.Adapted from Figure 1 of the W3C Verifiable Credentials specification.

Adapted from Figure 1 of the W3C Verifiable Credentials specification.

For this API, Change Healthcare is providing the Credential Sharing API in the role of the Holder. You, as a Client of the Credential Sharing APIs, is in the role of the "Verifier".

As a verifier, you will be able to access and validate the health-cards that the Credential Sharing API serves, and present the results to your users, most probably through your own API, or a UI. Note that this API only allows you to REQUEST the credential. There is a separate business approach for validation.

Using the APIs

Getting access to the Sharing and Verification APIs

All of the APIs in this document are served from both Change HealthCare's 'sandbox' environment and 'production' environment. You can integrate your application with masked data in our sandbox environment. The production environment serves live data based on your customer agreement with Change Healthcare.

All the examples in this document assume the sandbox environment. You can invoke the same API in the production environment by using the HostName as shown below.

EnvironmentHost
sandboxsandbox.apis.changehealthcare.com
productionapis.changehealthcare.com

Before you can use the Sharing or Verification APIs in any environment, you will need to obtain an APIGEE clientId and clientSecret to call our secure APIs. The same APIGEE clientId/clientSecret can not be used across different environments. You will require a separate clientId/clientSecret for the sandbox and production environments.

If you need assistance obtaining client APIGEE clientId/clientSecret, please reach out to [email protected]

Getting an APIGEE token using the APIGEE API

Our APIs are secured by an APIGEE Bearer token, which you need to supply as an Authorization header when you call them. To get the bearer token, you will need your clientId and clientSecret. To following Curl shows how to obtain an APIGEE token from the APIGEE API.

curl  -X POST  \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d "client_id=<CLIENT_ID>&client_secret=<CLIENT_SECRET>&grant_type=client_credentials" \
https://sandbox.apis.changehealthcare.com/apip/auth/v2/token
ParameterDescriptionExample
<CLIENT_ID>The APIGEE clientId you will receive when you register with Change HealthCare. This value should be protected like any other credential.3K8YenXcRPou5SpAITuwTr2pQZxAHMVW
<CLIENT_SECRET>The APIGEE clientSecret you will receive when you register with Change HealthCare. This value should be protected like any other credential.mus0exPejuDExRX

Upon a successful invocation (status=200) , the JSON returned by this call will look similar to this:

{
  "access_token": "eyJraWQiOiIxIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJhY2Nlc3NfdG9rZW4iOiJOWkJUNEVOSzF0dHRMUnRkTm5lU3hPYTlvdmlCIiwiYXVkIjoiYXBpUGxhdGZvcm0iLCJhcGlfcHJvZHVjdF9saXN0IjpbIkRTX1ZQYXNzX1Byb2R1Y3RfdjEiXSwiYXBwbGljYXRpb25fbmFtZSI6IlZhY2NpbmVQYXNzcHJ0VjEiLCJuYmYiOjE2MjEwOTc5ODQsImRldmVsb3Blcl9lbWFpbCI6ImxhcnJ5LnNjaG9lbmZlbGRAY2hhbmdlaGVhbHRoY2FyZS5jb20iLCJpc3MiOiJodHRwczpcL1wvc2FuZGJveC5hcGlzLmNoYW5nZWhlYWx0aGNhcmUuY29tIiwic2NvcGVzIjoiIiwiZXhwIjoxNjIxMTAxNTg0LCJpYXQiOjE2MjEwOTc5ODQsImp0aSI6ImFkNDdlNmIxLTk5MjgtNGM3NS1hMTkyLTYxZDhiNTMwM2QzZSJ9.J1Uf5sEhFFNlCP_Z0bbhtzflWlviyTEbpbufVr3_uZeGheZJ_7QiFchnmEnVONHnnRo-gYuN_UjGApsoMIXi1WB9jSmvze-ED4vow9iKKADUHtBxnELyJbzxL1JCzz2VqnraBOjm6YFTiZAN1XC5CFpG9AwVNOuDtb_bOcsbiMMpQf5ZAnVMUtNuL3_AW_Q3jU3l1cX-y6ro8m7cm0yqEkTV1WFrgF7n6qnmunYAePa03kl82Q3Oy_JZR50DWF1Plw2N6qG1QO3P4GK2iFr0WGqiRZMkIzDJbVnTAOjivfuXMIFTl-rwUE3V37kpQqXefg9iaTI9CZqaOZm3mJJkQA",
  "token_type": "bearer",
  "expires_in": 3600
}

The token has a 60-minute time to live (TTL). You can reuse the same token in subsequent calls to the Vaccination Sharing and Verification APIs, but will need to request a new one upon (or before) its expiration.

You will need to parse the access token property from this JSON response before using it in the Sharing and Verification APIs.

Vaccination Credential Sharing API

Process Overview

  • The client first calls the $health-cards-lookup API to obtain an opaque, short-lived patientId if the identifying data in the request is matched. This step of patient identification is NOT part of the existing VCI protocol spec.
  • The client then uses the patientId to call any variation of the $health-cards-issue API to obtain a health-card in the format of a JWS token or QR code as specified by the VCI spec. The client then processes the health-card based on its application's use case.
  • The spec requires that all validator processing scenarios validate the token signature. The client can get the currently published public keys for verification using the jwks.json API.

$health-cards-lookup endpoint

The following Curl shows how to call the $health-cards-lookup API to retrieve a patientId for a patient with the supplied identity profile as the request body:

curl -s -X POST \
    -H "Authorization: Bearer <TOKEN>" \
    -d '<IDENTITY_JSON>' \
    'https://sandbox.apis.changehealthcare.com/dataservices/shc/v1/$health-cards-lookup'
ParameterDescriptionExample
<TOKEN>Apigee access token obtained from The APIGEE API. Do not forget to indicate that it is a Bearer token as shown.See section 'Getting an APIGEE token using the APIGEE API'
<IDENTITY_JSON>JSON object with the identity profile of the patient requesting a health card{
"phone": "8110000801",
"firstName": "Jane",
"lastName": "Doe",
"rxNumber": "99000801",
"dob": "19990101",
"consent": true
}

IDENTITY_JSON PROPERTIES

FieldTypeDescription
phonestring10 digit phone number as recorded in pharmacy record, dash delimited as shownRequired
firstNamestringpatient first name as recorded in pharmacy record, case-insensitiveRequired
lastNamestringpatient last name as recorded in pharmacy record, case-insensitiveRequired
rxNumberstringPrescription number as recorded in pharmacy record.Optional
dobstringDate of birth as recorded in pharmacy record in yyyymmdd formatRequired
consentbooleanpatient's consent to proceed with issuing a health card record. If false, request will be denied.Required

Upon a successful invocation (status=200) , the application/text returned by this call will be the patientId to include in the $health-cards-issue API. It is an 8 character string similar to the following:

D5E6AAC1

API NOTES:

  • The patientId returned by this API is NOT persisted on the server side and may be linked to a different patient at a future date.. Therefore do NOT reuse it on multiple calls to the $health-cards-issue API. The SAFE approach is to always invoke $health-cards-lookup and $health-cards-issue in sequence.
  • The VCI API will locate all immunization records for the phone, firstName, lastName, dob. If you have a multi-immunization health-card (like COVID-19) that potentially has different Rx numbers for the 1st and 2nd dose, the VCI API will accept either Rx number.
  • The Rx number is optional, and may be incorrect or completely omitted, but will not fail the identity match, provided all the other fields match.
  • Your client implementation may choose NOT to submit the request to the $health-cards-lookup API if the user has not given consent. However, in that case, there will not be a record in the VCI audit log that the patient denied consent. Such an audit trail, if desired, would be the client's responsibility.
  • The lookup API checks for a match on these fields: phone, dob, firstName, lastName. The Rx number is optional, and may be incorrect or completely omitted, but will not fail the identity match, provided all the other fields match. If phone, dob, firstName, or lastName fields fail to match, the lookup is not successful. All matches must be exact, with the exception that the firstName and lastName match are not case sensitive. (Otherwise, the firstName and lastName match are also exact.)
  • Even if there is a match, the lookup may fail if the patient's data does not come from a "brand" with which Change Healthcare has the necessary business relationships. We do offer an API to get a list of all our supported brands. You can then compare the patient's brand to our list of supported brands and advise the patient immediately if our system will not generate a corresponding health-card. However, for that solution to work, the patient needs to accurately identify their brand, which may be problematic. So, the results of the lookup might still fail.
  • For security reasons, if the lookup fails, the response body provides no useful data to identify the cause of the failure. Please consider these lookup behaviors when designing your software and creating your UX, if applicable.

$health-cards-issue endpoint

There are 3 variations for the the $health-cards-issue API, as determined by the query parameters. All 3 return the same health card data, but the format is different in each case.

  • /$health-cards-issue (no query parameters)
    • Return JSON per the VCI spec, containing a JWS token which encodes the content of the health-cards
  • /$health-cards-issue?qrnumeric
    • Return an array of qrnumeric values, each representing the content of a single QR code as described by the VCI spec. Note that the number of qrnumeric codes can be more than 1, depending on the size of the payload. For this version of the API, the conversion of each qrnumeric value to a QR code is the client's responsibility. Please be aware that the VCI spec has specific guidelines for the structure of the resulting QR code, for the QR code to be accepted by VCI compliant validator implementations.
  • /$health-cards-issue?qr&type=png/svg
    • Return an array of QR codes as base64 encoded images. The resulting image format may be either PNG or SVG as specified by the type query string value. (The default is PNG.) Note that the number of QR codes generated by a payload can be more than 1, depending on the size of the payload. When using this version of the API, the resulting image file will be fully VCI compliant, saving you the conversion effort of the ?qrnumeric option. You will need only to decode the base64 to the native file format (binary for PNG, XML for SVG)

Each of the 3 variations in health-cards-issue is now described in more detail.

/$health-cards-issue [JSON]

The following Curl shows how to call the $health-cards-issue API to retrieve a VCI credential in JSON format.

curl  -s  -X POST \
    -H "Authorization: Bearer <TOKEN>" \
    -d '<CREDENTIALS_REQUESTED>' \
     'https://sandbox.apis.changehealthcare.com/dataservices/shc/v1/Patient/<PATIENT_ID>/$health-cards-issue'
ParameterDescriptionExample
<TOKEN>Apigee access token obtained from The APIGEE API. Do not forget to indicate that it is a Bearer token as show.See section 'Getting an APIGEE token using the APIGEE API'
<CREDENTIALS_REQUESTED>The credentialTypes being requested for inclusion in the response. Currently only covid-19 is supported, so the example to the right is the actual request body to use in your API calls.{
"resourceType": "Parameters",
"parameter": [{
"name": "credentialType",
"valueUri": "https://smarthealth.cards#covid19"
}]
}
<PATIENT_ID>The patientId returned by the $health-cards-lookup APID5E6AAC1

Upon a successful invocation (status=200) , the application/json returned by this call will be the JSON encapsulating the JWS token containing the requested credentials. It should look similar to the following, where the 'valueString' is the JWS token.

{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "verifiableCredential",
      "valueString": "eyJ6aXAiOiJERUYiLCJraWQiOiJhSEdmR3FEY0FWa1A0cXdOdS15M1poeHFySVJuNWZ0T3dXS1VqM3A4Rk9NIiwiYWxnIjoiRVMyNTYifQ.fZLdb9MwEMD_lep4zUfdMbbmbXQrQohpqFl5QH1w7Wt7yLEj2wmUKf8757RFIE34JfJ9_PK7S16AQoAKDjG2oSpL2VKusS_42RbyR7DOtt7p4oDSxIOSHikWFmMpOVNqGWVA35PCUPaKSm6dlb2ADEhGqMS7mbgW8-sbkYHd7v4N9AqqF4jHFqH6Bmv0tCO5NbjwqNFGkoYxF6_QSB9PEgVb6PDmdMnTBTYZqD9dq277HVVM8N2BPIMDOcszvi2mRVJL0fed1QZTjcfgOq-wHkXgnMjOYqCcMUxLhAz4Bf7ItkzujHn2hgsu_dWUCy6XV8BPMhL3c5GVDZ4gsiHDPFg-Lz8t1-slJ_fUo00LqeuvXxb3H5awGXi8LfH49zImkpjP57kQuZjDMGSvuoj_u3xsms7SL3keK0QZuzAO27QGI2oO9lIpsrhweiQop8nuR-1wDBGb80_D3-Zgbgrn92XaaxlIl6r_yQA1doKAYTNk0J7HH2V26NEms7-3x0VOqc6PqTRqTWlPMJvOprmY5eKWoS36nfMN-tFEquh8QmoKrZFplYvV5OFpNakf7j5fTfLJ7TSdK5ZIWzQuPnbNNnXD412KDXx-Aw.a8jXxiNtiCGXnrqUa0R0gTbWkXmO3mTyRpR2vWc--QBVH5_tV1Vnr7DyD0JJH5XjPQ1lBogYO3ym5pFiQXWSwQ"
    }
  ]
}

After processing the token as explained below, the FHIR bundle will look similar to this. (This bundle was extracted from the token shown above.

{
  "resourceType": "Bundle",
  "type": "collection",
  "entry": [
    {
      "fullUrl": "resource:0",
      "resource": {
        "resourceType": "Patient",
        "name": [
          {
            "family": "FUFKFVVF",
            "given": [
              "TTWQCDGF"
            ]
          }
        ],
        "birthDate": "1999-11-19"
      }
    },
    {
      "fullUrl": "resource:1",
      "resource": {
        "resourceType": "Immunization",
        "status": "completed",
        "vaccineCode": {
          "coding": [
            {
              "system": "http://hl7.org/fhir/sid/cvx",
              "code": "1"
            }
          ]
        },
        "patient": {
          "reference": "resource:0"
        },
        "occurrenceDateTime": "2020-12-18",
        "performer": [
          {
            "actor": {
              "display": "CS EPS TEAM3 - 80000031"
            }
          }
        ],
        "lotNumber": "NA"
      }
    }
  ]
}

API NOTES:

  • Steps to be taken by the API client to validate the token.

Get the latest public keys by calling the jwks API.

Decode the base64URL header to base64.

Decode the base64 header to stringified JSON.

Parse the stringified JSON to get the header JSON.

Verify the token signature. The kid field in the header is the appropriate index to the public key in the JWKS API response.

Decode the base64URL payload to base64.

Convert the base64 payload to a binary buffer.

Inflate the binary buffer to stringified JSON.

Parse the stringified JSON to get the FIHR bundle.

Validate the FIHR bundle.

Extract desired results from FIHR bundle and communicate to patient.

  • The payload is not encrypted, per the VCI spec.
  • Do not decode and process the payload without verifying the signature first. Verifying the signature is NOT optional for obvious reasons.

/$health-cards-issue?qrnumeric [Array of qrnumeric codes]

The following Curl shows how to call the $health-cards-issue?qrnumeric API to retrieve a VCI credential.

curl  -s  -X POST \
    -H "Authorization: Bearer <TOKEN>" \
    -d '<CREDENTIALS_REQUESTED>' \
     'https://sandbox.apis.changehealthcare.com/dataservices/shc/v1/Patient/<PATIENT_ID>/$health-cards-issue?qrnumeric'
ParameterDescriptionExample
<TOKEN>Apigee access token obtained from The APIGEE API. Do not forget to indicate that it is a Bearer token as show.See section 'Getting an APIGEE token using the APIGEE API'
<CREDENTIALS_REQUESTED>The credentialTypes being requested for inclusion in the response. Currently only covid-19 is supported, so the example to the right is the actual request body to use in your API calls.{
"resourceType": "Parameters",
"parameter": [{
"name": "credentialType",
"valueUri": "https://smarthealth.cards#covid19"
}]
}
<PATIENT_ID>The patientId returned by the $health-cards-lookup APID5E6AAC1

Upon a successful invocation (status=200) , the application/json returned by this call will be an array of qrnumeric strings representing the requested credentials. It should look similar to the following, which is the format for a single QR code (1 array element)

["shc:/56762909524320603460292437404460312229695242366034602926366463273923360452263322532332754123596255263607426312383904634452232943556363394404417333773738542437055526086528607460444275652861666037413276333944605736015741313153717074243574414406734174043822297144715556306030216862703432562259116654640575662460216733380958570712381162722660207431113172775808655965662108390540402857360061313556527138604304260677536173100575676541424561417627426921275268362636740867036272565620564352112400717743286857412872114529302107582929123121442572760744381121400010563343622308207227442867365044447134103742733322075538613721544003034504050007380832286129382857052768405961543726656468447709601135766768313626251029556222555864285775314243574031374459301210417667332927655930727006624257545372671108286137276103337334225576326972200338240772364160716042043836595607280462650862106945095429543307730874360725001136350824550560563607360434293175376473595812537709727167724177361168210833392756770057251256571208215372211025423069335077242965444469252826407329002320621005675963104111563772742377750357613953712166237572576772372330073331306240254468547559633405353564217700583567434267126204630676263472724154762550035728592361295939772675590536743171304421377759075564686171505074284528436606236030456156686438603056546830633303385344717253040523537139223753207240626963421104616432730410342567355570110627051064684277050662114107767666597604234412554011417156317631734427343074017035612610673420093644345664605941660958112368683467706839776877610453702022586955664042332538603743544203523155237340631208737423412256052529533526540029087512597303607336"]

API NOTES:

  • The client is responsible for converting each qrnumeric element into a VCI compliant QR code to present to the end user. See the VCI spec for details. Be aware that the format of the array elements are slightly different, depending on the total number of elements in the array. When converting to a VCI compliant QR code, be sure to consult the VCI documentation - as the QR format is enforced by VCI compliant validators.

  • Steps to be taken by the client to validate the QR codes:

Scan each QR code to get the qrnumeric string encoded into the QR.

Verify that the format of each qrnumeric string is consistent with the total number of qrnumeric strings.

Decode the numeric portion of each qrnumeric string. The decoded string is a 'portion' of the JWS.

Assemble the JWS by concatenating the decoded strings IN THE CORRECT ORDER, as indicated by byte portion of each qrnumeric string.

The resulting string is the VCI JWS. So see the API NOTEs for the /$health-cards-issue above for the remaining steps in the validation.

/$health-cards-issue?qr&type=png [Array of base64 encoded QR images in PNG or SVG format]

The following Curl shows how to call the $health-cards-issue?qr API to retrieve a VCI credential.

curl  -s  -X POST \
    -H "Authorization: Bearer <TOKEN>" \
    -d '<CREDENTIALS_REQUESTED>' \
     'https://sandbox.apis.changehealthcare.com/dataservices/shc/v1/Patient/<PATIENT_ID>/$health-cards-issue?qr'
ParameterDescriptionExample
<TOKEN>Apigee access token obtained from The APIGEE API. Do not forget to indicate that it is a Bearer token as show.See section 'Getting an APIGEE token using the APIGEE API'
<CREDENTIALS_REQUESTED>The credentialTypes being requested for inclusion in the response. Currently only covid-19 is supported, so the example to the right is the actual request body to use in your API calls.{
"resourceType": "Parameters",
"parameter": [{
"name": "credentialType",
"valueUri": "https://smarthealth.cards#covid19"
}]
}
<PATIENT_ID>The patientId returned by the $health-cards-lookup APID5E6AAC1

Upon a successful invocation (status=200) , the application/json returned by this call will be an array of base64 strings, each being a PNG image file with QR codes representing the requested credentials. It should look similar to the following.

["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"]

API NOTES:

  • The client can decode the base64 response to the QR image file and display directly to the user. The resulting QR code will be VCI compliant.

  • Both the SVG files (XML) and the PNG files (binary) are base64 encoded in the response.

  • To validate the QR codes, follow the same process as described in the above section on the qrnumeric validation.

Vaccination Credential Verification API

The following Curl shows how to call the $health-cards-validate API to validate VCI credentials in either JSON, SHC, or image (base64) format.

curl  -s  -X POST \
    -H "Authorization: Bearer <TOKEN>" \
    -d '<CREDENTIALS>' \
     'https://sandbox.apis.changehealthcare.com/dataservices/shc/v1/$health-cards-validate'
ParameterDescriptionExample
<TOKEN>Apigee access token obtained from The APIGEE API. Do not forget to indicate that it is a Bearer token as show.See section 'Getting an APIGEE token using the APIGEE API'
<CREDENTIALS>JWS in JSONSee below
Array of SHC stringsSee below
Array of base64 imagesSee below

Format of the CREDENTIALS parameter for the validation API

The can be presented for validation in one of 3 acceptable formats. This API will auto-detect which format is being presented.

JWS in JSON

This form of the validation credentials is the same as the output of the $health-card-issue API. See the following example.

{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "verifiableCredential",
      "valueString": "eyJ6aXAiOiJERUYiLCJraWQiOiJhSEdmR3FEY0FWa1A0cXdOdS15M1poeHFySVJuNWZ0T3dXS1VqM3A4Rk9NIiwiYWxnIjoiRVMyNTYifQ.fZLdb9MwEMD_lep4zUfdMbbmbXQrQohpqFl5QH1w7Wt7yLEj2wmUKf8757RFIE34JfJ9_PK7S16AQoAKDjG2oSpL2VKusS_42RbyR7DOtt7p4oDSxIOSHikWFmMpOVNqGWVA35PCUPaKSm6dlb2ADEhGqMS7mbgW8-sbkYHd7v4N9AqqF4jHFqH6Bmv0tCO5NbjwqNFGkoYxF6_QSB9PEgVb6PDmdMnTBTYZqD9dq277HVVM8N2BPIMDOcszvi2mRVJL0fed1QZTjcfgOq-wHkXgnMjOYqCcMUxLhAz4Bf7ItkzujHn2hgsu_dWUCy6XV8BPMhL3c5GVDZ4gsiHDPFg-Lz8t1-slJ_fUo00LqeuvXxb3H5awGXi8LfH49zImkpjP57kQuZjDMGSvuoj_u3xsms7SL3keK0QZuzAO27QGI2oO9lIpsrhweiQop8nuR-1wDBGb80_D3-Zgbgrn92XaaxlIl6r_yQA1doKAYTNk0J7HH2V26NEms7-3x0VOqc6PqTRqTWlPMJvOprmY5eKWoS36nfMN-tFEquh8QmoKrZFplYvV5OFpNakf7j5fTfLJ7TSdK5ZIWzQuPnbNNnXD412KDXx-Aw.a8jXxiNtiCGXnrqUa0R0gTbWkXmO3mTyRpR2vWc--QBVH5_tV1Vnr7DyD0JJH5XjPQ1lBogYO3ym5pFiQXWSwQ"
    }
  ]
}

Array of SHC strings

This form of the validation credentials is the same as the output of the $health-card-issue?qrnumeric API. See the following example. The array length could be greater than one if the health card QR representation required more than one QR code as specified by the VCI API. All the elements in the array MUST be the same format -- in this case, SHC strings per the VCI spec.

["shc:/56762909524320603460292437404460312229695242366034602926366463273923360452263322532332754123596255263607426312383904634452232943556363394404417333773738542437055526086528607460444275652861666037413276333944605736015741313153717074243574414406734174043822297144715556306030216862703432562259116654640575662460216733380958570712381162722660207431113172775808655965662108390540402857360061313556527138604304260677536173100575676541424561417627426921275268362636740867036272565620564352112400717743286857412872114529302107582929123121442572760744381121400010563343622308207227442867365044447134103742733322075538613721544003034504050007380832286129382857052768405961543726656468447709601135766768313626251029556222555864285775314243574031374459301210417667332927655930727006624257545372671108286137276103337334225576326972200338240772364160716042043836595607280462650862106945095429543307730874360725001136350824550560563607360434293175376473595812537709727167724177361168210833392756770057251256571208215372211025423069335077242965444469252826407329002320621005675963104111563772742377750357613953712166237572576772372330073331306240254468547559633405353564217700583567434267126204630676263472724154762550035728592361295939772675590536743171304421377759075564686171505074284528436606236030456156686438603056546830633303385344717253040523537139223753207240626963421104616432730410342567355570110627051064684277050662114107767666597604234412554011417156317631734427343074017035612610673420093644345664605941660958112368683467706839776877610453702022586955664042332538603743544203523155237340631208737423412256052529533526540029087512597303607336"]

Array of base64 images

This form of the validation credentials is the same as the output of the $health-card-issue?qr API. See the following example. The array length could be greater than one if the health card QR representation required more than one QR code as specified by the VCI API. All the elements in the array MUST be the same format -- in this case, base64.

["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"]

Upon a successful invocation (status=200) , the application/json returned by this call will be a JSON FHIR payload similar to the following example.

{
    "resourceType": "Bundle",
    "type": "collection",
    "entry": [
      {
        "fullUrl": "resource:0",
        "resource": {
          "resourceType": "Patient",
          "name": [
            {
              "family": "Danielle-963",
              "given": [
                "jk_Keeling-576"
              ]
            }
          ],
          "birthDate": "2021-06-22"
        }
      },
      {
        "fullUrl": "resource:1",
        "resource": {
          "resourceType": "Immunization",
          "status": "completed",
          "vaccineCode": {
            "coding": [
              {
                "system": "http://hl7.org/fhir/sid/cvx",
                "code": "207"
              }
            ]
          },
          "patient": {
            "reference": "resource:0"
          },
          "occurrenceDateTime": "2021-06-01",
          "performer": [
            {
              "actor": {
                "display": "CS EPS TEAM3 - 80000031"
              }
            }
          ],
          "lotNumber": "NA"
        }
      }
    ]
  }

jwks.json

The following Curl shows how to call the jwks.json API to get the public keys to validate the VCI tokens you receive using the $health-cards-issue API.

curl  -s  -X GET \
     '<ISSUER>/.well-known/jwks.json'

Upon a successful invocation (status=200) , the JSON returned by this call will look similar to this:

ParameterDescriptionExample
<ISSUER>The issuer URL as supplied by the 'iss' field in the JWS token payload.https://sandbox.apis.changehealthcare.com/anon/dataservices/shc/v1/albertsons
{"keys":[{"kty":"EC","crv":"P-256","x":"ezCvfr1h-LAC44ZA3BvFgRBL_JmQe6Got1o9R2XjX8k","y":"0nVmoFIFlp7n8arl6jHnxxxwbAoQHJwe8T9hs47e8do","kid":"_0jpa2GxEKjH-ApJKev2QGHMK7Ch4jL1ZMyMohiYNag","use":"sig","alg":"ES256"}]}

API Notes:

  • You will not need to call this API directly if you are using the Vaccine Credential Verification APIs provided by Change Healthcare. This is because the Verification API reads the issuer from the JWS token and calls the JWKS endpoint internally.

  • Take note of the 'anon' token (following the host name) in the URI for this API. It is NOT present in the other Vaccination Credential APIs. This is because Change Healthcare requires the 'anon' token in any unsecured API.

  • Per the JWKS spec, this API is not secured. No APIGEE token is required.

  • The 'iss' field is a top level property in the token payload. You will have to decode the payload, obtain the issuer, and then call the JWKS endpoint to retrieve the public signing key - then you may verify the signature. Note that the payload is compressed base64URL format, but not encrypted, as per the VCI spec.

  • The public keys change rarely. In fact, the spec states that updating once/year is acceptable. Therefore, you can adopt one of two basic scenarios for calling this API.

Update rarely: Syncing to a date when Change Healthcare notifies you of an upcoming refresh

Call each time you verify: Because of the low overhead of this call, and the nuisance of remembering to call an API on rare notifications, simply call the API every time you verify a token.

{"keys":[{"kty":"EC","crv":"P-256","x":"ezCvfr1h-LAC44ZA3BvFgRBL_JmQe6Got1o9R2XjX8k","y":"0nVmoFIFlp7n8arl6jHnxxxwbAoQHJwe8T9hs47e8do","kid":"_0jpa2GxEKjH-ApJKev2QGHMK7Ch4jL1ZMyMohiYNag","use":"sig","alg":"ES256"}]}

Testable patient profiles for $health-cards-lookup API

The following combination of patient identification data can be used in the $health-cards-lookup API to successfully return a patienId. Try any combination of data NOT in the table below to explore non-success scenarios.

Payload #$health-cards-lookup payloadAlternate rxNumber (addtl doses)# of QR codes generated
1{
"phone": "8110000800",
"firstName": "John",
"lastName": "Doe",
"rxNumber": "99000800",
"dob": "19990101",
"consent": true
}
99000900
99001000
1
2{
"phone": "8110000801",
"firstName": "Jane",
"lastName": "Doe",
"rxNumber": "99000801",
"dob": "19990101",
"consent": true
}
990009011
3{
"phone": "8110000803",
"firstName": "Richard",
"lastName": "Roe",
"rxNumber": "99000803",
"dob": "19990101",
"consent": true
}
990009031
4{
"phone": "8110000804",
"firstName": "Ordinary",
"lastName": "Joe",
"rxNumber": "99000804",
"dob": "19990101",
"consent": true
}
990009041
5{
"phone": "8110000805",
"firstName": "Average",
"lastName": "Joe",
"rxNumber": "99000805",
"dob": "19990101",
"consent": true
}
1
6{
"phone": "8110000806",
"firstName": "Joe",
"lastName": "Sixpack",
"rxNumber": "99000806",
"dob": "19990101",
"consent": true
}
1
7{
"phone": "8110000807",
"firstName": "John",
"lastName": "Public",
"rxNumber": "99000907",
"dob": "19990101",
"consent": true
}
990011071
8{
"phone": "880-555-4444",
"firstName": "testmultiple",
"lastName": "qrcodes",
"rxNumber": "6000538",
"dob": "2006-06-06",
"consent": true
}
N/A2

Sample BASH script for calling VCI APIs Integrations

Script Notes:

  • Script was tested on MAC Catalina
  • Copy script below and the desired identity payload file to your computer. The identity payload can be selected from the Testable Patient Profiles.
  • jq must be installed for this script to work. https://github.com/stedolan/jq/wiki/Installation
  • Invoke script with 3 parameters: clientId clientSecret relative-path-from-this-script-to-identity-json-file
#!/bin/bash
SCRIPT_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)

clientId=$1
clientSecret=$2
IDENTITY_FILE=$3
host=sandbox.apis.changehealthcare.com





echo "-------------------------------- get the apigee token -----------------------------------------"

TOKEN=$(curl -s -X POST  \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d "client_id=$clientId&client_secret=$clientSecret&grant_type=client_credentials" \
https://$host/apip/auth/v2/token | jq -r .access_token)


echo "TOKEN=$TOKEN"


echo "---------------------------------jwks.json --------------------------------------------"

# No token required
curl  -s  -X GET \
     https://$host/anon/dataservices/shc/v1/healthchain/.well-known/jwks.json

echo ""

echo "--------------------------------- \$health-cards-lookup---------------------------------------------"



PATIENT_ID=$(curl -s -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -d @$SCRIPT_DIR/$IDENTITY_FILE \
    'https://'$host'/dataservices/shc/v1/$health-cards-lookup')



# check that the return value is length 8  (
if [[  ${#PATIENT_ID} != 8 ]]; then
  echo "$PATIENT_ID is not a valid patientId"
  echo ""
  exit 100
else
  echo $PATIENT_ID
fi

echo ""

echo "---------------------------------\$health-cards-issue---------------------------------------------"


curl  -s  -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -d '{"resourceType": "Parameters",  "parameter": [{  "name": "credentialType", "valueUri": "https://smarthealth.cards#covid19" }] }' \
     'https://'$host'/dataservices/shc/v1/Patient/'"$PATIENT_ID"'/$health-cards-issue' | jq .




echo "--------------------------------- \$health-cards-validate (jws) ---------------------------------------------"
curl  -s  -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -d '{"resourceType": "Parameters",  "parameter": [{  "name": "credentialType", "valueUri": "https://smarthealth.cards#covid19" }] }' \
     'https://'$host'/dataservices/shc/v1/Patient/'"$PATIENT_ID"'/$health-cards-issue' \
     | sed 's/"/\\"/g' \
     | xargs  -J '{}' \
        curl  -s  -X POST \
        -H "Authorization: Bearer $TOKEN" \
        -d '{}' \
        'https://'$host'/dataservices/shc/v1/$health-cards-validate'

echo ""






echo "--------------------------------- \$health-cards-issue?qrnumeric' ---------------------------------------------"

curl  -s  -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -d '{"resourceType": "Parameters",  "parameter": [{  "name": "credentialType", "valueUri": "https://smarthealth.cards#covid19" }] }' \
     'https://'$host'/dataservices/shc/v1/Patient/'"$PATIENT_ID"'/$health-cards-issue?qrnumeric'

echo ""
echo "--------------------------------- \$health-cards-validate  (qrnumeric) ---------------------------------------------"
curl  -s  -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -d '{"resourceType": "Parameters",  "parameter": [{  "name": "credentialType", "valueUri": "https://smarthealth.cards#covid19" }] }' \
     'https://'$host'/dataservices/shc/v1/Patient/'"$PATIENT_ID"'/$health-cards-issue?qrnumeric' \
     | sed 's/"/\\"/g' \
     | xargs  -J '{}' \
        curl  -s  -X POST \
        -H "Authorization: Bearer $TOKEN" \
        -d '{}' \
        'https://'$host'/dataservices/shc/v1/$health-cards-validate'

echo ""


echo ""
echo "--------------------------------- \$health-cards-issue?qr---------------------------------------------"

curl  -s  -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -d '{"resourceType": "Parameters",  "parameter": [{  "name": "credentialType", "valueUri": "https://smarthealth.cards#covid19" }] }' \
     'https://'$host'/dataservices/shc/v1/Patient/'"$PATIENT_ID"'/$health-cards-issue?qr'



echo ""

echo "--------------------------------- \$health-cards-validate  (qr)---------------------------------------------"
curl  -s  -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -d '{"resourceType": "Parameters",  "parameter": [{  "name": "credentialType", "valueUri": "https://smarthealth.cards#covid19" }] }' \
     'https://'$host'/dataservices/shc/v1/Patient/'"$PATIENT_ID"'/$health-cards-issue?qr' \
     | sed 's/"/\\"/g' \
     | xargs  -J '{}' \
        curl  -s  -X POST \
        -H "Authorization: Bearer $TOKEN" \
        -d '{}' \
        'https://'$host'/dataservices/shc/v1/$health-cards-validate'

echo ""

Using the Microsoft SDK as a Boilerplate for Client

IMPORTANT: The Microsoft SDK is an open source effort by the VCI Working Group. The SDK can be used as a token validator, and as a 'boilerplate' for your client side implementation for token validation and parsing. Keep in mind that this software is not supported or owned by Change HealthCare. If you have questions or issues about its use, we can provide limited support only.

Th Microsoft SDK repo can be found in GIT. Please consult the repository's README page for detailed information on its installation and use.

Other References

These are reference to underlying standards and specs in the VCI specification. Fortunately, almost all development environments/languages have excellent support through native libraries or third party libraries. Therefore, the actual implementation is much less challenging than reading the specs!

NameLinkSummary
Fast Health Interoperability Resources (FHIR)https://hl7.org/fhir/Standards for FIHR and other electronic health information
DEFLATE Compressionhttps://tools.ietf.org/html/rfc1951Compression algorithm specified in VCI spec for FIHRpayload
JSON Web Token (JWT)https://tools.ietf.org/html/rfc7519Specification for compliant tokens generated per the VCI spec.
JSON Web Key (JWK)https://tools.ietf.org/html/rfc7517Specification for jwks file and related technologies
JSON Web Key (JWK) Thumbprinthttps://tools.ietf.org/html/rfc7638JSON web key thumbprint specification. Used for 'kid' in JWKS file

JSON Web Token (JWT): https://tools.ietf.org/html/rfc7519
JSON Web Key (JWK): https://tools.ietf.org/html/rfc7517
JSON Web Key (JWK) Thumbprint: https://tools.ietf.org/html/rfc7638

The following references are mentioned elsewhere in this page - they are repeated here for completeness.

NameLinkSummary
JQhttps://github.com/stedolan/jq/wiki/InstallationJSON parser used in example Curl scripts
Microsoft Health Cards Validation SDKhttps://github.com/microsoft/health-cards-validation-SDK.gitTool to validate VCI compliant tokens and payloads
SmartHealth Cardshttps://smarthealth.cardsImplementation guide for VCI compliant health-cards
Release Notes
View our Change Log/Release Notes for more information on the API