Consumer Pricing API

04

Personalized Estimates

Learn how our API calculates a patient’s actual out-of-pocket cost for expensive, shoppable procedures. We layer a member’s current benefits and accumulators (deductible and out-of-pocket maximum) on top of our Standard Service Packages to calculate what they would actually owe.

Why this matters

A personalized estimate tells a patient what they will actually pay, so they can compare their real out-of-pocket costs before they book care. This matters most for patients on high-deductible plans facing coinsurance, or on plans with variable copay structures (such as lower copays at ambulatory surgery centers). We built this for shoppable procedures (e.g. colonoscopies) where a patient will actually compare options, and where a delta of a few hundred dollars can meaningfully impact their decision.

Our personalized estimates are best used for the following types of encounters:

  • MRIs, CT, and imaging
  • Colonoscopies & endoscopies
  • Surgeries & ambulatory procedures

What you can build

The Consumer Pricing API can power your conversational AI patient experiences. Today these experiences return generic ranges that aren’t actionable. With the Consumer Pricing API, you can deliver the true cost of care, personalized to the patients’ insurance coverage.

Here are other ways to use personalized estimates via our API/MCP:

  • Care navigation platform: Reveal a patient’s real after-insurance cost directly in your user experience.
  • Digital Health companies: Show a patient what they’ll pay before booking their appointment.
  • Referrals in EHRs: Surface estimates for patients alongside provider referrals

Networks and plans with cost share

Cost share calculations, i.e. how we generate personalized estimates, are live for a subset of payers and networks today and are not available yet for every network the API supports. We return negotiated rates for a much broader set of payers and networks, but we are expanding cost share coverage on a rolling basis. View the table below for a list of networks live today.

Aetna POS
Anthem CA PPO
Anthem NY (Empire) PPO
Blue Cross Blue Shield (30 plans)
  • BCBS of Alabama – Preferred PPO
  • BCBS of Arizona – PPO
  • BCBS of Arkansas – True Blue PPO
  • BCBS of Illinois – PPO
  • BCBS of Maryland & DC (CareFirst) – PPO
  • BCBS of Massachusetts – PPO
  • BCBS of Michigan – PPO
  • BCBS of Minnesota – Aware PPO
  • BCBS of Mississippi – Preferred Provider Network
  • BCBS of Nebraska – Networkblue PPO
  • BCBS of New Jersey (Horizon) – Omnia
  • BCBS of New Mexico – Preferred Provider Organization PPO
  • BCBS of North Carolina – Preferred Provider Network
  • BCBS of North Dakota – PPO
  • BCBS of Pennsylvania (Independence) – KHPE Commercial HMO/POS
  • BCBS of Pennsylvania (Independence) – QCC Commercial PPO/EPO
  • BCBS of Rhode Island – PPO
  • BCBS of South Carolina – Preferred Blue
  • BCBS of Tennessee – Preferred
  • BCBS of Texas – PPO
  • BCBS of Vermont – PPO
  • Blue Cross of Idaho – PPO
  • Blue Shield of California – PPO
  • Capital Blue Cross – PPO
  • Premera Blue Cross – Alaska Heritage Network
  • Premera Blue Cross – PBC PPO (Heritage) Network
  • Regence Blue Cross Blue Shield – ID PPO
  • Regence Blue Cross Blue Shield – OR PPO
  • Regence Blue Cross Blue Shield – UT PPO
  • Regence Blue Cross Blue Shield – WA PPO
Cigna National OAP
United Healthcare Choice Plus

How it works

Standard plan mapping diagram

We build each service into a Standard Service Package so every provider is priced on the same, apples-to-apples definition of the service and its ancillary components. See how we build packages on the pricing methodology page.

To turn a negotiated rate into a personalized estimate, we map the member's plan benefits to that package using our open-source benefit mapping logic, then apply their year-to-date accumulators (deductible and out-of-pocket maximum).

The benefit mapping logic takes the codes that would appear on a claim, or in this case within our Standard Service Package (SSP), and identifies the appropriate benefit category(s) to trigger. This logic contemplates bundling methodologies and other plan design nuances that impact downstream cost-share application (such as preventive benefits).

Plan-specific benefits and patient accumulator data are retrieved by running a 270/271 eligibility check with the member's payer, which returns their current benefits, eligibility, and accumulators, applied based on the service, provider, and place of service in question.

