Skip to main content

Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you've safely connected to the .gov website. Share sensitive information only on official, secure websites.

How to Access Claims Data

Learn how to access claims data for both the sandbox and production environments and use Beneficiary Claims Data API (BCDA) endpoints.

The sandbox and production environments follow similar instructions. They support the same workflow, endpoints, parameters, and resource types.

Sandbox and Production environments comparison
Sandbox Production
Available to everyone via test credentials Must complete the steps for production credentials
Contains test claims data Contains real Medicare enrollee data
sandbox.bcda.cms.gov api.bcda.cms.gov

BCDA recommends using v2 of the API

This is the latest version which follows the FHIR R4 specification. REACH ACOs must use v2 for partially adjudicated claims data.

Instructions

1. Get a bearer token

You will need a bearer token to call the API. The process requires credentials, which are formatted as a client ID and client secret.

Jobs will not be interrupted when the bearer token expires. In progress and queued jobs will continue to run.

2. Start a job

Make a GET request to the /Group or /Patient endpoint to start a data export job. The examples below are sandbox curl requests to /Group. Follow along in your terminal or using a tool like Postman.

Request all resource types

By default, the GET request returns all available resource types.

GET /api/v2/Group/all/$export

Use the _type parameter to specify which resource types you’d like returned.

Request header

The header must contain your bearer token. You may receive a 401 response if your credentials are invalid or expired. Bearer must be included in the header with a capital B and followed by a space.

Authorization: Bearer {bearer_token}
Accept: application/fhir+json
Prefer: respond-async

