Data at the Point of Care Accessing and Working with the API
Guidance for Blue Button Data at the Point of Care Accessing and Working with the API
Issued by: Centers for Medicare & Medicaid Services (CMS)
Issue Date: June 01, 2012
Reference
Information on accessing and working with the API
As patients move throughout the healthcare system, providers often struggle to gain and maintain a complete picture of their medical history. The Data at the Point of Care (DPC) pilot project fills in the gaps with claims data to inform providers with structured patient history, past procedures, medication adherence, and more. This data is made available through a set of FHIR compliant APIs.
This guide serves as a starting point for users to begin working with the API by introducing the core APIs as well as two key concepts of Bulk Data and Patient Attribution.
Documentation is also available in a comprehensive OpenAPI format as well as a FHIR implementation guide.
Bulk Data
This project provides an implementation of the FHIR Bulk Data Access specification, which provides an async interface over the existing Blue Button 2.0 data model. Details on the Blue Button data model can be found on its project page.
This project will closely track changes in the underlying standard and is fully compliant with the current specification, with the following limitations:
- Type filters are not supported
- The _since parameter is not currently supported.
- Only Group level exporting is supported, not Patient or System level exports
In addition, the only available resource types are those exposed by Blue Button which include:
Attribution
In order to receive data from the DPC application, a healthcare provider must have a treatment related purpose for viewing a patient’s claims history. Providers can attest to their treatment purposes by submitting a an attribution roster which lists the patients currently under their care.
In order for a provider to establish a treatment related purpose for viewing patient data, they must fulfill one of the following conditions:
- Have an existing treatment relationship, defined as a visit or processed claim for the given patient with the provider’s National Provider Identity (NPI) number within the past 18 months.
- Have an upcoming appointment for the given patient within 10 days.
If neither of these conditions are met, a treatment relationship cannot be established and the provider is is NOT authorized to retrieve claims data. With each roster addition or renewal, the provider is attesting that there is an active treatment relationship that creates a need for the data being requested.
Given that existing standards for patient rosters do not exist, CMS is currently piloting an implementation of the Attribution Guide currently under discussion with the SMART-ON-FHIR team. The goal is to provide feedback to the group on experiences related to implementation and supporting the recommendations.
Note: The attribution logic and interaction flow will be subject to revision over time. CMS welcomes feedback on the implementation as well as experiences with other systems.
Specific details on creating and updating treatment rosters is given in a later section.
Providers are required to keep their treatment rosters up to date, as patient attributions automatically expire after 90 days. If an attribution expires, the provider may resubmit the patient to their roster and re-attest to a treatment purpose for another 90 days.
CMS currently restricts individual providers to no more than 5,000 attributed patients. These restrictions are subject to change over time.
Authentication and Authorization
The Data at the Point of Care pilot project is currently accessible as a private sandbox environment, which returns sample NDJSON files with synthetic beneficiary data. There is no beneficiary PII or PHI in the files you can access via the sandbox.
DPC implements the SMART Backend Services Authentication (BSA) as described by the SMART ON FHIR team. This specification requires the user to exchange their DPC provided client_token for an access_token which can be used to make API requests to the FHIR endpoints. This exchange requires the user to submit a self-signed JSON Web Token using a public/private key pair that they submit to DPC either via the Web UI or the API.
Note: Authentication is performed on a per-environment basis. Users will need to request a client_token and upload a public key for each environment they wish to access (e.g. sandbox, production, etc).
The access_token is then set as a Bearer token in the Authorization header for each API request.
Authorization: Bearer {access_token}cURL command
curl -H 'Authorization: Bearer {access_token}' {command to execute}The authorization flow is as follows:
- The user first submits a public key to DPC for the given environment. This can be done either through the Web UI or via the PublicKey endpoint in the API.
Note: Because the PublicKey endpoint is secured by BSA, the initial public key for each environment must be uploaded via the Web UI. Any additional keys can then be submitted via the API endpoints, using an existing key for signing the JWT.
-
The user creates a client_token to use for a given application.
-
For each API request, the user creates an access_token by submitting a self-signed JWT to the /Token/auth endpoint.
-
The user sets the provided access_token as a Bearer token in the Authorization header, for each request to the DPC API
Managing client_tokens
Client tokens are required in order to provide the ability for a given application to access the DPC API. Details on how to create an access_token from a given client_token are given in a later section.
Listing client_tokens
All client tokens registered by the organization for a given environment can be listed by making a GET request to the /Token endpoint. This will return an array of objects which list the token ID, when it was created, when it expires, and the label associated with the token.
GET /api/v1/TokencURL command
curl -v https://sandbox.dpc.cms.gov/api/v1/Token \ -H 'Authorization: Bearer {access_token}' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -X GETResponse
{ "created_at": "2019-11-04T11:49:55.126-05:00", "count": 3, "entities": [ { "id": "3c308f6e-0223-42f8-80c2-cab242d68afc", "tokenType": "MACAROON", "label": "Token for organization 46ac7ad6-7487-4dd0-baa0-6e2c8cae76a0.", "createdAt": "2019-11-04T11:49:55.126-05:00", "expiresAt": "2020-11-04T11:49:55.095-05:00" }, { "id": "eef87627-db4b-4c08-8a27-e88a8343099d", "tokenType": "MACAROON", "label": "Token for organization 46ac7ad6-7487-4dd0-baa0-6e2c8cae76a0.", "createdAt": "2019-11-04T11:50:06.101-05:00", "expiresAt": "2020-11-04T11:50:06.096-05:00" }, { "id": "ea314eaa-1cf5-4d01-9ea7-1646099ca9fd", "tokenType": "MACAROON", "label": "Token for organization 46ac7ad6-7487-4dd0-baa0-6e2c8cae76a0.", "createdAt": "2019-11-04T11:50:06.685-05:00", "expiresAt": "2020-11-04T11:50:06.677-05:00" } ] }Specific client_tokens can be listed by making a GET request to the /Token endpoint using the unique id of the client_token.
GET /api/v1/Token/{client_token id}cURL command
curl -v https://sandbox.dpc.cms.gov/api/v1/Token/{client_token id} \ -H 'Authorization: Bearer {access_token}' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -X GETResponse
{ "id": "3c308f6e-0223-42f8-80c2-cab242d68afc", "tokenType": "MACAROON", "label": "Token for organization 46ac7ad6-7487-4dd0-baa0-6e2c8cae76a0.", "createdAt": "2019-11-04T11:49:55.126-05:00", "expiresAt": "2020-11-04T11:49:55.095-05:00" }Creating a client_token
Creating a client_token can be done by making a POST request to the /Token endpoint. This endpoint accepts two, optional query params:
-
label sets a human readable label for the token. If omitted, DPC will auto-generate one. Note, token labels are not guaranteed to be unique.
-
expiration sets a custom expiration for the client_token. This is provided as an ISO formatted string and if omitted will default to the system specified expiration time.
Note: The user cannot set an expiration time longer than the system allowed maximum, which is currently five minutes. This will result in an error being returned to the user.
The response from the API includes the client_token in the token field.
POST /api/v1/TokenNote: This is the only time that the client token will be visible to user. Ensure that the value is recorded in a safe and durable location.
cURL command
curl -v https://sandbox.dpc.cms.gov/api/v1/Token?label={token label}&expiration={ISO formatted dateTime} \ -H 'Authorization: Bearer {access_token}' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -X POSTResponse
{ "id": "3c308f6e-0223-42f8-80c2-cab242d68afc", "tokenType": "MACAROON", "label": "Token for organization 46ac7ad6-7487-4dd0-baa0-6e2c8cae76a0.", "createdAt": "2019-11-04T11:49:55.126-05:00", "expiresAt": "2020-11-04T11:49:55.095-05:00", "token:": "{client_token}" }Deleting a client_token
Client tokens can be removed by sending a DELETE request to the /Token endpoint, using the unique ID of the client_token, which is returned either on creation, or as the result of listing the client_tokens.
DELETE /api/v1/Token/{client_token id}cURL command
curl -v https://sandbox.dpc.cms.gov/api/v1/Token/{client_token id} \ -H 'Authorization: Bearer {access_token}' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -X DELETEResponse
200 - Token was removedManaging public keys
Creating an access_token from a given client_token requires that the user to submit a self-signed JWT with the specific request information (details are given in a later section). In order for DPC to validate that the token request is coming from an authorized application, it verifies that the private key used to sign the JWT matches a public key previously uploaded to the system. Users are required to maintain a list of acceptable public keys with the DPC system and management operations are described in this section.
Note: There is no direct correlation between the number of client_tokens an organization has and the number of public/private key pairs. A keypair can be used to sign any number of client_tokens.
Listing public keys
All public keys registered by the organization for the given endpoint can be listed by making a GET request to the /Key endpoint. This will return an array of objects which list the public key ID, the human readable label, creation time and the PEM encoded value of the public key
GET /api/v1/KeycURL command
curl -v http://localhost:3002/v1/Key \ -H 'Authorization: Bearer {access_token}' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -X GETResponse
{ "created_at": "2019-11-04T13:16:29.008-05:00", "count": 1, "entities": [ { "id": "b296f9d2-1aae-4c59-b6c7-c759b9db5226", "publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmyI+y8vAAFcV4deNdyKC\nH16ZPU7tgwnUzvtEYOp6s0DFjzgaqWmYZd/CNlb1psi+J0ChtcL9+Cx3v+HwDqVx\nToQrEqJ8hMavtXnxm2jPoRaxmbIGjHZ6jfyMot5+CdP8Vr5o9G2WIUgzjhFwMEXh\nlYg97uZadLLVKVXYTl4HtluVX5y7p1Wh4vkyJFBiqrX7qAJXvr6PK7OUeZDeVsse\nOMm33VwgbQSGRw7yWNOw+H/RbpGQkAUtHvGYvo/qLeb+iJsF2zBtjnkTmk5I8Vlo\n4xzbqaoqZqsHp4NgCw+bq0Y6AWLE2yUYi/DOatOdIBfLxlpf/FAY3f5FbNjISUuL\nmwIDAQAB\n-----END PUBLIC KEY-----\n", "createdAt": "2019-11-04T13:16:29.008-05:00", "label": "test-key" } ] }Specific public keys can be listed by making a GET request to the /Key endpoint using the unique id of the public key.
GET /api/v1/Key/{public key id}cURL command
curl -v https://sandbox.dpc.cms.gov/api/v1/Key/{public key id} \ -H 'Authorization: Bearer {access_token}' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -X GETResponse
{ "id": "b296f9d2-1aae-4c59-b6c7-c759b9db5226", "publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmyI+y8vAAFcV4deNdyKC\nH16ZPU7tgwnUzvtEYOp6s0DFjzgaqWmYZd/CNlb1psi+J0ChtcL9+Cx3v+HwDqVx\nToQrEqJ8hMavtXnxm2jPoRaxmbIGjHZ6jfyMot5+CdP8Vr5o9G2WIUgzjhFwMEXh\nlYg97uZadLLVKVXYTl4HtluVX5y7p1Wh4vkyJFBiqrX7qAJXvr6PK7OUeZDeVsse\nOMm33VwgbQSGRw7yWNOw+H/RbpGQkAUtHvGYvo/qLeb+iJsF2zBtjnkTmk5I8Vlo\n4xzbqaoqZqsHp4NgCw+bq0Y6AWLE2yUYi/DOatOdIBfLxlpf/FAY3f5FbNjISUuL\nmwIDAQAB\n-----END PUBLIC KEY-----\n", "createdAt": "2019-11-04T13:16:29.008-05:00", "label": "test-key" }Uploading a public key
Uploading a public key can be done by making a POST request to the /Key endpoint. This endpoint requires one additional query param:
- label sets a human readable label for the public key (this must be less than 26 characters long).
The submitted public key must be unique to each environment and meet the following requirements:
- PEM encoded
- Be an RSA key with a minimum length of at least 4096 bits.
- Or, be an ECC key with one of the following curves:
- secp256r1
- secp384r1
cURL command
curl -v https://sandbox.dpc.cms.gov/api/v1/Key?label={key label} \ -H 'Authorization: Bearer {access_token}' \ -H 'Accept: application/json' \ -H 'Content-Type: text/plain' \ -X POST \ -d "{PEM encoded public key}"Response
{ "id": "b296f9d2-1aae-4c59-b6c7-c759b9db5226", "publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmyI+y8vAAFcV4deNdyKC\nH16ZPU7tgwnUzvtEYOp6s0DFjzgaqWmYZd/CNlb1psi+J0ChtcL9+Cx3v+HwDqVx\nToQrEqJ8hMavtXnxm2jPoRaxmbIGjHZ6jfyMot5+CdP8Vr5o9G2WIUgzjhFwMEXh\nlYg97uZadLLVKVXYTl4HtluVX5y7p1Wh4vkyJFBiqrX7qAJXvr6PK7OUeZDeVsse\nOMm33VwgbQSGRw7yWNOw+H/RbpGQkAUtHvGYvo/qLeb+iJsF2zBtjnkTmk5I8Vlo\n4xzbqaoqZqsHp4NgCw+bq0Y6AWLE2yUYi/DOatOdIBfLxlpf/FAY3f5FbNjISUuL\nmwIDAQAB\n-----END PUBLIC KEY-----\n", "createdAt": "2019-11-04T13:16:29.008-05:00", "label": "test-key" }The id field of the response will be used as the kid JWT header value, as described in a later section
Deleting a public key
Public keys can be removed by sending a DELETE request to the /Key endpoint, using the unique ID of the public key, which is returned either on creation, or as the result of listing the public keys.
DELETE /api/v1/Key/{public key ID}cURL command
curl -v https://sandbox.dpc.cms.gov/api/v1/Key/{public key id} \ -H 'Authorization: Bearer {access_token}' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -X DELETEResponse
200 - Key was removedCreating an access_token
Creating an access_token for API access requires the user to submit a self-signed JWT to the /Token/auth endpoint. This token must be signed with a public key previously registered and contain the following header and claim values:
Authentication JWT Header Values
alg required - Fixed value: RS384
kid required - The identifier of the key-pair used to sign this JWT. This must be the ID of a previously registered public key
typ required - Fixed value: JWT.
Authentication JWT Claims
iss required Issuer of the JWT – the client_token provided by DPC
sub required Issuer of the JWT – the client_token provided by DPC (note that this is the same as the value for the iss claim)
aud required The DPC “token URL” (the same URL to which this authentication JWT will be posted. e.g. https://dpc.cms.gov/api/v1/Token/auth)
exp required Expiration time integer for this authentication JWT, expressed in seconds since the “Epoch” (1970-01-01T00:00:00Z UTC). This time SHALL be no more than five minutes in the future.
jti required A nonce string value that uniquely identifies this authentication JWT.
Creating a JSON Web Token (JWT)
JWT.io provides comprehensive information about what JSON Web Tokens are and how to use them. For testing purposes, the site offers a debugger that allows you to enter a header, payload, and keys to generate a signed JWT.
Online tools for creating JWTs should not be considered secure and should not be used to create tokens to access production data. Instead, use one of the libraries listed on JWT.io to generate JWTs in your DPC API client.
JWT for testing in the sandbox
For the DPC sandbox environment, which contains no PII or PHI, a JWT can be created with the JWT.io debugger. More details on each field can be found under Authentication JWT Header Values and Authentication JWT Claims. 1. From the Algorithm dropdown, select RS384. 1. On the “Decoded” side, the “Header: Algorithm & Token Type” text area must contain a JSON object with the fields below. alg and typ will already be set, so you will need to add kid. 1. "alg": "RS384" (set for you after you select the algorithm) 1. "kid": "{ID of public key}" 1. "typ": "JWT" (set by default) 1. The “Payload: Data” text area must contain a JSON object with the fields below. It will already contain sub, name, admin, and iat. The value of sub will change, and name, admin, and iat should be removed. 1. "iss": "{client token}" 1. "sub": "{client token}" 1. "aud": "https://sandbox.dpc.cms.gov/api/v1/Token/auth" 1. "exp": "{expiration time}" 1. "jti": "{nonce}" 1. Under “Verify Signature”, the first text area should contain your public key, and the second, your private key. This keypair should be for testing in the sandbox, not one that is used to access any production data.
JWT for production use
JWT.io’s debugger should not be used to create tokens for accessing the production environment. JWTs can be created by your DPC client using one of the many JWT libraries in a variety of programming languages. For example, Auth0 has created a Java library, and its README shows you how to implement it to create your own tokens.
Validating a DPC token
The DPC API supports a /Token/validate endpoint, which allows the user to submit their signed JWT for validation. This will return an error message with details as to which claims or values on the JWT are missing or incorrect. This method DOES NOT validate the JWT signature, public key or client tokens, it merely verifies the necessary elements are present in the JWT entity.
POST /api/v1/Token/validatecURL command
curl -v https://sandbox.dpc.cms.gov/api/v1/Token/validate \ -H 'Accept: application/json' \ -H 'Content-Type: text/plain' \ -X POST \ -d "{Signed JWT}"In order to receive an access_token the JWT is submitted to the /Token/auth endpoint as the client_assertion form param of an application/x-www-form-urlencoded POST request, along with the following, additional, form params:
Parameters
scope required The scope of access requested. (Currently, the only supported scope is system/*.*)
grant_type required Fixed value: client_credentials
client_assertion_type required Fixed value: urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertion required Signed authentication JWT value (see above)
The endpoint response is a JSON object which contains the access_token, the lifetime of the token (in seconds) and the authorized system scopes.
POST /api/v1/Token/authcURL command
curl -v "https://sandbox.dpc.cms.gov/api/v1/Token/auth" \ -H 'Content-Type: application/x-www-form-urlencoded' \ -H 'Accept: application/json' \ -X POST -d "grant_type=client_credentials&scope=system%2F*.*&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion={self-signed JWT}"Response
{ "access_token": "{access_token value}", "token_type": "bearer", "expires_in": 300, "scope": "system/*.*" }Environment
The examples below include cURL commands, but may be followed using any tool that can make HTTP GET requests with headers, such as Postman.
Note: DPC sandbox environments do not have any test data loaded. Users will need to provide their own FHIR resources in order to use the Sandbox. Details on finding sample data is given in a later section.
Examples
Examples are shown as requests to the DPC sandbox environment. Any resource Identifiers that are show are merely examples and cannot be used as actual requests to the DPC sandbox.
Be sure to include the CMS generated Access token in the requests, as documented in the Authorization section.
DPC Metadata
Metadata about the Data at the Point of Care (DPC) pilot project is available as a FHIR CapabilityStatement resource.
GET /api/v1/metadatacURL command
curl https://sandbox.dpc.cms.gov/api/v1/metadataResponse
{ "resourceType": "CapabilityStatement", "description": "This Capability Statement defines the available resource, endpoints and operations supported by the Data @ the Point of Care Application.", "id": "dpc-capabilities", "version": "0.3.0-SNAPSHOT", "status": "draft", "date": "2019", "publisher": "Centers for Medicare and Medicaid Services", "kind": "capability", "instantiates": [ "http://build.fhir.org/ig/HL7/bulk-data/CapabilityStatement-bulk-data" ], "software": { "name": "Data @ Point of Care API", "version": "0.3.0-SNAPSHOT", "releaseDate": "2019" }, "fhirVersion": "3.0.1", "acceptUnknown": "extensions", "format": [ "application/json", "application/fhir+json" ], "rest": [ { "mode": "server", "resource": [ { "type": "Endpoint", "profile": { "reference": "https://dpc.cms.gov/api/v1/StructureDefinition/dpc-profile-endpoint" }, "interaction": [ { "code": "read" }, { "code": "search-type" } ], "versioning": "no-version" }, { "type": "Organization", "profile": { "reference": "https://dpc.cms.gov/api/v1/StructureDefinition/dpc-profile-organization" }, "interaction": [ { "code": "read" } ], "versioning": "no-version" }, { "type": "Patient", "profile": { "reference": "https://dpc.cms.gov/api/v1/StructureDefinition/dpc-profile-patient" }, "interaction": [ { "code": "read" }, { "code": "create" }, { "code": "update" }, { "code": "delete" }, { "code": "search-type" } ], "versioning": "no-version", "searchParam": [ { "name": "identifier", "type": "string" } ] }, { "type": "Practitioner", "profile": { "reference": "https://dpc.cms.gov/api/v1/StructureDefinition/dpc-profile-practitioner" }, "interaction": [ { "code": "read" }, { "code": "create" }, { "code": "update" }, { "code": "delete" }, { "code": "search-type" } ], "versioning": "no-version", "searchParam": [ { "name": "identifier", "type": "string" } ] }, { "type": "StructureDefinition", "interaction": [ { "code": "read" }, { "code": "search-type" } ], "versioning": "no-version" } ], "interaction": [ { "code": "batch" } ], "operation": [ { "name": "Group level data export", "definition": { "reference": "http://build.fhir.org/ig/HL7/bulk-data/OperationDefinition-group-export" } } ] } ] }Attributing Patients to Providers
In order to export data from the DPC application, a healthcare provider must have attributed Patient resources. This attribution assertion attests to CMS that the provider has a treatment related purpose for accessing patient information. More details on the attribution logic and rules are given earlier in this reference.
Sample data
As previously mentioned, the DPC sandbox environments do not have any pre-loaded test data. Users will need to provide their own FHIR resources in order to successfully make export requests to the Blue Button backend.
The DPC team has created a collection of sample Patient and Practitioner resources which can be used to get started with the sandbox. The files are available in our public GitHub repository. More details are given in the included README file.
The sample data was generated using the excellent Synthea project, with some modifications that are documented in the repository.
Users can provide any sample FHIR resources (that fulfill the required FHIR profiles) to DPC, but will need to ensure that, for the sandbox environments, any
HHS is committed to making its websites and documents accessible to the widest possible audience, including individuals with disabilities. We are in the process of retroactively making some documents accessible. If you need assistance accessing an accessible version of this document, please reach out to the guidance@hhs.gov.
DISCLAIMER: The contents of this database lack the force and effect of law, except as authorized by law (including Medicare Advantage Rate Announcements and Advance Notices) or as specifically incorporated into a contract. The Department may not cite, use, or rely on any guidance that is not posted on the guidance repository, except to establish historical facts.