Optimizing your app for production
- Tested against multiple synthetic users (not just one)
- Handling pagination for large EOB bundles
- Handling token refresh and expiration
- Handling cases where the user denies demographic access
- Using gzip compression
- Filtering by claim type where possible
- Consent flow meets CMS requirements
- Privacy policy and terms of service finalized
Optimize your queries
Filter with query parameters
The most effective optimization is to request less data. Blue Button supports several server-side parameters for filtering, so you avoid transferring claims you’ll discard anyway.
Increase the page size. Search results default to 10 per page, with a maximum of 50. Setting _count=50 cuts your round trips by a factor of five:
/ExplanationOfBenefit?count=50
Values above 50 are rejected with a validation error.
Filter by claim type. Request only the claim types your app uses. Accepts one or more comma-separated values: carrier, pde, dme, hha, hospice, inpatient, outpatient, snf:
/ExplanationOfBenefit?type=carrier,pde
You can also use fully qualified tokens, like https://bluebutton.cms.gov/resources/codesystem/eob-type|carrier. Values are case-insensitive.
Filter by date of service. Use service-date to bound results by when care was delivered, rather than when the record changed. It supports the same operators as _lastUpdated:
/ExplanationOfBenefit?service-date=ge2025-01-01\&service-date=lt2026-01-01
Use service-date when you care about the care period, and _lastUpdated when you care about what’s changed since your last sync. They’re independent and can be combined.
Compress resources for more efficient data
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/htmltext/plainapplication/jsonapplication/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 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 only the changes since that request. The format of this request would be: /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: /ExplanationOfBenefit?patient=Patient/-20000000001112&lastUpdated=gt2020-02-13T08:00:00-05:00&lastUpdated=lt2020-02-14T08:00:00-05:00.
CARIN IG compliance
The Blue Button API aligns with the CARIN Consumer Directed Payer Data Exchange Implementation Guide. If your app works with other payer APIs, following the CARIN IG ensures interoperability.
Key things to know:
- CARIN uses supportingInfo instead of extensions for many data points
- Blue Button provides data in both formats for backward compatibility
- CARIN defines standard code systems for adjudication, claim types, and supporting info categories
If you’re building for Blue Button only, you don’t need to study the full IG, but awareness of it helps if you plan to integrate with other FHIR APIs.
Reference:
Testing checklist
Before your production demo, test these scenarios:
- Multiple users Test with several synthetic users (use the synthetic users CSV (LINK: TBD) to find users with different claim volumes)
- Large datasets Some synthetic users have hundreds of claims. Verify your pagination handles them
- Missing demographics Simulate a user who denies
patient/Patient.rsscope access - Token expiration Use the sandbox
/expireauthenticateduserendpoint (see Testing token expiration) to test expired tokens - Revoked access Test what happens when a user disconnects your app
- All claim types Verify your app handles carrier, inpatient, outpatient, PDE, DME, HHA, hospice, and SNF claims
- Error handling Test 401, 403, 404, and 429 responses
Next steps
Ready to apply? Head to the Production overview to see the application process, requirements checklist, and what to expect in the demo.