Skip to main content
U.S. flag

An official website of the United States government

Return to Search

Blue Button API 2.0 documents

Guidance for Blue Button Blue Button API 2.0 documents

Final

Issued by: Centers for Medicare & Medicaid Services (CMS)

Issue Date: June 01, 2012

The CMS Blue Button API:

  • Enables a developer to register a beneficiary-facing application
  • Enables a beneficiary to grant an application access to four years of their Part A, B, and D claims data
  • Uses the HL7 FHIR standard for beneficiary data and the OAuth 2.0 standard for beneficiary authorization

Authorization

To use the Blue Button OAuth 2 a developer must register their application.

A registered application is given a client ID and a client secret. The secret should only be used if it can be kept confidential, such as communication between your server and the Blue Button API. Otherwise the Client Application Flow may be used.

Scopes

Access tokens have a scope, which defines what the access token can do and what resources it can access. For our purposes, scopes are primarily utilized to give Medicare beneficiaries more granular choice over what data they would like to share with applications. The Blue Button 2.0 API has implemented HL7 FHIR Scopes to manage access to beneficiary data. They look like this:

patient/Patient.read
patient/Coverage.read
patient/ExplanationOfBenefit.read

From the OpenID Connect specification we support:

profile

This gives access to the /v1/connect/UserInfo Endpoint.

Our OAuth screen gives beneficiaries the ability to choose whether or not to share their demographic information. Your application will need to handle the return of a 403 status code from the /v1/fhir/Patient and /v1/connect/userinfo endpoints.

The OAuth screen with a choice for benes to share or withhold certain demographic information

If the beneficiary declines to share information that your application needs to function, you may display a message explaining why that information is needed and request reauthorization, or handle the collection of that information elsewhere within your application.

The default selection when a beneficiary reaches the authorization screen will be to share all data, including demographic data, with your application. If a beneficiary makes a selection as to whether or not they want to share demographic data with your application and later decides they want to change that selection, they’ll need to be taken through the authorization flow again to make a different choice from the OAuth screen.

Ensuring you still get the data you need

Take the time to ensure that you have fallbacks in place if you are unable to access the patient or userinfo endpoints.

For example, if you are getting the patient_ID from the v1/fhir/Patient endpoint, we recommend getting that identifier from the initial authorization response, or another resource like ExplanationOfBenefit or Coverage.

Explanation of needed data to Medicare Beneficiaries

If information limited by a scope is required for your application to properly function and it is not possible to get the information in another endpoint, we recommend providing an explanation about why certain data is needed in your user flow.

For example, if you use demographic information to help beneficiaries autofill tedious data-entry, you might want to explain that benefit before they reach the authorization screen. It is essential, however, that you give beneficiaries the full picture. If they do share that data with you for one-time data entry, they should know how long you keep it and if it is used for any other purposes.

Native Mobile App Support

Native Mobile App Support follows the RFC 8252 - OAuth 2.0 for Native Apps authentication flow utilizing the PKCE extension and enables a custom URI scheme redirect.

The implementation of the RFC 8252 specification enables developers to build mobile applications without requiring a proxy server to route redirect calls to their mobile app.

The PKCE extension provides a technique for public clients to mitigate the threat of a “man-in-the-middle” attack. This involves creating a secret that is used when exchanging the authorization code to obtain an access token.

PKCE uses a code challenge that is derived from a code-verifier. The standard supports two styles of code challenge:

  • plain
  • S256

However, Blue Button 2.0 only supports the “S256” style code challenge.

Where the:  

codechallenge = BASE64URL-ENCODE(SHA256(ASCII(codeverifier)))

The following additional parameters and values are sent as part of the OAuth2.0 Authorization Request:

  • code_challenge
  • codechallengemethod = “S256”

More details can be found about this flow on OAuth.com. Check out this link: Protecting Mobile Apps with PKCE - OAuth 2.0 Servers

Registering Your App for Mobile App Support

When you register your application in the Blue Button 2.0 Developer Sandbox, you will want to specify a unique custom URI scheme. This should be a unique value that will not conflict with other custom URI schemes implemented on a user’s mobile device.

We recommend that you define your custom URI scheme using a reverse domain name notation. As we developed our own testing application, we implemented a custom URI scheme of:

  • gov.cms.bluebutton.oauthtester

This equated to an oauthtester subdomain for the bluebutton.cms.gov domain.

The reverse DNS style custom URI scheme should then be coupled with the re-direct path on the mobile device that will handle the call back from the Blue Button 2.0 API.

For example:

tld.app.subdomain[.subsubdomain]:/callback/path/endpoint

A coding example of an OAuth 2.0 and PKCE flow is available here: Authorization Code with PKCE Flow - OAuth 2.0 Playground