The EDI 270/271 transaction uses X12 language and operates on Service Type Categories (STCs) rather than procedure codes. Turquoise's logic bridges this gap: we translate STCs into the benefit adjudication logic at the billing code level. In practice, this means taking a Service Type Category, say STC 05 ("Labs"), and determining which CPT/HCPCS codes would be subject to that category's cost-share treatment.

See it in action

Let’s say Jane wants to know what a colonoscopy will cost her at Inova Fairfax Hospital, and she has insurance through Cigna under the National OAP network. Here is how you would use the API, with one call to POST /v3/personalized-estimates, to generate an estimate for her.

Choose what you’re pricing

Start with a package and a network. For Jane, that is the colonoscopy package priced against her Cigna National OAP plan. Because she only cares about Inova Fairfax, we also pass provider_id to narrow the results to that one hospital. Omit provider_id to get every provider and compare. These are the same inputs you would use for a negotiated-rate lookup (POST /v3/prices/query).

FieldMeaning
package_id (required)The service you are pricing, e.g. a screening colonoscopy.
pricing (required)type: "negotiated" with a network_id.
provider_idOptional. Narrow the results to a single provider, like Inova Fairfax.
locationOptional. Narrow by near, within, or zip.

Add the member’s insurance details

The member_eligibility block identifies the patient we generate the estimate for. In our case, Jane. This is PHI, so every request must attest that the patient consented to the check.

FieldMeaning
first_name, last_nameThe patient’s legal name.
date_of_birthThe patient’s date of birth.
member_idThe ID on the patient’s insurance card.
consent_attestedMust be true — your attestation that the patient consented.

The eligibility block is PHI. See HIPAA compliance for how it must be handled.

Call the endpoint

Now we send the package (colonoscopy), the pricing target (Cigna National OAP and Inova Fairfax Hospital), and the member's eligibility (Jane's insurance details) to POST /v3/personalized-estimates.

curl --request POST https://api.turquoise.health/v3/personalized-estimates \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "package_id": "pkg_01hxyz",
    "pricing": { "type": "negotiated", "network_id": "482910" },
    "provider_id": "prov_8821",
    "member_eligibility": {
      "first_name": "Jane", "last_name": "Doe",
      "date_of_birth": "1990-01-01", "member_id": "MBR-000-EXAMPLE",
      "consent_attested": true
    }
  }'

Note: the first query for a given patient returns a 202 “Eligibility check in progress, retry after a short delay”. The real-time eligibility check can take a few seconds to run. Subsequent queries for the same patient return a 200 with the information requested, and are faster because we cache the eligibility response.

Read the estimate

The response will contain a list of estimates, one per provider for the selected package and network. In this case, we have narrowed to Inova Fairfax, so the response only has one item. Jane's colonoscopy has a negotiated rate (total_allowed_amount) of $2,400, and her share (user_cost_share) is $680.

200 OK
{
  "items": [
    {
      "provider": { "id": "prov_8821", "name": "Inova Fairfax Hospital" },
      "package": { "id": "pkg_01hxyz", "name": "Colonoscopy" },
      "pricing": {
        "type": "negotiated",
        "network": { "id": "482910", "name": "Example PPO Network" },
        "payer": { "id": "payer_01hxyz", "name": "Example Payer" }
      },
      "total_allowed_amount": { "amount": "2400.00", "minor_units": 240000, "currency": "USD" },
      "user_cost_share": {
        "total":                      { "amount": "680.00", "minor_units": 68000, "currency": "USD" },
        "amount_towards_deductible":  { "amount": "500.00", "minor_units": 50000, "currency": "USD" },
        "amount_towards_copayment":   { "amount":   "0.00", "minor_units": 0, "currency": "USD" },
        "amount_towards_coinsurance": { "amount": "180.00", "minor_units": 18000, "currency": "USD" },
        "is_deductible_met": false,
        "is_out_of_pocket_max_met": false
      }
    }
  ],
  "benefits_summary": { /* see step 5 */ }
}

The response also returns a single benefits_summary, Jane's current accumulator state, so you can explain why a personalized estimate looks the way it does. Here she has not met her deductible, so most of the $680 goes toward it.

FieldHow to read it
totalThe number to show the patient. The three amounts below sum to this.
amount_towards_deductibleHow much of this service goes toward the not-yet-met deductible.
amount_towards_copaymentThe flat copay portion, if the plan charges one for this service.
amount_towards_coinsuranceTheir percentage share of the rest, after the deductible.
is_deductible_mettrue means the deductible is fully met at or after this service.
is_out_of_pocket_max_mettrue means the out-of-pocket maximum is met, so the plan covers everything beyond this.