Example curl commands to start a job

  • Combine your GET request for resources with the request header.
  • The dollar sign $ before export in the URL indicates the endpoint is an operation, rather than a CRUD interaction.
  • PowerShell users will need to replace backslash characters \ with backticks ( ` ) to properly escape the $export operation.

Remember to use the correct URL for your environment

Use sandbox.bcda.cms.gov to access the sandbox or api.bcda.cms.gov to access the production environment.

curl -X GET "https://sandbox.bcda.cms.gov/api/v2/Group/all/\$export" \
    -H "Accept: application/fhir+json" \
    -H "Prefer: respond-async" \
    -H "Authorization: Bearer {bearer_token}" \
    -i
curl -X GET "https://sandbox.bcda.cms.gov/api/v2/Group/all/\$export?_type=ExplanationOfBenefit,Patient" \
    -H "Accept: application/fhir+json" \
    -H "Prefer: respond-async" \
    -H "Authorization: Bearer {bearer_token}" \
    -i
curl -X GET "https://sandbox.bcda.cms.gov/api/v2/Group/all/\$export?_type=Patient" \
    -H "Accept: application/fhir+json" \
    -H "Prefer: respond-async" \
    -H "Authorization: Bearer {bearer_token}" \
    -i

Response example: successful request

A 202 Accepted response with a Content-Location header indicates a successful request.

Response header example

You’ll need the job ID in the Content-Location header to check your job status.

Content-Location: https://sandbox.bcda.cms.gov/api/v2/jobs/{job_id}

Response example: too many requests

A 429 Too Many Requests response can occur due to 2 reasons:

  1. Making too many HTTP requests within a period of time
  2. Trying to recreate jobs already marked as “In-Progress.” For reference, you can view both existing and past jobs using the /jobs endpoint.

Wait until the period of time specified in the Retry-After: <delay-seconds> header passes before making any more requests. This makes sure your client can adapt without manual intervention, even if the rate-limiting parameters change.

3. Check job status

Make a GET request to check the status using the job ID from step 2. You may need another bearer token if it’s been over 20 minutes since it was generated.

Request to check the job status

GET https://sandbox.bcda.cms.gov/api/v2/jobs/{job_id}

Request header

Authorization: Bearer {bearer_token}
Accept: application/fhir+json

curl command to check the job status

curl -X GET "https://sandbox.bcda.cms.gov/api/v2/jobs/{job_id}" \
    -H "Accept: application/fhir+json" \
    -H "Authorization: Bearer {bearer_token}" \
    -i

Response example: incomplete job

A 202 response indicates your job is still processing. The status will change to 200 OK when the export is complete and the data is ready for download.

202 Accepted

Response header example: incomplete job

The X-Progress will have a percentage indicating your estimated progress.

X-Progress: In Progress, 80%

Response example: completed job

You’ll receive a 200 OK response with the output URL(s) needed to download the data. In the example URLs below, 42 indicates the job ID.

There is a separate URL for each resource type requested. The following example shows a request for all resource types for adjudicated claims data.

{
  "transactionTime": "2019-12-09T20:44:01.705398Z",
  "request": "https://sandbox.bcda.cms.gov/api/v2/Group/all/$export",
  "requiresAccessToken": true,
  "output": [
    {
      "type": "ExplanationOfBenefit",
      "url": "https://sandbox.bcda.cms.gov/data/42/afd22dfa-c239-4063-8882-eb2712f9f638.ndjson"
    },
    {
      "type": "Coverage",
      "url": "https://sandbox.bcda.cms.gov/data/42/f76a0b76-48ed-4033-aad9-d3eec37e7e83.ndjson"
    },
    {
      "type": "Patient",
      "url": "https://sandbox.bcda.cms.gov/data/42/f92dcf16-63a2-448e-a12a-3bf677f966ed.ndjson"
    }
  ],
  "error": [],
  "JobID": 42
}

4. Download the data

Make a GET request to download your data using the URL(s) from step 3.

If you’re downloading from more than 1 URL, make multiple download requests concurrently to save time. Large files may take significantly longer to download.

Files expire after 24 hours

You can download these files using a new bearer token. After 24 hours, the files will expire and you will need to restart the job.

Request to download the data

GET https://sandbox.bcda.cms.gov/data/{job_id}/{file_name}

Request header: compressed data files

Request compressed data files with the optional Accept-Encoding: gzip header in your requests for faster download times. Afterward, decompress (unzip) the files into NDJSON format.

Authorization: Bearer {bearer_token}
Accept-Encoding: gzip

curl command to download the data

curl -X GET "https://sandbox.bcda.cms.gov/data/{job_id}/{file_name}" \
    -H "Accept-Encoding: gzip" \
    -H "Authorization: Bearer {bearer_token}"

If some of the data can’t be exported due to errors, details can be found at the URLs in the error field. The errors are provided in an NDJSON file as FHIR OperationOutcome resources.

Response example

By default, you’ll receive the requested data as FHIR resources in NDJSON format. Each resource type will appear as a separate, labeled file.

Test data from the sandbox contains only negative Patient IDs.

  1. ExplanationOfBenefit.ndjson
  2. Patient.ndjson
  3. Coverage.ndjson

Other BCDA endpoints

Cancel a job

Cancel any active job. If the request is successful, you’ll receive a 202 response.

Request to cancel a job

DELETE /api/v2/jobs/{job_id}

Request header

Authorization: Bearer {bearer_token}

curl command to cancel a job

curl -X DELETE "https://sandbox.bcda.cms.gov/api/v2/jobs/{job_id}" \
    -H "Accept: application/fhir+json" \
    -H "Authorization: Bearer {bearer_token}"

Request job history

Retrieve details on your organization’s historical requests, including the start and end datetime, unique ID, original valueString request, and status.

Request to retrieve all past jobs

If your organization has no jobs to return, you’ll receive a 404 ERROR response.

GET /api/v2/jobs

Request that filters jobs by end state

Supply the _status parameter to filter for jobs with a specific end state. BCDA jobs have 9 possible end states: Completed, Archived, Expired, Failed, FailedExpired, In Progress, Pending, Cancelled, and CancelledExpired.

These are how the job end states map to the 4 supported values you can receive in the response body:

  • Archived, Expired, Completedcompleted
  • FailedExpired, Failedfailed
  • Pending, In Progressin-progress
  • CancelledExpired, Cancelledcancelled

The example below is a filtered request for all past archived jobs. If any are found, the response will list the status as completed. Even so, the filter will only return archived jobs; it will exclude expired and completed jobs.

GET /api/v2/jobs?_status=Archived

Request header

Authorization: Bearer {bearer_token}
Accept: application/fhir+json
Prefer: respond-async

curl command to check the job status

curl -X GET "https://sandbox.bcda.cms.gov/api/v2/jobs" \
    -H "Accept: application/fhir+json" \
    -H "Prefer: respond-async" \
    -H "Authorization: Bearer {bearer_token}" \
    -i

Response example: completed job

The response will contain a bundle of resources for each historical job. Each resource section in the response represents a single past job request.

This example shows 1 historical job with a completed status. Since this was an unfiltered request, the job could either be archived, expired, or completed.

{
  "entry": [
    {
      "resource": {
        "executionPeriod": {
          "end": "2021-08-14T00:07:48+00:00",
          "start": "2021-08-13T00:07:48+00:00"
        },
        "identifier": [
          {
            "system": "https://bcda.cms.gov/api/v2/jobs",
            "use": "official",
            "value": "1"
          }
        ],
        "input": [
          {
            "type": {
              "text": "BULK FHIR Export"
            },
            "valueString": "GET https://bcda.test.gov/this-is-a-test"
          }
        ],
        "intent": "order",
        "resourceType": "Task",
        "status": "completed"
      }
    }
  ],
  "resourceType": "Bundle",
  "total": 1,
  "type": "searchset"
}

Request attribution status

Check your attribution status for a timestamp of when your attribution data was last updated. By comparing the timestamp to the date of your most recent job, you can determine if your organization has new claims data to download.

Request to check attribution status

GET /api/v2/attribution_status

Request header

Authorization: Bearer {bearer_token}
Accept: application/json

curl command to check attribution status

curl -X GET "https://sandbox.bcda.cms.gov/api/v2/attribution_status" \
    -H "Accept: application/json" \
    -H "Authorization: Bearer {bearer_token}"

Response example

If BCDA has never ingested an attribution or runout file for your organization, you’ll receive a 404 not found response.

{
  "ingestion_dates": [
    {
      "type": "last_attribution_update",
      "timestamp": "2020-12-22 22:31:40.397916+00"
    },
    {
      "type": "last_runout_update",
      "timestamp": "2020-12-22 22:31:40.397916+00"
    }
  ]
}

Check API status

Retrieve metadata to view the current status and release or FHIR version of the API. A bearer token, and therefore a response header, is not required.

Request to check API status

GET /api/v2/metadata

curl command to check API status

curl "https://sandbox.bcda.cms.gov/api/v2/metadata"

Response example

The response will contain a FHIR Capability Statement resource in JSON format. The example below shows the API is active, using FHIR Release 4.0.1, and that the API release version is r231.

{
  "date": "2024-09-09T13:35:05+00:00",
  "fhirVersion": "4.0.1",
  "format": [
    "application/json",
    "application/fhir+json"
  ],
  "implementation": {
    "description": "The Beneficiary Claims Data API (BCDA) enables Accountable Care Organizations (ACOs) participating in the Shared Savings Program to retrieve Medicare Part A, Part B, and Part D claims data for their prospectively assigned or assignable beneficiaries.",
    "url": "https://sandbox.bcda.cms.gov"
  },
  "instantiates": [
    "https://prod.bfd.cms.gov/v2/fhir/metadata",
    "https://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data"
  ],
  "kind": "instance",
  "publisher": "Centers for Medicare & Medicaid Services",
  "resourceType": "CapabilityStatement",
  "rest": [
    {
      "interaction": [
        {
          "code": "batch"
        },
        {
          "code": "search-system"
        }
      ],
      "mode": "server",
      "resource": [
        {
          "operation": [
            {
              "definition": "https://hl7.org/fhir/uv/bulkdata/OperationDefinition/patient-export",
              "name": "patient-export"
            }
          ],
          "type": "Patient"
        },
        {
          "operation": [
            {
              "definition": "https://hl7.org/fhir/uv/bulkdata/OperationDefinition/group-export",
              "name": "group-export"
            }
          ],
          "type": "Group"
        }
      ],
      "security": {
        "cors": true,
        "extension": [
          {
            "extension": [
              {
                "url": "token",
                "valueUri": "https://sandbox.bcda.cms.gov/auth/token"
              }
            ],
            "url": "https://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris"
          }
        ],
        "service": [
          {
            "coding": [
              {
                "code": "OAuth",
                "display": "OAuth",
                "system": "https://terminology.hl7.org/CodeSystem/restful-security-service"
              }
            ],
            "text": "OAuth"
          }
        ]
      }
    }
  ],
  "software": {
    "name": "Beneficiary Claims Data API",
    "releaseDate": "2024-09-09T13:35:05+00:00",
    "version": "r231"
  },
  "status": "active"
}
Looking for U.S. government information and services?
Visit USA.gov