# 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](/api/docs/pricing-methodology/#about-ssps)
 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](/api/docs/data-coverage/)
 (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](https://static.turquoise.health/static/api/images/standard-plan-mapping-diagram.cd5e609b75c9.png)

 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](/api/docs/pricing-methodology/#about-ssps)
 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.
 

1
### 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`).
 

| Field | Meaning |
| --- | --- |
| `package_id` (required) | The service you are pricing, e.g. a screening colonoscopy. |
| `pricing` (required) | `type: "negotiated"` with a `network_id`. |
| `provider_id` | Optional. Narrow the results to a single provider, like Inova Fairfax. |
| `location` | Optional. Narrow by `near`, `within`, or `zip`. |

2
### 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.
 

| Field | Meaning |
| --- | --- |
| `first_name`, `last_name` | The patient’s legal name. |
| `date_of_birth` | The patient’s date of birth. |
| `member_id` | The ID on the patient’s insurance card. |
| `consent_attested` | Must be `true` — your attestation that the patient consented. |

 The eligibility block is PHI. See [HIPAA compliance](#hipaa) for how it
 must be handled.
 

3
### 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.
 

4
### 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.
 

| Field | How to read it |
| --- | --- |
| `total` | The number to show the patient. The three amounts below sum to this. |
| `amount_towards_deductible` | How much of this service goes toward the not\-yet\-met deductible. |
| `amount_towards_copayment` | The flat copay portion, if the plan charges one for this service. |
| `amount_towards_coinsurance` | Their percentage share of the rest, after the deductible. |
| `is_deductible_met` | `true` means the deductible is fully met at or after this service. |
| `is_out_of_pocket_max_met` | `true` 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`.
 

5
### 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": []
}
```

| Field | How to read it |
| --- | --- |
| `remaining_deductible` | The 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_deductible` | The full deductible for the year. Pair with remaining to show progress, e.g. “$800 of $2,000 met.” |
| `remaining_out_of_pocket_max` | Dollars left before the plan covers everything. Once this hits 0, the member pays nothing more. |
| `total_out_of_pocket_max` | The full out\-of\-pocket maximum for the year. |
| `deductible_accumulator_type`, `out_of_pocket_accumulator_type` | How 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 `422`s tied to member matching or coverage, and their messages are written to be
 shown to the patient so they can retry with corrected details.
 

| Error | HTTP | Message |
| --- | --- | --- |
| `INVALID_MEMBER_ID` | `422` | Member ID does not match the payer’s requirements. Retry with different member information. |
| `INVALID_DOB` | `422` | We were not able to find your insurance with the date of birth provided. Retry with different member information. |
| `INVALID_MEMBER_NAME` | `422` | We were not able to find your insurance with the name provided. Retry with different member information. |
| `MEMBER_NOT_FOUND` | `422` | No member found matching the details provided. Retry with different member information. |
| `NO_ACTIVE_COVERAGE` | `422` | A member was found but has no active coverage. Try again with different member information. |
| `UNSUPPORTED_TPA` | `422` | This plan is managed by `<tpa_name>`, which is not currently supported. |
| `UNAVAILABLE_PAYER` | `500` | The payer is temporarily unavailable. Please retry later. |
| `ELIGIBILITY_SERVICE_ERROR` | `500` | Eligibility service error. An unexpected error occurred. |
| `PRICING_UNAVAILABLE` | `503` | The pricing service is temporarily unavailable. Please retry later. |
| `INTERNAL_SERVER_ERROR` | `500` | An 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](https://turquoise.health/request-a-demo) 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](https://app.vanta.com/turquoise.health/trust/4eadhio8ef1h3zwumb77kp) 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.