Every money value uses the standard Money shape: a string amount ("680.00"), integer minor_units (68000), and currency.

Understand the plan context

The response also returns a single benefits_summary, Jane’s current accumulator state, so you can explain why a personalized estimate looks the way it does. Here she has not met her deductible, so most of the $680 goes toward it.

# benefits_summary, returned once alongside items[]
{
  "remaining_deductible":            1200.00,
  "total_deductible":                2000.00,
  "remaining_out_of_pocket_max":     4800.00,
  "total_out_of_pocket_max":         6000.00,
  "deductible_accumulator_type":     "individual",
  "out_of_pocket_accumulator_type":  "individual",
  "benefit_categories": [
    { "category": "outpatient_surgery", "coinsurance": 0.20, "copayment": 0.00, "deductible": 2000.00 }
  ],
  "limitations": []
}
FieldHow to read it
remaining_deductibleThe cap minus what the member has already spent. Jane’s $500 toward the deductible comes out of this; it is met once this hits 0.
total_deductibleThe full deductible for the year. Pair with remaining to show progress, e.g. “$800 of $2,000 met.”
remaining_out_of_pocket_maxDollars left before the plan covers everything. Once this hits 0, the member pays nothing more.
total_out_of_pocket_maxThe full out-of-pocket maximum for the year.
deductible_accumulator_type, out_of_pocket_accumulator_typeHow each accumulator resolves: embedded, aggregate, individual, or zero.
benefit_categories[]The per-category rules that applied. coinsurance is a rate (0.20 = 20%), plus copayment and a category deductible.
limitations[]Any plan limits, such as visit or dollar caps. Empty when none apply.
A note on accumulator types

How the remaining deductible resolves depends on the plan’s accumulator type. Embedded plans have both an individual and a family deductible; it is met when either is exceeded, using whichever remaining amount is smaller. Aggregate plans have a family deductible only, met once the family accumulator is exceeded. Individual plans have no family accumulator; the deductible is met once the individual accumulator is reached. Zero plans have a $0 deductible, so coverage kicks in immediately. In every case, remaining_deductible and total_deductible report the same accumulator (individual or family), so the two values line up.

Error messages

Calls to POST /v3/personalized-estimates can return the errors below. Most are 422s tied to member matching or coverage, and their messages are written to be shown to the patient so they can retry with corrected details.

ErrorHTTPMessage
INVALID_MEMBER_ID422Member ID does not match the payer’s requirements. Retry with different member information.
INVALID_DOB422We were not able to find your insurance with the date of birth provided. Retry with different member information.
INVALID_MEMBER_NAME422We were not able to find your insurance with the name provided. Retry with different member information.
MEMBER_NOT_FOUND422No member found matching the details provided. Retry with different member information.
NO_ACTIVE_COVERAGE422A member was found but has no active coverage. Try again with different member information.
UNSUPPORTED_TPA422This plan is managed by <tpa_name>, which is not currently supported.
UNAVAILABLE_PAYER500The payer is temporarily unavailable. Please retry later.
ELIGIBILITY_SERVICE_ERROR500Eligibility service error. An unexpected error occurred.
PRICING_UNAVAILABLE503The pricing service is temporarily unavailable. Please retry later.
INTERNAL_SERVER_ERROR500An unexpected error occurred.

HIPAA compliance

Fields in member_eligibility(first_name, last_name, date_of_birth, and member_id) are Protected Health Information (PHI) under HIPAA.

The demo environment does not accept live patient data, and no PHI may be exchanged. Production access is required to send real PHI to this endpoint and mandates a signed Business Associate Agreement (BAA) with Turquoise. Please contact us to enable production access.

Once in use, by setting consent_attested to true, you represent to us that you obtained the patient's consent, consistent with your BAA.

How Turquoise safeguards PHI

Traffic to these endpoints is routed to isolated environments subject to HIPAA administrative, physical, and technical safeguards. PHI is encrypted in transit and at rest, and access is logged for audit purposes. See our Trust Center for our current security certifications and compliance documentation.

This section is provided for informational purposes only and does not constitute legal advice. Please consult your own counsel to determine your organization's HIPAA obligations.