Overview
Blue Button 2.0 (BB2.0) API enables software developers to build trusted applications, services, and research programs that benefit Medicare enrollees. As a standards-based API, BB2.0 provides claims data for more than 64 million people with Medicare.
Data
BB2.0 API includes more than 20 billion Medicare Part A, B and D claims going back to 2014.
- Part A: Institutional claims (Example: services received at the hospital)
- Part B: Professional or carrier claims (Example: primary care visits)
- Part D: Prescription drug claims (Example: when a prescription was filled)
Note: Blue Button 2.0 API does not provide Medicare Part C claims (Medicare Advantage). However, if a Medicare Advantage enrollee has a Part D plan, the API includes those claims.
Use Cases
BB2.0 API data is valuable for any organization interested in innovating with claims data from over 64 million Medicare enrollees. The API serves a variety of use cases and we encourage you to explore ways to use BB2.0 API data to support Medicare enrollees in making healthcare decisions.
Examples of current use cases include:
Personal health data aggregators
Digital health applications can use BB2.0 to give Medicare enrollees a more comprehensive view of their health data. Access to personal health data can make Medicare enrollees more aware of their health conditions, helping them communicate more effectively with their providers. Research shows that thirty percent of Medicare enrollees have 2 or 3 chronic conditions and see 5 or more physicians annually.1 Helping Medicare enrollees gather their health information in one place makes it easier for them to coordinate care across providers and may minimize redundant procedures.
Insurance plan finders
BB2.0 API data can help filter insurance plan options based on a Medicare enrollee’s specific health history and needs. Medicare enrollees can use insurance plan finder tools directly or Medicare brokers can use these tools to advise patients on the best plan options.
For example, with BB2.0 you can:
- Use claims and utilization data to make personalized recommendations for new plan options.
- Estimate prescription costs to optimize Medicare plan guidance.
- Check if a Medicare enrollee’s current providers are in-network for various plan options.
Clinical research studies
Organizations conducting healthcare research and clinical trials often require participants to fill out long forms or regularly submit data over the course of the study. Medicare enrollees can authorize a research study to automatically pull their claims data with BB2.0, reducing the need for manual data entry.
Health record sharing
BB2.0 API can make it easy for Medicare enrollees to share their health data with doctors, pharmacies, caregivers, and others.
You can use BB2.0 to:
- Integrate BB2.0 data with Electronic Health Records (EHR) systems to import current health information.
- Allow patients to share health information like current medications, lab results, and medical imaging with providers.
- Give caregivers an accurate picture of a Medicare enrollee’s health data to facilitate care coordination and communication with providers.
For other examples of how applications use the Blue Button 2.0 API, visit the Blue Button app directory on Medicare.gov.
Access to Medicare enrollee data
Scope of access
Applications receive permission to access Medicare enrollee data on a per-user basis. Access to claims data for each individual enrollee begins after they grant access to an application via the BB2.0 API’s authorization flow.
Medicare enrollees may always opt to omit personal data such as name, date of birth, race, and gender when granting access to claims data. An enrollee’s choice during the BB2.0 authorization flow determines the scope of access an application will have to their data.
Duration of access
The length of time that an application can continue to pull new claims data from Medicare depends on the application’s use case and category. The BB2.0 API team determines your application’s access duration category during the production access process.
There are 3 categories for data access duration:
Category | Description and notes |
---|---|
10 hours | One-time use apps (Example: An app that pulls an enrollee’s data once to recommend insurance plans)
|
13 months | Apps that pull data for the enrollee’s use on an ongoing basis (Example: A personal health aggregator app.)
|
Research | Apps that facilitate Institutional Review Board (IRB)-approved clinical research studies
|
Technical Specifications and Standards
The Blue Button 2.0 API is a RESTful API, based on the HL7 FHIR standard and the CARIN Consumer Directed Payer Data Exchange Implementation Guide. It supplies data in JSON format, and uses the OAuth 2.0 protocol for authorization.
- HL7 FHIR Standard
- CARIN Consumer Directed Payer Data Exchange Implementation Guide
- OAuth 2.0 protocol
- RESTful API Overview
Versions
We currently support 2 BB2.0 API versions:
Version 2
BB2.0 Version 2 (V2) is based on FHIR release (R4) and the CARIN CDPDE Implementation Guide (Carin for Blue Button) and was released in July 2021. To learn about migrating to BB2.0 V2, go to Migrating to V2 FAQ
Version 1
Version 1 (V1) is the original Blue Button API, based on FHIR release 3 (STU3). Development on V1 is limited to bug fixes and basic maintenance. If you’re developing a new app, use V2. For information about BB2.0 V1, see the V1 Documentation.
Environments
We currently maintain production and sandbox environments for developing with the BB2.0 API. For technical information about our environments, see Base FHIR URLs.
Sandbox
Develop your application using our sandbox environment. It provides access to synthetic Medicare enrollee data and includes all the same endpoints, resource types, and parameters as production. You can complete all of the same operations in the sandbox as in the production environment.
It’s helpful to know that:
- Sandbox credentials will not work in production.
- While we strive to provide a synthetic data set relevant to most use cases, our synthetic data set is not as comprehensive as production data.
To get started in the developer sandbox, create an account.
Production
Once your development is nearing completion, get access to live data in our production environment by following the instructions in our production access user guide. After you complete the requirements in the production access guide and your app is approved, we’ll give you credentials for the production environment.
Explore the API
Test client
The Blue Button 2.0 API test client is a quick, no-code-required way to explore data returned from our API endpoints.
Before you begin: If you’re logged in to the sandbox, log out to use the test client.
- Go to the Blue Button 2.0 API test client.
- Choose a sample authorization token option. We recommend choosing the “Get an Authorization Token of v2 (PKCE enabled)” option. This option references our current codebase and Proof Key for Code Exchange (PKCE) is recommended for improved security. For more information on PCKE see Proof Key for Code Exchange (PKCE) extension usage.
- Click Authorize as a Beneficiary.
- Log in to Medicare.gov using a synthetic user’s account credentials.
- Choose a Privacy Option setting.
- Click Allow.
Once you’re logged in as a Medicare enrollee, you’ll get an access token and you can make calls to different endpoints and see the sample data that is delivered in the response.
Sample data
If you want to see a sample of the data available in the Blue Button 2.0 API without authenticating a synthetic user or creating a sandbox account, you can download a sample file. This zip folder of JSON files contains synthetic data for a single Medicare enrollee. The download includes 3 FHIR resources in JSON format:
- A single Patient resource
- A FHIR bundle containing multiple ExplanationOfBenefit resources (EOB)
- A FHIR bundle containing multiple Coverage resources
To learn more about Blue Button 2.0 API data, refer to Understanding the Data.
Getting started in the developer sandbox
To get started integrating with the Blue Button 2.0 API, you’ll need to register a sandbox application. You don’t need a working application at this point, but you need to define basic settings to generate client credentials for testing purposes.
1. Register an application in the developer sandbox
- Go to the Sandbox Dashboard. (If you don’t already have an account, create one.)
- Click Add an Application.
2. Enter application details
When you add or edit a sandbox application, you’ll enter various required configuration details.
Application Name
The name of your sandbox application.
OAuth Client Type
The Blue Button 2.0 API only supports confidential client type.
Authorization Grant Type
The Blue Button 2.0 API only supports the authorization code grant type. An authorization code is a random string generated by the authorization server and returned to the application as part of the authorization response.
Callback URLs / Redirect URIs
This is an API endpoint on your system that receives the callback after a user successfully authorizes your application to access their Medicare data. To enter multiple URIs in the Callback URLs / Redirect URIs field, separate each entry with a space or new line.
Sample format: URIscheme://[sub-domain.]domain_name[:port]/path
Does my application need to collect beneficiary demographic data?
This setting determines 2 things:
- What scopes are applied to your application (determines which API calls your application can execute).
- The information and options displayed on the authorization screen Medicare enrollees use to allow or deny your application access to their data.
Setting | Description |
---|---|
Yes | Allows your application to request access to a Medicare enrollee’s claims data AND personal information such as name, date of birth, race and gender. (Scopes: patient/Patient.read , patient/Coverage.read , patient/ExplanationOfBenefit.read , profile ) |
No | Allows your application to request access to the patient/Coverage.read and patient/ExplanationOfBenefit.read scopes. |
To learn more about scopes and permissions, visit Authorization.
3. Save your application
Click Save Application.
After you register your sandbox application, you’ll get a Client ID and Client Secret.
- Client ID: an alphanumeric string used to identify your application. Use this in your code when you call the Blue Button 2.0 API.
- Client Secret: an alphanumeric string used by your application to authenticate with the Blue Button server.
Note: Client credentials from the developer sandbox only work in the sandbox environment. To get production credentials, you need to complete the production access requirements and be approved.
4. Test the API with Postman or cURL
Once you’ve created a Blue Button 2.0 sandbox application, you can start making requests. The instructions in this section will get you up and running quickly with Postman or cURL.
Postman
Postman is a widely used API client. To start making Blue Button 2.0 API sandbox calls in Postman, follow the steps shown below.
- Configure your Sandbox application to work with Postman:
- Log into the Blue Button 2.0 Sandbox.
- Click View/Edit App for the app you want to use with Postman.
- Click Edit Application.
- Enter the following URLs into the Callback URLs / Redirect URIs field, separated by a carriage return.
https://oauth.pstmn.io/v1/callback
https://oauth.pstmn.io/v1/browser-callback
- Click Save Application.
- Log into the Blue Button 2.0 Sandbox.
- Download the Blue Button 2.0 API Sandbox Postman collection and import it into the Postman desktop or web application.
- To import the collection, either click the Import button in Postman and select the collection file, or drag the file into the Postman window.
- Select the top-level folder in the collection, CMS BlueButton 2.0 API Sandbox.
- Select the Variables tab.
- Copy your application’s Client ID and Client Secret from your Sandbox account into both the Initial Value and Current Value cells for the corresponding Postman variables,
clientId
andclientSecret
. - After copying and pasting your API credentials, log out of the Blue Button sandbox in your browser. Being logged into the sandbox can cause errors during authorization in Postman.
- In Postman, select the Authorization tab.
- Click Get New Access Token.
- A Medicare.gov login window will open. Enter the username and password for a synthetic sandbox user account (e.g., user = “BBUser00000” and password = “PW00000!”), and click Log in.
- Click Connect.
- When the Manage Access Tokens window appears, click Use Token. You may also give your token a name.
- Make any desired Blue Button 2.0 API calls from the endpoints listed under the Patient, Explanation of Benefit, and Coverage folders. For example, to retrieve explanation of benefits information for the authenticated patient:
- Select the Explanation of Benefits folder, then GET Search Explanation of Benefits.
- Click Send.
- The API will return a FHIR bundle with explanation of benefits information.
cURL
You can also call the Blue Button 2.0 sandbox with cURL, a popular command-line HTTP client.
First, obtain an access token. To test using your sandbox application, you can use Postman to retrieve a token with your client ID and secret, as shown in the previous section. Alternately, you can get a sample authorization token from the Blue Button 2.0 Test Client as shown in the following steps:
- Navigate to the Blue Button 2.0 API Test Client.
- If you are currently logged into the Blue Button 2.0 sandbox, click Log Out to Continue.
- Click Get a Sample Authorization Token for v2.
- Click Authorize as a Beneficiary.
- A Medicare login screen will open. Enter the username and password for a synthetic sandbox user account (e.g., user = “BBUser00000” and password = “PW00000!”), and click Log in.
- Click Connect.
- A new page will open. Copy the access token from the JSON shown under Step 1: Sample Authorization for use in your cURL command.
Once you have an access token, you can start making API calls with cURL. For example, the following command will retrieve explanation of benefit information for the authenticated patient (replace <YOUR ACCESS TOKEN>
with your actual access token):
curl --location "https://sandbox.bluebutton.cms.gov/v2/fhir/ExplanationOfBenefit/" --header "Accept: application/json" --header "Authorization: Bearer <YOUR ACCESS TOKEN>"
5. Next steps
If you’re ready to start building, check out our Sample Applications or SDKs:
SDKs
Our SDKs provide a comprehensive set of tools to help you build applications faster and in a more standardized way. The SDKs are available for Node and Python.
Sample Apps
Our sample applications provide examples of basic use of the BB2.0 API.
Authorization
The BB2.0 API uses the OAuth 2 authorization flow. To initiate an integration, you’ll need the client ID and client secret for your application that were generated when you registered your application.
Web applications
BB2.0 API supports the Authorization Code flow for web applications running on a server. Use the following settings when registering your application:
- Client Type: Confidential
- Grant Type: Authorization code
User authorization
To allow a user to authorize your application, direct them to the BB2.0 API /authorize
endpoint with the appropriate parameters.
Example call:
https://sandbox.bluebutton.cms.gov/v2/o/authorize/?client_id=swBu7LWsCnIRfu530qnfPw1y5vMmER3lAM2L6rq2&redirect_uri=http://localhost:8080/testclient/callback&response_type=code&state=8e896a59f0744a8e93bf2f1f13230be5
Parameters: Authorization code request
Parameter | Required | Description |
---|---|---|
client_id |
required | The client_id from your registered application. |
lang |
optional | Authorization screen language selection. Use en for English or es for Spanish. |
redirect_uri |
required | The callback URL of your application. The user will be directed to this URL after authorizing your application. |
response_type |
required | Supported response type: code |
state |
optional | Recommended. A random string used to protect against request forgery attacks. |
Authorization screen language selection
The BB2.0 user authorization screens are available in both English (the default) and Spanish. Language selection for these screens works as follows:
- To explicitly specify the language for the Blue Button 2.0 authorization screens, add the optional
lang
parameter to your/authorize
request. Valid values areen
(English) andes
(Spanish).- Example:
https://sandbox.bluebutton.cms.gov/v2/o/authorize/?lang=es
- Example:
- If the
lang
parameter is omitted or is set to a value other thanen
ores
, the API server will next check theAccept-Language
HTTP header in the/authorize
request.- If the language settings in a user’s web browser lists Spanish higher in the preference list than English, the browser will automatically include the correct
Accept-Language
value to request the Spanish-language screens.
- If the language settings in a user’s web browser lists Spanish higher in the preference list than English, the browser will automatically include the correct
- If neither English or Spanish is requested via the
lang
parameter orAccept-Language
header, the API server will default to the English version of the authorization screens.
Token endpoints
- Sandbox:
https://sandbox.bluebutton.cms.gov/v2/o/token/
- Production:
https://api.bluebutton.cms.gov/v2/o/token/
Exchange code for token
If the user authorizes your application, the BB2.0 API redirects back to the redirect_uri
registered with your application with an authorization code and state parameter appended to it.
For example, if the Redirect URI is http://localhost:8080/testclient/callback
, BB2.0 API will redirect with this request:
GET http://localhost:8080/testclient/callback?code=TSjqiZCdJwGyytGjz2GzziPfHTJ6z2&state=8e896a59f0744a8e93bf2f1f13230
Your application can now exchange the code provided in the redirected request for an access token.
To retrieve an access token, POST to the BB2.0 /token endpoint providing the code with the following parameters:
client_id
client_secret
redirect_uri
grant_type
:authorization_code
code
cURL command
curl -X POST "https://sandbox.bluebutton.cms.gov/v2/o/token/" \
-u "<client_id>:<client_secret>" \
-d "code=TSjqiZCdJwGyytGjz2GzziPfHTJ6z2&grant_type=authorization_code&redirect_uri=http://localhost:8080/testclient/callback"
Token response
{
"access_token": "oQlduHNr09GKCU506GOgp8OarrAy2q",
"expires_in": 16768.523842,
"token_type": "Bearer",
"scope": "profile patient/Patient.read patient/ExplanationOfBenefit.read patient/Coverage.read",
"refresh_token": "wDimPGoA8vwXP51kie71vpsy9l17HN",
"access_grant_expiration": "2025-09-05 19:17:53Z"
}
Applications in the “10 hours” access category do not receive a refresh token in the BB2.0 token response.
Note that for applications in the “10 hours” or “13 months” access expiration categories, the response includes the access_grant_expiration
date for that user.
Exchange refresh token for new access token
Access tokens expire after 10 hours. You can’t use an expired access token to access data. To access data after an access token expires, request a new access token using a refresh token. Refresh tokens are available to applications in the “13 months” and “Research” access duration categories.
You can use a refresh token at any time in your application’s workflow, even before an access token expires.
To retrieve a new refresh token, POST to the BB2.0 API /token
endpoint with the following parameters:
client_id
client_secret
grant_type
:refresh_token
refresh_token
cURL command
curl -X POST "https://sandbox.bluebutton.cms.gov/v2/o/token/" \
-u "<client_id>:<client_secret>" \
-d "grant_type=refresh_token&refresh_token=wDimPGoA8vwXP51kie71vpsy9l17HN"
Token response
(successful with 200 status code):
{
"access_token": "VD1VaT4IfjXAMlZTS9E4RVXZlkhYG7",
"expires_in": 36000,
"token_type": "Bearer",
"scope": "profile patient/Patient.read patient/Coverage.read patient/ExplanationOfBenefit.read",
"refresh_token": "7x0VkRQlRU4fRNCQL2vh239nIyucgw",
"patient": "-20140000000001",
"access_grant_expiration": "2025-09-05 19:17:53Z"
}
Common token endpoint errors
Reused refresh token
A refresh token can only be used one time. The following is an example of an error response when attempting to reuse a refresh token:
Response (unsuccessful with 400 status code):
{
"error": "invalid_grant"
}
If you receive this error, verify that your refresh token sent the correct value. If it’s already been used, the user should be directed to re-authorize following the original authorization flow above.
Client credentials or permissions problems
If your request has any issues with client credentials or permissions, the following response will be received:
Response (unsuccessful with 401 status code):
{
"error": "invalid_client"
}
If you receive this message, double-check that the request looks correct. If everything looks correct, email bluebuttonapi@cms.hhs.gov, and the Blue Button 2.0 API team can help troubleshoot.
Expired Data Access Grant
If your authorization for accessing user data has expired, the corresponding access token will not be refreshed. Attempts to refresh the token will result in the following error message:
Response (unsuccessful with 400 status code):
{
"status_code": 400,
"error": "invalid_grant",
"error_description": "The authorization for accessing user data has expired. To refresh Medicare data, the end user must re-authenticate and consent to data sharing."
}
For information on re-authorizing, see user authorization.
Expire authenticated user for sandbox testing
For testing in our sandbox, you can use the /expire_authenticated_user
endpoint that expires the authorization granted by a patient user.
/expire_authenticated_user
can be used to test your code for the following conditions that produce the same error responses via the API:
- When an access token expires, without needing to wait for the expiration in 10 hours
- When a patient revokes access to your application
- When access granted to a patient’s data has expired
POST to the BB2.0 API /expire_authenticated_user
endpoint with the following parameters:
client_id
client_secret
- patient ID (patient ID “-20140000000001” is used in the cURL example below)
cURL command
curl -X POST "https://sandbox.bluebutton.cms.gov/v2/o/expire_authenticated_user/-20140000000001/" \
-u "<client_id>:<client_secret>" \
-H "Content-Length: 0"
Response
Successful with 200 status code:
success
Common error responses
Error Code | Response | Reason |
---|---|---|
404 | Data Access Grant was Not Found |
Patient ID has not granted access |
403 | FORBIDDEN |
Issues with client credentials or permissions |
Native & mobile applications
The Blue Button API supports the OAuth 2.0 Authorization Framework using the authorization code grant with a confidential client type flow. To optimize the security of Medicare enrollees’ data during authentication, we do not support the implicit grant or public client types.
For best practices for the type of application you’re developing, review the OAuth 2.0 for Native Apps.
To mitigate security risks, use a proxy middleware server following a Backend For Frontend (BFF) authentication pattern. In the BFF pattern, a backend server performs all authorization code and refresh token exchanges. For examples of this type of proxy middleware client/server implementation, check out our sample applications available in Node or Python.
Proof Key for Code Exchange (PKCE) extension usage
To improve the security of your application, we highly recommend using the PKCE extension.
There are several reasons to use the PKCE extension:
- Ensures that the application that started the OAuth 2.0 flow is the same one that is finishing it.
- Mitigates the impact of a compromised Authorization Code by a malicious actor.
- Follows the OAuth 2.0 Security Best Current Practice
PKCE code challenge support
PKCE uses a code challenge that is derived from a code-verifier. The BB2.0 API supports the S256 style code challenge:
codechallenge = BASE64URL-ENCODE(SHA256(ASCII(codeverifier)))
When using PKCE, send the following additional parameters and values as part of the OAuth2.0 Authorization Request:
code_challenge
codechallengemethod = "S256"
To learn more about this flow, refer to OAuth.com.
Scopes
Scopes define the API endpoints that your application is allowed to access. The BB2.0 API uses HL7 FHIR Scopes to manage access to Medicare enrollee data.
BB2.0 API HL7 FHIR
Scope | Grants |
---|---|
patient/Patient.read |
Permission to read the Patient resource for a Medicare enrollee |
patient/Coverage.read |
Permission to read the Coverage resources for a Medicare enrollee |
patient/ExplanationOfBenefit.read |
Permission to read the Explanation of Benefit resources for a Medicare enrollee |
profile |
Permission to access the /UserInfo endpoint (from the OpenID Connect specification |
Medicare enrollee personal information guidelines
There are 2 scenarios that block your application’s access to the /Patient
and /Userinfo
endpoints:
- You choose not to collect Medicare enrollee personal information when your application is approved in production.
- A Medicare enrollee does not give your application permission to access their personal information. In the Medicare.gov authentication process, Medicare enrollees always have the option to block access to their personal data.
If you can’t access the /Patient
or /Userinfo
endpoint, you can get the resource ID for a patient by pulling it during the initial authorization response or from the ExplanationOfBenefit
or Coverage
bundles.
Suppose your application requires information limited by a scope and you can’t get the information in another endpoint. In that case, you can explain why certain data is needed within your application before the user goes through the Medicare.gov authentication process. For example, if you use demographic information to help users autofill forms, explain in your UI that allowing access to their personal data will make it easier and faster to fill out required forms. However, if a user shares that data with you for one-time data entry, be clear about how long you keep the information and if it is used for any other purposes in your Privacy Policy and/or Terms of Service documents.
Revoked access
An enrollee can revoke access to your application in the ‘My Connected Apps’ section of their Medicare.gov account. This results in an invalid token for that user. If a Medicare enrollee revokes access to their data, be sure to account for that use case in your application’s UI so it’s easy for a Medicare enrollee to understand what’s happening with their Medicare data.
Understanding the data
The BB2.0 database pulls data from the CMS Chronic Conditions Warehouse (CCW), which contains Medicare Part A, B and D claims data going back to 2014. Over 600 fields from the CCW are mapped to FHIR. These fields are surfaced across the Patient, Coverage and Explanation of Benefits FHIR resources.
FHIR resources
Blue Button 2.0 API data is supplied in three resources from the FHIR standard:
- Explanation of Benefit (EOB): Primary source of claims data. The EOB resource contains the lines within an episode of care, including where and when the service was performed, the diagnosis codes, the provider who performed the service, and the cost of care.
- Patient: Provides information about patients including demographic information and updates to their patient identifiers.
- Coverage: Provides information about the enrollees’ insurance coverage, including information about dual coverage.
Explanation of Benefit
The Explanation of Benefit resource provides data for the following claim types:
- Inpatient (INPATIENT)
- Outpatient (OUTPATIENT)
- Skilled Nursing Facility Claims (SNF)
- Hospice (HOSPICE)
- Home Health Agency Claims (HHA)
- Carrier (Professional)
- Durable Medical Equipment (DME)
- Prescription Drug Events - Part D (PDE)
Request:
HTTP GET /v2/fhir/ExplanationOfBenefit/?patient=[fhir_id]
This request returns claims as Explanation of Benefit Resources inside a FHIR Bundle.
Example response excerpt:
{
"total":99,
"entry": [
{
"resource": {
"resourceType":"ExplanationOfBenefit",
"id":"carrier--10045426206",
"meta":{
"lastUpdated":"2021-06-07T21:51:33.787-04:00",
"profile": [
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-ExplanationOfBenefit-Professional-NonClinician"
]
},
"identifier": [
{
"type":{
"coding": [
{
"system":"http://hl7.org/fhir/us/carin-bb/CodeSystem/C4BBIdentifierType",
"code":"uc",
"display":"UniqueClaimID"
}
]
},
"system":"https://bluebutton.cms.gov/resources/variables/clm_id",
"value":"-10045426206"
},
Download a sample EOB resource
Patient
HTTP GET /v2/fhir/Patient/[fhir_id]
The above URL returns demographic and other administrative information as a Patient FHIR Resource. This information is mostly demographic information, not medical data. Note that users can choose to allow or deny access to the /Patient endpoint in the Medicare.gov authorization flow. For more information, go to Scopes.
Request:
curl --header "Authorization:Bearer AUTHORIZATION TOKEN" "https://sandbox.bluebutton.cms.gov/v2/fhir/Patient/-20140000008325"`
Example response excerpt:
{
"resourceType": "Patient",
"id": "-20000000001112",
"meta": {
"lastUpdated":"2021-06-07T21:50:48.132-04:00",
"profile": [
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Patient"
]
},
"identifier": [
{
"type":{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code":"MC",
"display":"Patient'sMedicarenumber"
}
]
},
"system": "http://hl7.org/fhir/sid/us-mbi",
"value":"2S00A00AA00",
"period": {
"start":"2020-01-01"
}
}
],
"name": [
{
"use":"usual",
"family":"Doe",
"given": [
"John",
"X"
]
}
],
"gender":"male",
"birthDate":"1999-06-01",
"deceasedDateTime":"1981-03-17",
"address": [
{
"state":"07",
"postalCode":"99999"
}
]
}
Download a sample Patient FHIR Resource
Coverage
HTTP GET /v2/fhir/Coverage/?beneficiary=[fhir_id]
The above URL returns Coverage information as Coverage resources inside a FHIR Bundle. One coverage resource is supplied for each coverage type.
Request:
curl --header "Authorization:Bearer AUTHORIZATION TOKEN" "https://sandbox.bluebutton.cms.gov/v2/fhir/Coverage/?beneficiary=-20140000008325"`
Response excerpt:
{
"resourceType":"Bundle",
"id":"fb4bffd7-abb3-401f-96cd-d617c545092c",
"meta":{
"lastUpdated":"2022-02-14T17:27:56.303-05:00"
},
"type":"searchset",
"total":4,
"entry": [
{
"resource": {
"resourceType":"Coverage",
"id":"part-a--20000000001112",
"meta": {
"lastUpdated":"2021-06-07T21:50:48.132-04:00",
"profile": [
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Coverage"
]
},
"status":"active",
"type":{
"coding": [
{
"system":"http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code":"SUBSIDIZ"
}
]
},
"subscriberId": "2S00A00AA00",
"beneficiary": {
"reference":"Patient/-20000000001112"
},
Download a sample Coverage FHIR Resource
UserInfo
The UserInfo endpoint is an OAuth 2.0 Protected Resource that returns information about an authenticated user.
Note that users can choose to allow or deny access to the UserInfo endpoint in the Medicare.gov authorization flow. For more information, go to Scopes.
HTTP GET /connect/userinfo
The above URL returns basic information about the user, given an authorization token. An HTTP GET is called and the response is returned as JSON.
Request:
curl --header "Authorization: Bearer <AUTHORIZATIONTOKEN\>" "https://sandbox.bluebutton.cms.gov/v2/connect/userinfo"`
Example response:
{
"sub": "-123456789",
"prefered_username": "fflinstone",
"given_name": "Fred",
"family_name:, "Flinstone,
"name": "FredFlinstone",
"email": "pebbles-daddy@example.com",
"created": "2017-11-28",
"patient": "-123456789",
}
Terminology and coding systems
BB2.0 API supplies codified data using several different terminology and coding systems, defined by various standards bodies, along with locally defined CMS coding systems:
Additional information about coding systems can be found on the terminology page of the CARIN Implementation Guide and in the Blue Button Code System Listing (CSV 77KB).
BB2.0 API also provides data in FHIR Extensions. FHIR extensions are custom data elements that are not found in the FHIR standard:
Refresh rate and rate limiting
Data from the CCW is pulled into the BB2.0 API database on a weekly basis. The weekly data pull may be delayed for maintenance or because of delayed delivery of claims to the CCW.
Our rate limit is high enough to accommodate the needs of anyone integrating with the BB2.0 API. The BB2.0 API is one of 4 CMS APIs that share the same data from the CCW. BB2.0 is for single data calls for an individual Medicare enrollee and the other 3 APIs are designed for bulk data calls. Because the rate limit is set based on the needs the bulk data APIs, the rate limit is higher than required for an application making single API calls using BB2.0.
Synthetic data
Because access to real claims data is restricted in order to protect the privacy of Medicare enrollees, CMS created synthetic user accounts representing enrollment information and healthcare claims for 40,000 Medicare enrollees. Since synthetic data are realistic-but-not-real data, the typical privacy and security restrictions do not apply.
Although the synthetic user accounts are not tied to any real patient data, they mimic real claims data. For example, if a patient is prescribed the diabetes medication Metformin, the associated cost and date of this prescription will be realistic. However, the synthetic data set does not represent a longitudinal patient view or true clinical scenario. This allows you to test your integration with BB2.0 API, but could result in a patient with records for contradictory procedures.
Working with synthetic user accounts
BB2.0 API offers 40,000 synthetic user accounts for you to test with in both the sandbox and production environments:
User account ranges | Date updated | Description |
---|---|---|
BBUser00000 to BBuser09999 | Rolling Claims updated weekly Loaded July 2023 |
Most recently updated and most useful accounts. These accounts receive new claims data on a rolling basis. These user accounts represent a range of Medicare demographics and ages, including people under 65 who qualify for Medicare for reasons other than age. |
BBUser10000 to BBuser29999 | Loaded 2017 | Static claims data |
BBUser30000 to BBuser39999 | Loaded October, 2021 | Static claims data |
Note: BBUser10000 is a special synthetic user that provides nearly every field the API supports, including a variety of claim types. This makes it an excellent testing account for populating test scenarios.
To differentiate between synthetic data and real patient production data, synthetic records have negative Patient ID and Explanation of Benefit values (example synthetic Patient ID: -10000010254618). Real Patient IDs will always have positive values.
Authenticating as a synthetic user
Each of our 40,000 synthetic user accounts have Medicare.gov login credentials. To log in as a synthetic user, use the following username/password combination pattern when authorizing a test user with Blue Button 2.0:
- Username: BBUserXXXXX (Example: BBUser00005)
- Password: PWXXXXX! (Example: PW00005!)
Claim dates in rolling claims updates
When new data is added for a synthetic user account in the weekly update, the new data includes claims dated 1-2 weeks prior. This delay simulates real claim processing time in production data. Get updated claims using the _lastUpdated query parameter.
Consuming the data
The Blue Button API includes over 1300 data elements with a wide variety of data exchange use cases. Here are some basics to get you started with common data elements.
For complete implementation guidance, see the FHIR specification and the CARIN implementation guide. Our Resources page also includes links to tutorials and helpful information on FHIR.
Understanding the payload
Blue Button API search operations (like /Patient
, /ExplanationOfBenefit
, and /ExplanationOfBenefit?patient=123
) return data in FHIR Bundles. A FHIR bundle is a container resource that includes a collection of FHIR resources. You can grab each resource by looping through the Bundle.entry
list attribute.
Read calls such as /Patient/123
return a single resource.
FHIR Bundle
example:
{
"resourceType": "Bundle",
"id": "123",
....
....
"type": "searchset",
"total": 99,
"entry": [
{
"resource": {
"resourceType": "ExplanationOfBenefit",
"id": "carrier--123",
....
}
}
{
"resource": {
"resourceType": "ExplanationOfBenefit",
"id": "carrier--456",
....
}
}
]
}
Navigating through a bundle
FHIR search results are paginated because they typically contain many records. The default is 10 records in each call. You can override the default of 10 with a _count parameter in the request. The maximum records allowed is 50.
To navigate forward and backward through the bundle, use the URLs provided in Bundle.link
, as described in the table below. For instance, to get the next X
records, use the URL supplied in Bundle.link
where relation = next
.
Relation | Description |
---|---|
first | Retrieve the first X records in the resultset |
next | Retrieve the next X records in the resultset |
previous | Retrieve the previous X records in the resultset |
last | Retrieve the last X records in the resultset |
In the example below, the Bundle.total
attribute shows that there are 89 records in the results. However, only the first 10 records are delivered in the Bundle.entry
array.
For more information on Bundles and FHIR search results, see FHIR v4.3.0 Bundle and FHIR v4.3.0 Managing Returned Resources.
Bundle navigation example:
"resourceType": "Bundle",
"id": "5e5844c4-d3e2-44ca-8c87-77efccc5d60d",
...
...
"total": 89,
"link": [
{
"relation": "first",
"url": "{host}/v2/fhir/ExplanationOfBenefit?startIndex=0&_count=10&patient=......
},
{
"relation": "next",
"url": "{host}/v2/fhir/ExplanationOfBenefit?startIndex=10&_count=10&patient=......
},
{
"relation": "last",
"url": "{host}/v2/fhir/ExplanationOfBenefit?&startIndex=.....
},
{
"relation": "self",
"url": "{host}/v2/fhir/ExplanationOfBenefit?&startIndex=.....
}
],
Working with identifiers
In FHIR, the difference between the Resource.id
(resource ID) and identifier
attributes within a resource can be confusing.
-
Resource ID: In the Blue Button API, the resource ID is an internal identifier from the source database, the Chronic Conditions Warehouse (CCW). The resource ID is a system-level resource, held outside the resource. The Resource ID is guaranteed to be unique for a particular resource and will always be limited to one value.
-
Identifier: The identifier attribute typically provides business identifiers (or externally recognized identifiers). In the Blue Button API, the
Patient.identifier
attribute provides the Medicare Beneficiary ID (MBI). The MBI is the number on a beneficiary’s Medicare card.
In FHIR, the identifier attribute is a list element that could supply multiple identifiers. Use discriminators to distinguish between the entries to pull your desired identifier.
For example, you can use discriminators to pull the current MBI from a Patient resource. (Beneficiaries are sometimes given new or replacement MBIs in situations such as identity theft.) In the Patient
resource snippet below, there are two identifiers in the list. Use the following discriminators to pull the current MBI:
identifier.system
=http://hl7.org/fhir/sid/us-mbi
(ensures that the entry is an MBI)identifier.type.coding[n].extension.valueCoding.code
= “current”
Patient identifier example:
"identifier": [
{
"system": "http://hl7.org/fhir/sid/us-mbi",
"type": {
"coding": [
{
"code": "MC",
"extension": [
{
"url": "https://bluebutton.cms.gov/resources/codesystem/identifier-currency",
"valueCoding": {
"code": "current",
}
}
]
}
]
},
"value": "<CURRENT MBI HERE>"
},
{
"system": "http://hl7.org/fhir/sid/us-mbi",
"type": {
"coding": [
{
"code": "MC",
"extension": [
{
"url": "https://bluebutton.cms.gov/resources/codesystem/identifier-currency",
"valueCoding": {
"code": "historic",
}
}
]
}
]
},
"value": "<HISTORIC MBI HERE>"
}
],
Example FHIRPath expression for pulling the current MBI:
Patient.identifier.where(type.coding.extension('https://bluebutton.cms.gov/
resources/codesystem/identifier-currency').valueCoding.code =
'current').where(system = 'http://hl7.org/fhir/sid/us-mbi').value
Working with references
The Blue Button API uses both literal and logical FHIR references to refer to other resources/data external to the resource.
Literal references
For literal references, relative URLs are provided. In the sample EOB resource below, the Eob.patient
attribute contains a relative URL reference, /Patient/123
. Append this path to the base FHIR URL to perform a Patient read operation.
Literal reference example:
"resource": {
"resourceType": "ExplanationOfBenefit",
"id": "carrier--10045426206",
....
....
"patient": {
"reference": "Patient/123"
},
Contained resources
The Blue Button API also uses fragments and contained resources. A resource that does not have independent existence is embedded inside another resource as a contained resource. For example, the Organization resource does not have its own endpoint. Instead, it is supplied as a contained resource with EOB. In the example EOB resource below, the organization resource is within the Eob.contained
attribute, and the Eob.provider
attribute has a #
reference to contained.id
(#provider-org
).
Contained resource example:
"contained": [
{
"active": true,
"id": "provider-org",
"identifier": [
{
"type": {
"coding": [
{
"code": "PRN",
"system": "http://terminology.hl7.org/CodeSystem/v2-0203"
....
....
....
"provider": {
"reference": "#provider-org"
},
Logical references
Logical references typically supply a business identifier instead of a URL to an endpoint or contained resource.
In the example below, the Eob.careTeam.provider
attribute contains a reference to the the National Provider Identifier (NPI) for the practitioner. (Note: The Blue Button API does not support a /Practitioner
endpoint.)
Logical reference example:
"careTeam": [
{
"provider": {
"identifier": {
"type": {
"coding": [
{
"code": "npi",
"display": "National Provider Identifier",
"system": "http://hl7.org/fhir/us/carin-bb/CodeSystem/C4BBIdentifierType"
}
]
},
"value": "123"
}
},
Extensions and SupportingInfo
The Blue Button API supplies many data points using FHIR extensions. Extensions are information that is not part of the basic definition of the FHIR resource. They’re often very specific to a use case or situation. For example, the Blue Button API uses extensions to supply Medicare-specific data points that are not part of the standard FHIR specification.
All Blue Button API resources include extensions. Extensions are like a key-value list, where the extension URL is the key. In an extension, the value attribute is defined as Choice of Types, where the data type depends on the definition of the extension.
In the example below, there are two extensions:
- NCH Near Line Record Identification Code provides the value as a
valueCoding
type - Carrier or MAC Number is a
valueIdentifier
Note: In the Blue Button API, the extension URL points at an underlying valueset rather than the standard FHIR practice of the URL pointing to the StructureDefinition of the extension. This is due to historical reasons and will be revisited in future versions of Blue Button.
Extension example:
"extension": [
{
"url": "https://bluebutton.cms.gov/resources/variables/nch_near_line_rec_ident_cd",
"valueCoding": {
"code": "O",
"display": "Part B physician/supplier claim record (processed by local carriers; can include DMEPOS services)",
"system": "https://bluebutton.cms.gov/resources/variables/nch_near_line_rec_ident_cd"
}
},
{
"url": "https://bluebutton.cms.gov/resources/variables/carr_num",
"valueIdentifier": {
"system": "https://bluebutton.cms.gov/resources/variables/carr_num",
"value": "15202"
}
}
SupportingInfo attribute
The supportingInfo
attribute is a standard element in the FHIR EOB resource. Similar to extensions, suportingInfo
is like a key-value list. supportingInfo.category
serves as the key and supportingInfo.code
is the value. Other attributes in supportingInfo
include timing[x]
, value[x]
, and reason
.
Note: The CARIN Implementation Guide has chosen to use supportingInfo
over extensions. The CARIN IG does not define any extensions. For historical and backwards compatibility reasons, the Blue Button API provides data in both extensions and supportingInfo
.
Determining claim type
The Blue Button API supplies claims data in the ExplanationOfBenefit resource for all claim types (Example: Inpatient, Outpatient, Carrier, DME, etc.)
To determine the type of a given claim, inspect the Eob.type
attribute. Eob.type
is a CodeableConcept
, which provides data as a list of codings. There are multiple entries in the list.
Each entry is a code from a given codesystem or valueset with information about the type of claim. For example, the NCH_CLM_TYPE_CD
codesystem uses the code 71
for a carrier claim. The Blue Button API eob-type
valueset uses a code of CARRIER
for a carrier claim.
Claim type example:
"type": {
"coding": [
{
"code": "71",
"display": "Local carrier non-durable medical equipment, prosthetics, orthotics, and supplies (DMEPOS) claim",
"system": "https://bluebutton.cms.gov/resources/variables/nch_clm_type_cd"
},
{
"code": "CARRIER",
"system": "https://bluebutton.cms.gov/resources/codesystem/eob-type"
},
.....
.....
]
},
For more information about determining claim types, see the following coding system reference links:
Linking items
The item
data element in the EOB resource supplies a list of entries describing products/services provided. You can link each entry in the list to other parts of the EOB using the item.*sequence elements
.
For example, Eob.item.diagnosisSequence
links to Eob.diagnosis.sequence
, which tells you that this product/service is linked to the corresponding diagnosis. In the partial EOB example below, the item
is linked to diagnosis 1
and careTeam member 3
.
Linking item example:
"item": [
{
"adjudication": [
....
....
"diagnosisSequence": [
1
],
"careTeamSequence": [
3
],
....
....
}
]
"diagnosis": [
{
"sequence": 1,
"diagnosisCodeableConcept": {
"coding": [
{
"code": "Z0000",
"display": "ENCNTR FOR GENERAL ADULT MEDICAL EXAM W/O ABNORMAL FINDINGS",
....
....
},
"careTeam": [
{
"sequence": 1
....
....
},
{
"sequence": 2
....
....
},
{
{
"sequence": 3,
"provider": {
"identifier": {
....
....
},
"role": {
"coding": [
{
"code": "performing",
"display": "Performing provider",
....
....
Calling the API
This section provides information on basic and common queries against the Blue Button API. For a complete listing of Blue Button API calls, see our Swagger documentation.
Base FHIR URLs
Environment | Purpose | Base URL |
---|---|---|
Sandbox | Development and Testing | https://sandbox.bluebutton.cms.gov/v2/fhir/ |
Production | Production Data Access | https://api.bluebutton.cms.gov/v2/fhir/ |
To find beneficiaries with varying volumes and types of data, use this CSV of synthetic data. Using the synthetic data, you can break down claims by type (carrier, inpatient, etc.) for each beneficiary/user combination. Synthetic data works in both the Sandbox and Production environments.
Querying Resources
A listing of common API calls are shown in the table below. See “Base FHIR URLs” above and substitute for {baseURL} as appropriate.
For a complete listing of Blue Button API calls, see our Swagger documentation.
Resource | Request | Description |
---|---|---|
Patient | HTTP GET {baseURL}/Patient |
Returns a bundle of Patient resources with one entry (one patient resource). You can use the resource ID Bundle.entry.resource.id in later queries. For synthetic data, the ID is a negative number. |
Patient | HTTP GET {baseURL}/Patient/{id} |
Returns a single Patient resource. Replace {id} with a valid patient resource ID. See /Patient call above. |
Coverage | HTTP GET {baseURL}/Coverage?beneficiary={ id } OR HTTP GET {baseURL}/Coverage |
Replace {id} with the patient resource ID. Returns a bundle of Coverage resources |
Explanation of Benefit | HTTP GET {baseURL}/ExplanationOfBenefit?patient={ id } OR HTTP GET {baseURL}/ExplanationOfBenefit |
Replace {id} with patient resource ID. Returns a bundle of Explanation of Benefit resources. The bundle should contain one or more EOBs. You can use the resource ID located at Bundle.entry.resource.id (the explanation of benefit resource ID) in later queries. For synthetic data, the ID is typically formatted as [claimtype] –[number] Example: carrier--10114937820 |
Explanation of Benefit | HTTP GET {baseURL}/ExplanationOfBenefit/{id} |
Returns a single Explanation of Benefit resources. Replace {id} with a valid EOB resource ID. See /ExplanationOfBenefit call above. |
Capability Statement | HTTP GET {baseURL}/metadata |
Returns the FHIR capability statement (Example: the FHIR features and operations supported by this server) |
User Info | HTTP GET {host}/{version}/connect/userinfo |
If the user grants access to access to their personal information, UserInfo returns name, family name and email. If the user denies access to their personal information, UserInfo returns You do not have permission. |
Optimizing your application
Compress resources for more efficient data transfers
Turn on compression to improve performance when transferring large data resources. Gzip compression is turned off by default. Compression can be activated for the following content types:
text/html
text/plain
application/json
application/fhir+json
To activate compression add the following to the header:
Accept-Encoding: gzip
The minimum payload size we will gzip is 1 kilobyte. Check for the Content-Encoding: gzip
response header before trying to decompress.
Query by type
EOB resources fall into 8 types. If you only need specific types of data, the query by type feature allows you to request claims by claim type. By default, the FHIR API returns all of these claim types when requesting the EOB for an individual Medicare enrollee.
EOB Claim types and parameters
Claim Type | Type Parameter (case-sensitive) |
---|---|
Carrier | carrier |
Durable Medical Equipment | dme |
Home Health Agency | hha |
Hospice | hospice |
Inpatient | inpatient |
Outpatient | outpatient |
Skilled Nursing Facility | snf |
Prescription Drug Event | pde |
Use the query parameter to request a specific claim type.
Example: ?type=pde
To request multiple claim types, use a comma-separated list of values for the TYPE parameter. If multiple codes are specified, EOBs matching all of those claim types will be returned.
Example:
{baseURL}/ExplanationOfBenefit?patient=123&type=carrier,dme,hha,hospice,inpatient,outpatient,snf
Claim type errors
If you submit an invalid combination of claim types or use the wrong case you’ll get an error response with a status code of 400 Bad Request
.
Query by “lastUpdated” Field
The HL7 FHIR specification provides a Meta section in each resource. The lastUpdated
field represents the date and time of the last update and is supplied with a FHIR instant datatype
YYYY-MM-DDThh:mm:ss.sss+zz:zz.
The HL7 FHIR specification also provides a _lastUpdated query
parameter for the search operations on the endpoints. By using the _lastUpdated
query parameter, you can request records that have changed before or after a specific date. If you keep track of the date of a previous request, you can request just the changes since your previous request. The format of this request would be:
{baseURL}/Patient?_id=-20000000001112&_lastUpdated=gt2020-02-13T08:00:00-05:00
Do not use dates before 2020-02-12 with the _lastUpdated parameter
.
The Blue Button API supports operators for less than (lt), greater than (gt), less than or equal (le), and greater than or equal (ge) the specified instant. You can also specify a time interval by using two _lastUpdated parameters
like this:
{baseURL}/ExplanationOfBenefit?patient=Patient/-20000000001112&_lastUpdated=gt2020-02-13T08:00:00-05:00&_lastUpdated=lt2020-02-14T08:00:00-05:00
Production API access
In order to gain production access, an organization should start by reviewing the Terms of Service and production access user guide. Once an organization believes it is fulfilling all the requirements detailed in the guide and is adherent to the terms of service, they should email BlueButtonAPI@cms.hhs.gov to set up a production access demonstration meeting with the CMS team.
Implementation guides
HL7 FHIR Common Payer Consumer Data Set (CPCDS)
Implementation Guide: Version 1.0.0, Date 2020-11-23
This IG describes the CARIN Alliance Blue Button 2.0 Framework and Common Payer Consumer Data Set (CPCDS), providing a set of resources that payers can exchange with third-parties to display to consumers via a FHIR-based API. This IG will help Medicare, Medicaid, CHIP, BHP standard health plans, and QHP issuers on the FFEs share adjudicated claims and encounter data via the Patient Access API discussed in section II.A. of this proposed rule. It includes data elements and coding instructions each impacted payer can use to prepare and share the specified data.
HL7 FHIR CARIN - v2 Artifacts Summary
Implementation Guide: Version 1.0.0, Date 2020-11-23
The purpose of this IG is to outline the different artifacts released by CARIN for v2. The artifacts contain code explanations and benefits for the different EOB Profiles.
HL7 FHIR CARIN – BlueButton GitHub IG
Github Version 0.1.13, Date 2020-11-23
This implementation guide describes the CARIN Blue Button® Framework and Common Payer Consumer Data Set (CPCDS), providing a set of resources that payers can display to consumers via a FHIR API.
1 Jama Health Forum, “Addressing Challenges in Primary Care—Lessons to Guide Innovation” https://jamanetwork.com/journals/jama-health-forum/fullarticle/2795471, August 19, 2022
Back to top