Overview
The digital vaccination record ecosystem has three components:
- Certified Issuers: Entities that are the source of verifiable vaccination data, for example, vaccination sites, pharmacies, hospitals, registries, and so on, 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, Optum (formerly, 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: Optum’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: Optum’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 Optum. VCI is working to define a set of standards to enable the secure issue, exchange, and verification of vaccination credentials. Optum’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 Optum 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
For this API, Optum 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 user interface (UI).
NOTE
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 Optum's environments (sandbox and production). You can integrate your application with masked data in our sandbox environment. The production environment serves live data based on your customer agreement with Optum.
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.
Environment | Host |
---|---|
Sandbox | sandbox.apigw.changehealthcare.com |
Production | apigw.changehealthcare.com |
Before you can use the Sharing or Verification APIs in any environment, you will need to obtain an APIGEE client_id
and client_secret
to call our secure APIs. The same APIGEE client_id
and client_secret
cannot be used across different environments. You will require a separate client_id
and client_secret
for the sandbox and production environments.
If you need assistance obtaining client APIGEE client_id
and client_secret
, 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 client_id
and client_secret
. The following Curl shows how to obtain an APIGEE token using 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.apigw.changehealthcare.com/apip/auth/v2/token
Parameter | Description | Example |
---|---|---|
CLIENT_ID | The APIGEE client_id you will receive when you register with Optum. This value should be protected like any other credential. | 3K8YenXcRPou5SpAITuwTr2pQZxAHMVW |
CLIENT_SECRET | The APIGEE client_secret you will receive when you register with Optum. 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
}
BEARER TOKEN LIFESPAN
The lifespan of a Bearer token is one hour (3600 seconds) for both sandbox and production environments.
The token has a 60-minute (one hour) 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 token 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
endpoint to obtain an opaque, short-livedpatientId
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
endpoint 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
endpoint 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.apigw.changehealthcare.com/dataservices/shc/v1/$health-cards-lookup'
Parameter | Description | Example |
---|---|---|
<TOKEN | APIGEE access token obtained from The APIGEE API. Do not forget to indicate that it is a bearer token as shown. | See |
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
Field | Type | Description | |
---|---|---|---|
phone | string | 10-digit phone number as recorded in pharmacy record, dash delimited as shown | Required |
firstName | string | Patient's first name as recorded in pharmacy record, case-insensitive. | Required |
lastName | string | Patient's last name as recorded in pharmacy record, case-insensitive. | Required |
rxNumber | string | Prescription number as recorded in pharmacy record. | Optional |
dob | string | Date of birth as recorded in pharmacy record in yyyymmdd format. | Required |
consent | boolean | Patient'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
endpoint. 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
endpoint. 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
endpoint 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 three variations for the the $health-cards-issue
endpoint as determined by the query parameters. All three 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 greater 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 greater 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 three 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.apigw.changehealthcare.com/dataservices/shc/v1/Patient/<PATIENT_ID>/$health-cards-issue'
Parameter | Description | Example |
---|---|---|
<TOKEN | Apigee access token obtained from The APIGEE API. Do not forget to indicate that it is a Bearer token as show. | See |
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 API | D5E6AAC1 |
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 for the API client to validate the token:
- Get the latest public keys by calling the
jwks
endpoint. - 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
endpoint 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 as 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.apigw.changehealthcare.com/dataservices/shc/v1/Patient/<PATIENT_ID>/$health-cards-issue?qrnumeric'
Parameter | Description | Example |
---|---|---|
<TOKEN | Apigee access token obtained from The APIGEE API. Do not forget to indicate that it is a Bearer token as show. | See |
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 API | D5E6AAC1 |
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 for 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 NOTE 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.apigw.changehealthcare.com/dataservices/shc/v1/Patient/<PATIENT_ID>/$health-cards-issue?qr'
Parameter | Description | Example |
---|---|---|
<TOKEN | Apigee access token obtained from The APIGEE API. Do not forget to indicate that it is a Bearer token as show. | See |
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 API. | D5E6AAC1 |
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
endpoint to validate VCI credentials in either JSON, SHC, or image (base64) format.
curl -s -X POST \
-H "Authorization: Bearer <TOKEN>" \
-d '<CREDENTIALS>' \
'https://sandbox.apigw.changehealthcare.com/dataservices/shc/v1/$health-cards-validate'
Parameter | Description | Example |
---|---|---|
<TOKEN | Apigee access token obtained from The APIGEE API. Do not forget to indicate that it is a Bearer token as show. | See |
<CREDENTIALS | JWS in JSON | See below |
Array of SHC strings | See below | |
Array of base64 images | See below |
Format of the CREDENTIALS parameter for the validation API
The can be presented for validation in one of three acceptable formats. This API will auto-detect the format being presented.
JWS in JSON
This form of the validation credentials is the same as the output of the $health-card-issue
endpoint. 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
endpoint. 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
endpoint. 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
endpoint to get the public keys to validate the VCI tokens you receive using the $health-cards-issue
endpoint.
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:
{"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 Optum. 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 Optum 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 in the 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 Optum 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
endpoint to successfully return a patienId. Try any combination of data NOT in the table below to explore non-success scenarios.
Payload # | $health-cards-lookup payload | Alternate 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 } | 99000901 | 1 |
3 | { "phone": "8110000803", "firstName": "Richard", "lastName": "Roe", "rxNumber": "99000803", "dob": "19990101", "consent": true } | 99000903 | 1 |
4 | { "phone": "8110000804", "firstName": "Ordinary", "lastName": "Joe", "rxNumber": "99000804", "dob": "19990101", "consent": true } | 99000904 | 1 |
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 } | 99001107 | 1 |
8 | { "phone": "880-555-4444", "firstName": "testmultiple", "lastName": "qrcodes", "rxNumber": "6000538", "dob": "2006-06-06", "consent": true } | N/A | 2 |
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 three 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.apigw.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. Be aware that this software is not supported or owned by Optum. If you have questions or issues about its use, we can provide limited support only.
The 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 references 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!
Name | Link | Summary |
---|---|---|
Fast Health Interoperability Resources (FHIR) | https://hl7.org/fhir/ | Standards for FIHR and other electronic health information. |
DEFLATE Compression | https://tools.ietf.org/html/rfc1951 | Compression algorithm specified in VCI spec for FIHRpayload. |
JSON Web Token (JWT) | https://tools.ietf.org/html/rfc7519 | Specification for compliant tokens generated per the VCI spec. |
JSON Web Key (JWK) | https://tools.ietf.org/html/rfc7517 | Specification for jwks file and related technologies. |
JSON Web Key (JWK) Thumbprint | https://tools.ietf.org/html/rfc7638 | JSON 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.
Name | Link | Summary |
---|---|---|
JQ | https://github.com/stedolan/jq/wiki/Installation | JSON parser used in example Curl scripts. |
Microsoft Health Cards Validation SDK | https://github.com/microsoft/health-cards-validation-SDK.git | Tool to validate VCI compliant tokens and payloads. |
SmartHealth Cards | https://smarthealth.cards | Implementation guide for VCI compliant health-cards. |
Release Notes |
---|
View our Change Log/Release Notes for more information on the API |