The Blue Button 2.0 engineering team has also created a sample Android application. You can review or fork the code here: https://github.com/CMSgov/bluebutton-sample-client-android

Redirect_URI

When creating an Application in the sandbox a redirect URI is required. This is the API endpoint on your system that receives the callback from the Blue Button 2.0 API after a beneficiary is passed to the Blue Button 2.0 API to authorize your application. 

Multiple redirect URIs can be entered in the Redirect_URI field. Each entry should be separated by a space or newline.

A Redirect_URI follows this format:

URLprotocol://[sub-domain.]domain_name[:port]/path

URL Protocol

Three URL protocols are supported, depending on the purpose:

  • http:// protocol
  • https:// protocol
  • custom_url:// protocol

http:// protocol

(Works in: Sandbox only)

The http:// format is only accepted in the sandbox environment. It is typically used by developers for local testing by using http://localhost/ however, any domain name can be used.  

https://protocol

(Works in: Sandbox Production)

The https:// format is used for secure communication and is required for all applications in the production environment unless the application is using the Mobile OAuth method for handling callbacks.

custom_url:// protocol

(Works in: Sandbox Production)

The custom_url protocol is used by mobile applications to handle communications directly with your application on a mobile device.

If you are using Mobile OAuth support for communication directly with a mobile device the custom_url should follow this format:

Top-level.domain(TLD).domain-name[.sub-domain][.app_name]

For example, if the Blue Button 2.0 team created an application we might create a custom_url of:

gov.cms.bluebutton.oauthtester

This would then be incorporated into a redirect URI entry. Here is an example:

gov.cms.bluebutton.oauthtester:8080//bluebutton_app/callback.html

Web Application Flow

To use this flow your application should be registered with Client Type set to confidential and Grant Type set to authorization-code.

Request authorization from user

To allow a user to authorize your application, direct them to Blue Button’s authorize endpoint. The request must include the response_type set to code, your application’s client_id, and your application’s redirect_uri. An optional state field that your application can use to identify the authorization request is recommended.

https://sandbox.bluebutton.cms.gov/v1/o/authorize/?client_id=swBu7LWsCnIRfu530qnfPw1y5vMmER3lAM2L6rq2 &redirect_uri=http://localhost:8080/testclient/callback &response_type=code &state=8e896a59f0744a8e93bf2f1f13230be5

Exchange code for token

After visiting the authorization page a user will be redirected back to the redirect_uri registered with your application.

For example if the redirect_uri is http://localhost:8080/testclient/callback BlueButton will redirect with this request.

GET http://localhost:8080/testclient/callback?code=TSjqiZCdJwGyytGjz2GzziPfHTJ6z2 &state=8e896a59f0744a8e93bf2f1f13230be5

Your application can now exchange the code provided in the redirected request for a full token. Send a POST request to the BlueButton token endpoint providing the code, the application’s client_id, client_secret, and redirect_uri. Your request must also specify the grant_type which should always be authorization_code for this flow.

curl -X POST "https://sandbox.bluebutton.cms.gov/v1/o/token/" \ -u "swBu7LWsCnIRfu530qnfPw1y5vMmER3lAM2L6rq2:" \ -d "code=TSjqiZCdJwGyytGjz2GzziPfHTJ6z2 &grant_type=authorization_code &redirect_uri=http://localhost/testclient/callback"

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" }

Client Application Flow

To use this flow your application should be registered with Client Type set to public and Grant Type set to implicit.

Request authorization from user

To use the client application flow direct the user to the Blue Button authorization endpoint with the response_type parameter set to token.

https://sandbox.bluebutton.cms.gov/v1/o/authorize/?client_id=swBu7LWsCnIRfu530qnfPw1y5vMmER3lAM2L6rq2 &redirect_uri=http://localhost:8080/testclient/callback &response_type=token &state=8e896a59f0744a8e93bf2f1f13230be5

If the user authorizes your application they will be redirected back to the redirect_uri of your application. The request will include an access_token in the fragment.

http://localhost:8080/testclient/callback#access_token=KCHMTX5VHNAXYGYv38eG2RLAX4hL6R &expires_in=35849.875807 &token_type=Bearer &scope=profile+patient%2FPatient.read+patient%2FExplanationOfBenefit.read+patient%2FCoverage.read &state=8e896a59f0744a8e93bf2f1f13230be5

Below you will find a sample account you can use to test your Blue Button OAuth implementation. This account mimics a valid MyMedicare.gov account but has reduced functionality. For example, you cannot test “Forgot Password” flow.

Jane Doe Username: BBUser29999 Password: PW29999!


Core Resources

Base Request URL:

https://sandbox.bluebutton.cms.gov

