Authorization
The Blue Button 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
The Blue Button 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
Proof Key for Code Exchange (PKCE) extension usage
To improve the security of your application, we require using the Proof Key for Code Exchange (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 uses a code challenge that is derived from a code-verifier. The Blue Button API supports the S256 style code challenge:
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(codeverifier)))
When using PKCE, send the following additional parameters and values as part of the OAuth 2.0 Authorization Request:
code_challengecode_challenge_method = "S256"
These required parameters will be used in the examples in the following sections. To learn more about this flow, refer to OAuth.com.
User authorization
To allow a user to authorize your application, direct them to the Blue Button 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&scope=openid%20profile%20patient%2FPatient.rs%20patient%2FCoverage.rs%20patient%2FExplanationOfBenefit.rs&state=8e896a59f0744a8e93bf2f1f13230be5&code_challenge=Ds-QWGn89NeT5jpmHLPA3z3oy59hOkbA03B1QS13_CY&code_challenge_method=S256Note: The authorization in the example is started by an HTTP GET operation. For SMART App Launch compliance, POST style authorization is also supported.
Parameters: Authorization code request
| Parameter | Description |
|---|---|
Required | The |
Optional | Authorization screen language selection. Use |
Required | The callback URL of your application. The user will be directed to this URL after authorizing your application. |
Required | Supported response type: |
Optional | A list of scopes being requested. Use URL encoding for special characters, including using an encoded space character ( |
Required | A random string used to protect against request forgery attacks. The string shall have an entropy of at least 122 bits, and a randomly-generated UUID is preferred. If the state parameter is under 16 characters, an error will be returned. |
Required | Required for PKCE. Value computed from a generated code verifier value using |
Required | Required for PKCE. Only |
Authorization screen language selection
The Blue Button 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 authorization screens, add the optional
langparameter to your/authorizerequest. Valid values areen(English) andes(Spanish). For example:
https://sandbox.bluebutton.cms.gov/v2/o/authorize/?lang=es- If the
langparameter is omitted or is set to a value other thanenores, the API server will next check theAccept-LanguageHTTP header in the/authorizerequest.- 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-Languagevalue 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
langparameter orAccept-Languageheader, 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 Blue Button 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, the Blue Button API will redirect with this request:
GET http://localhost:8080/testclient/callback?code=TSjqiZCdJwGyytGjz2GzziPfHTJ6z2&state=8e896a59f0744a8e93bf2f1f13230Your application can now exchange the code provided in the redirected request for an access token.
To retrieve an access token, POST to the Blue Button /token endpoint providing the code with the following parameters:
client_idclient_secretredirect_urigrant_type: authorization_codecodecode_verifier
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&code_verifier=zlGzSLRQz6HrTpd3TvEraYoVPW2cknzu4tUk6wHaPFw"Token response
{ "access_token": "oQlduHNr09GKCU506GOgp8OarrAy2q", "expires_in": 16768.523842, "token_type": "Bearer", "scope": "profile patient/Patient.rs patient/ExplanationOfBenefit.rs patient/Coverage.rs", "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 Blue Button 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 Blue Button API /token endpoint with the following parameters:
client_idclient_secretgrant_type: refresh_tokenrefresh_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.rs patient/Coverage.rs patient/ExplanationOfBenefit.rs", "refresh_token": "7x0VkRQlRU4fRNCQL2vh239nIyucgw", "patient": "-20140000000001", "access_grant_expiration": "2025-09-05 19:17:53Z"}Revoking tokens
Developers can revoke an enrollee’s previously granted access. To invalidate the ability to generate new access tokens without authorization, developers can revoke an access token and the underlying data access grant.
To revoke an access token, POST to the Blue Button API /revoke endpoint with the following parameters:
client_idclient_secrettoken
cURL command
curl -X POST --url 'https://bluebutton.cms.gov/v2/o/revoke/' \ --header 'content-type: application/x-www-form-urlencoded' \ -u <client_id>:<client_secret> \ -d 'token=oQlduHNr09GKCU506GOgp8OarrAy2q'Response
Valid requests to the /revoke endpoint will always result in a 200 response, regardless of whether or not the requested token exists.
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 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 Blue Button API /expire_authenticated_user endpoint with the following parameters:
client_idclient_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:
HTTP/1.1 200 OKCommon 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.
Scopes
Scopes define the API endpoints that your application is allowed to access. The Blue Button API uses HL7 FHIR Scopes to manage access to Medicare enrollee data.
Blue Button API HL7 FHIR
| Scope | Permission |
|---|---|
patient/Patient.rs or patient/Patient.read | Read and search my general patient and demographic information |
patient/Coverage.rs or patient/Coverage.read | Read and search my Medicare and supplemental coverage information |
patient/ExplanationOfBenefit.rs or patient/ExplanationOfBenefit.read | Read and search my Medicare claim information |
launch/patient | Patient launch context |
openid | Retrieve information about the current logged-in user |
profile | 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.