FHIR Resources:

  • Explanation of Benefit
  • Patient
  • Coverage

UserInfo:

  • Get User Profile from an Authorization Token

As a security measure the date of birth, SSN, and HICN will not be provided by the CMS Blue Button API.

We use FHIR Extensions in our API responses.

Explanation of Benefit FHIR Resource

/v1/fhir/ExplanationOfBenefit/?patient=[fhir_id]

The above URL returns all of the beneficiary’s Explanation of Benefit (sometimes referred to as an episode of care) records as an ExplanationOfBenefit FHIR Resource. The bulk of a beneficiary’s data is contained within these ExplanationOfBenefit FHIR resources.
Each one can be thousands of lines long.

curl --header "Authorization: Bearer AUTHORIZATION TOKEN" "https://sandbox.bluebutton.cms.gov/v1/fhir/ExplanationOfBenefit/?patient=-20140000008325"

That API call will return an Explanation of Benefit that contains many FHIR resources and is typically thousands of lines long.

Learn more about the Explanation of Benefits FHIR resource in Blue Button

{ "fullUrl": "https://sandbox.bluebutton.cms.gov/v1/fhir/ExplanationOfBenefit/carrier-22011027731", "resource": { "resourceType": "ExplanationOfBenefit", "id": "carrier-22011027731", "contained": [ { "resourceType": "ReferralRequest", "id": "1", "status": "completed", "subject": { "reference": "Patient/-20140000008325" }, "requester": { "agent": { "identifier": { "system": "http://hl7.org/fhir/sid/us-npi", "value": "999999999999" } } }, "recipient": [ { "identifier": { "system": "http://hl7.org/fhir/sid/us-npi", "value": "999999999999" } } ] } ] ...this is only a subset of the entire output...

Patient FHIR Resource

HTTP GET /v1/fhir/Patient/[fhir_id]

The above URL returns the beneficiary’s demographics and other administrative information as a Patient FHIR Resource. This information is mostly contact information, not medical data.

curl --header "Authorization: Bearer AUTHORIZATION TOKEN" "https://sandbox.bluebutton.cms.gov/v1/fhir/Patient/-20140000008325" { "resourceType": "Patient", "id": "-20140000008325", "extension": [ { "url": "https://bluebutton.cms.gov/resources/variables/race", "valueCoding": { "system": "https://bluebutton.cms.gov/resources/variables/race", "code": "1", "display": "White" } } ], "identifier": [ { "system": "http://bluebutton.cms.hhs.gov/identifier#bene_id", "value": "-20140000008325" }, { "system": "http://bluebutton.cms.hhs.gov/identifier#hicnHash", "value": "2025fbc612a884853f0c245e686780bf748e5652360ecd7430575491f4e018c5" } ], "name": [ { "use": "usual", "family": "Doe", "given": [ "Jane", "X" ] } ], "gender": "unknown", "birthDate": "2014-06-01", "address": [ { "district": "999", "state": "15", "postalCode": "99999" } ] }

Download a sample Patient FHIR Resource

Coverage FHIR Resource

HTTP GET /v1/fhir/Coverage/?beneficiary=[fhir_id]

The above URL returns the beneficiary’s Coverage information as an Coverage FHIR Resource.

curl --header "Authorization: Bearer AUTHORIZATION TOKEN" "https://sandbox.bluebutton.cms.gov/v1/fhir/Coverage/?beneficiary=-20140000008325" { "fullUrl": "https://sandbox.bluebutton.cms.gov/v1/fhir/Coverage/part-a-20140000008325", "resource": { "resourceType": "Coverage", "id": "part-a-20140000008325", "extension": [ { "url": "https://bluebutton.cms.gov/resources/variables/ms_cd", "valueCoding": { "system": "https://bluebutton.cms.gov/resources/variables/ms_cd", "code": "10", "display": "Aged without end-stage renal disease (ESRD)" } }, { "url": "https://bluebutton.cms.gov/resources/variables/orec", "valueCoding": { "system": "https://bluebutton.cms.gov/resources/variables/orec", "code": "0", "display": "Old age and survivor’s insurance (OASI)" } }, { "url": "https://bluebutton.cms.gov/resources/variables/esrd_ind", "valueCoding": { "system": "https://bluebutton.cms.gov/resources/variables/esrd_ind", "code": "0", "display": "the beneficiary does not have ESRD" } }, { "url": "https://bluebutton.cms.gov/resources/variables/a_trm_cd", "valueCoding": { "system": "https://bluebutton.cms.gov/resources/variables/a_trm_cd", "code": "0", "display": "Not Terminated" } } ] ...this is only a subset of the entire output...

Compress Resources for more efficient data transfers

To improve the performance when transferring large data resources it is possible to turn on compression. 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. If the original uncompressed size of the payload is less than 1 kb, we will not apply gzip compression to our response. Therefore, developers should ensure their applications handle this scenario gracefully by checking for the Content-Encoding: gzip response header before trying to decompress.

Download a sample Coverage FHIR Resource

Get User Profile for an Authorization Token

HTTP GET /connect/userinfo

The UserInfo Endpoint is an OAuth 2.0 Protected Resource.The above URL fetches the fictitious beneficiary’s basic account information given an Authorization Token. This is most often used when creating an account within your application. An HTTP GET is called and the response is returned as JSON.

curl --header "Authorization: Bearer AUTHORIZATION TOKEN" "https://sandbox.bluebutton.cms.gov/v1/connect/userinfo" { "sub": "fflinstone", "prefered_username": "fflinstone", "given_name": "Fred", "family_name:, "Flinstone, "name": "Fred Flinstone", "email": "pebbles-daddy@example.com", "created": "2017-11-28", "patient": "123456789", }

More Efficient Data Queries

Query by Type

Many developers are interested in specific claim types, such as PDE. The query by type feature will allow applications to request just those claims. This will enable applications to process and download data more quickly and efficiently.

ExplanationOfBenefit resources fall into 8 types:

  • CARRIER
  • DME
  • HHA
  • HOSPICE
  • INPATIENT
  • OUTPATIENT
  • PDE
  • SNF

By default, the FHIR API returns all of these claim types when requesting the EOB for a beneficiary. You can use the Type query parameter to request specific claim types.

For example, to request only Part D drug claims, add the query parameter:

?type=pde

To request multiple claim types, a list of comma-separated values can be given for the TYPE parameter.

If multiple codes are specified, EOBs matching all of those claim types will be returned:

/v1/fhir/ExplanationOfBenefit?patient=123&type=carrier,dme,hha,hospice,inpatient,outpatient,snf

The full list of claim types are:

carrier

https://bluebutton.cms.gov/resources/codesystem/eob-type|carrier

pde

https://bluebutton.cms.gov/resources/codesystem/eob-type|pde

dme

https://bluebutton.cms.gov/resources/codesystem/eob-type|dme

hha

https://bluebutton.cms.gov/resources/codesystem/eob-type|hha

hospice

https://bluebutton.cms.gov/resources/codesystem/eob-type|hospice'

inpatient

https://bluebutton.cms.gov/resources/codesystem/eob-type|inpatient’

outpatient

https://bluebutton.cms.gov/resources/codesystem/eob-type|outpatient’

snf

https://bluebutton.cms.gov/resources/codesystem/eob-type|snf

It is important to use lower case when requesting a claim type. If you submit an invalid combination of claim types or use the wrong case you’ll see a message like this:

{ “detail”: “not a valid value” }

The status code for this message is a 400 Bad Request.

Query by Type Examples:

In the sandbox there are synthetic beneficiaries with three of the eight claim types:

  • carrier
  • inpatient
  • pde

Let us take a synthetic beneficiary record:

Username: BBUser20023 and Password PW20023!

The FHIR ID for this beneficiary is -20140000000024

Let us do a regular ExplanationOfBenefit request:

https://sandbox.bluebutton.cms.gov/v1/fhir/ExplanationOfBenefit/

This bundle identifies 148 claims, returning the first 10. Here is how the start of the bundle will look:

{ “resourceType”: “Bundle”, “id”: “9562c9b7-df79-419a-a94b-ef8cc9347e0e”, “meta”: { “lastUpdated”: “2019-11-05T22:05:48.257-05:00” }, “type”: “searchset”, “total”: 148, “link”: [ { “relation”: “first”, “Url”: “https://sandbox.bluebutton.cms.gov/v1/fhir/ExplanationOfBenefit?_count=10&startIndex=0&patient=-20140000000024” }, …

There are three claim types in this beneficiary’s record:

  • Carrier (44)
  • Inpatient (1)
  • PDE (103)

The queries to request each claim type individually would be:

Carrier Claims

https://sandbox.bluebutton.cms.gov/v1/fhir/ExplanationOfBenefit/?type=carrier

Or

https://sandbox.bluebutton.cms.gov/v1/fhir/ExplanationOfBenefit/?type=https://bluebutton.cms.gov/resources/codesystem/eob-type|carrier

Inpatient Claims

https://sandbox.bluebutton.cms.gov/v1/fhir/ExplanationOfBenefit/?type=inpatient

Or

https://sandbox.bluebutton.cms.gov/v1/fhir/ExplanationOfBenefit/?type=https://bluebutton.cms.gov/resources/codesystem/eob-type|inpatient

PDE Claims Since many of our developers are interested in the Part D drug claims it is now possible to query for only PDE-type claims.

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.