Using an eligibility check to determine whether a patient's deductible has been met

Arna Meyer

Arna Meyer

Guide

A deductible is the amount a patient must pay out of pocket for covered healthcare services before their insurance plan begins paying. For patients with high-deductible health plans, the timing of claim submission can affect who is expected to pay. If the patient has not met their deductible yet, the payer may process the claim and return a response showing that the allowed amount is the patient’s responsibility. In practice, that means the provider must collect payment from the patient instead of receiving payment from the payer.

Many providers address this by verifying the patient's deductible balance before the visit and collecting the estimated patient responsibility at the point of service. That approach works well in scheduled care settings. In acute and emergency care settings, point-of-service collection is rarely an option – patients arrive without warning, treatment happens first, and billing follows. In those settings, some providers choose to hold claims until the patient's deductible has been met. Consider a patient with a $1,000 annual deductible who has $600 remaining. A claim submitted today for $800 would have $600 applied to the deductible and the remainder paid by the payer – leaving a $600 patient balance to collect. The same claim submitted after the deductible is fully met is paid entirely by the payer. Holding the claim avoids the patient balance and the cost of collecting it.

You can use an eligibility check to determine whether the patient has met their deductible before submitting a claim. An eligibility response contains the deductible data needed to make that decision, including the patient’s annual deductible amount and the amount remaining. This guide shows how to read those values from Stedi’s JSON Eligibility API response and use them to decide whether to submit or hold a claim.

The fields that matter

Deductible information is returned in the benefitsInformation array of Stedi's JSON response. A payer that supports remaining deductible data will return two objects for each deductible: one for the annual amount and one for the amount remaining. Each object is made up of key-value pairs called properties – the property name identifies the field, and the value holds the data. For deductible monitoring, the properties that matter are:

JSON Property Name

Relevant values

code

C = Deductible

coverageLevelCode

IND = Individual, FAM = Family

serviceTypeCodes

30 = Health Benefit Plan Coverage (general medical)

timeQualifierCode

23 = Calendar Year, 29 = Remaining

benefitAmount

Dollar value as a string, e.g. "150" or "0"

inPlanNetworkIndicatorCode

Y = In-network, N = Out-of-network, W = Not Applicable

The remaining amount – benefitAmount on the object where timeQualifierCode is "29" – is the only figure you need for a hold-and-release decision. When that value is "0", the deductible is met and the claim can be released.

A deductible that has been met

In Stedi's JSON response, this appears as an object in the benefitsInformation array. The remaining-amount object is what you evaluate:

{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "23",
  "timeQualifier": "Calendar Year",
  "benefitAmount": "150",
  "inPlanNetworkIndicatorCode": "W",
  "inPlanNetworkIndicator": "Not Applicable"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "0",
  "inPlanNetworkIndicatorCode": "W",
  "inPlanNetworkIndicator": "Not Applicable"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "23",
  "timeQualifier": "Calendar Year",
  "benefitAmount": "150",
  "inPlanNetworkIndicatorCode": "W",
  "inPlanNetworkIndicator": "Not Applicable"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "0",
  "inPlanNetworkIndicatorCode": "W",
  "inPlanNetworkIndicator": "Not Applicable"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "23",
  "timeQualifier": "Calendar Year",
  "benefitAmount": "150",
  "inPlanNetworkIndicatorCode": "W",
  "inPlanNetworkIndicator": "Not Applicable"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "0",
  "inPlanNetworkIndicatorCode": "W",
  "inPlanNetworkIndicator": "Not Applicable"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "23",
  "timeQualifier": "Calendar Year",
  "benefitAmount": "150",
  "inPlanNetworkIndicatorCode": "W",
  "inPlanNetworkIndicator": "Not Applicable"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "0",
  "inPlanNetworkIndicatorCode": "W",
  "inPlanNetworkIndicator": "Not Applicable"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "23",
  "timeQualifier": "Calendar Year",
  "benefitAmount": "150",
  "inPlanNetworkIndicatorCode": "W",
  "inPlanNetworkIndicator": "Not Applicable"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "0",
  "inPlanNetworkIndicatorCode": "W",
  "inPlanNetworkIndicator": "Not Applicable"
}

Annual deductible: $150. Remaining: $0. Release the claim.

These represent the individual deductible. Family deductibles are tracked separately – see the individual versus family section below. benefitAmount: "0" on the timeQualifierCode: "29" object is the signal to release.

A deductible that has not been met

The individual has a $1,000 annual deductible with $1,000 remaining – nothing applied yet. The family deductible is $2,000 with $1,000 remaining – halfway through. Both claims should stay on hold.

The remaining-amount data in JSON:

{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "1000",
  "inPlanNetworkIndicatorCode": "Y",
  "inPlanNetworkIndicator": "Yes"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "FAM",
  "coverageLevel": "Family",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "1000",
  "inPlanNetworkIndicatorCode": "Y",
  "inPlanNetworkIndicator": "Yes"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "1000",
  "inPlanNetworkIndicatorCode": "Y",
  "inPlanNetworkIndicator": "Yes"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "FAM",
  "coverageLevel": "Family",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "1000",
  "inPlanNetworkIndicatorCode": "Y",
  "inPlanNetworkIndicator": "Yes"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "1000",
  "inPlanNetworkIndicatorCode": "Y",
  "inPlanNetworkIndicator": "Yes"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "FAM",
  "coverageLevel": "Family",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "1000",
  "inPlanNetworkIndicatorCode": "Y",
  "inPlanNetworkIndicator": "Yes"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "1000",
  "inPlanNetworkIndicatorCode": "Y",
  "inPlanNetworkIndicator": "Yes"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "FAM",
  "coverageLevel": "Family",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "1000",
  "inPlanNetworkIndicatorCode": "Y",
  "inPlanNetworkIndicator": "Yes"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "1000",
  "inPlanNetworkIndicatorCode": "Y",
  "inPlanNetworkIndicator": "Yes"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "FAM",
  "coverageLevel": "Family",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "1000",
  "inPlanNetworkIndicatorCode": "Y",
  "inPlanNetworkIndicator": "Yes"
}

Understanding your accumulators

Individual versus family

Payers return individual and family deductibles separately. In most commercial plans, once either the individual or the family accumulator is satisfied, that patient's claims are no longer subject to the deductible for the plan year. Either condition alone is sufficient to release a held claim.

The second example illustrates why both matter. The individual deductible is $1,000 with no progress, but the family deductible is halfway met. If the family accumulator reaches $0 before the individual does, claims for this patient are eligible for release even though the individual accumulator never hit zero.

In-network versus out-of-network

When inPlanNetworkIndicatorCode is "Y" or "N", the payer tracks separate deductible accumulators for in-network and out-of-network services. The same response that returned the in-network objects above also contains out-of-network deductible objects:

{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "2000",
  "inPlanNetworkIndicatorCode": "N",
  "inPlanNetworkIndicator": "No"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "FAM",
  "coverageLevel": "Family",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "4000",
  "inPlanNetworkIndicatorCode": "N",
  "inPlanNetworkIndicator": "No"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "2000",
  "inPlanNetworkIndicatorCode": "N",
  "inPlanNetworkIndicator": "No"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "FAM",
  "coverageLevel": "Family",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "4000",
  "inPlanNetworkIndicatorCode": "N",
  "inPlanNetworkIndicator": "No"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "2000",
  "inPlanNetworkIndicatorCode": "N",
  "inPlanNetworkIndicator": "No"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "FAM",
  "coverageLevel": "Family",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "4000",
  "inPlanNetworkIndicatorCode": "N",
  "inPlanNetworkIndicator": "No"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "2000",
  "inPlanNetworkIndicatorCode": "N",
  "inPlanNetworkIndicator": "No"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "FAM",
  "coverageLevel": "Family",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "4000",
  "inPlanNetworkIndicatorCode": "N",
  "inPlanNetworkIndicator": "No"
}
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "IND",
  "coverageLevel": "Individual",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "2000",
  "inPlanNetworkIndicatorCode": "N",
  "inPlanNetworkIndicator": "No"
},
{
  "code": "C",
  "name": "Deductible",
  "coverageLevelCode": "FAM",
  "coverageLevel": "Family",
  "serviceTypeCodes": ["30"],
  "serviceTypes": ["Health Benefit Plan Coverage"],
  "timeQualifierCode": "29",
  "timeQualifier": "Remaining",
  "benefitAmount": "4000",
  "inPlanNetworkIndicatorCode": "N",
  "inPlanNetworkIndicator": "No"
}

The out-of-network individual deductible has $2,000 remaining. The out-of-network family deductible has $4,000 remaining.

A claim from an in-network provider applies to the in-network deductible, not the out-of-network one. Evaluating the wrong accumulator produces the wrong hold decision.

When inPlanNetworkIndicatorCode is "W" (Not Applicable), as in the first example, the same deductible applies regardless of network status. No matching is needed.

The hold-and-release decision

The following steps outline the logic for automating a hold-and-release decision using the 271 response.

Step 1: Does the response contain objects where code: "C" and timeQualifierCode: "29"?

  • No → The payer has not returned remaining deductible data. Route the claim to manual review.

  • Yes → Continue to step 2.

Step 2: What is inPlanNetworkIndicatorCode on those objects?

  • "W" → Network status does not affect this deductible. No matching needed. Continue to step 3 using all code: "C", timeQualifierCode: "29" objects.

  • "Y" or "N" → Filter to the objects that match the claim's network status. In-network claims evaluate against "Y" objects; out-of-network claims against "N" objects. Continue to step 3 using only the matching objects.

Step 3: Among the matching objects, is benefitAmount on the coverageLevelCode: "IND" object "0"?

  • Yes → The individual deductible is met. Release the claim.

  • No → Continue to step 4.

Step 4: Among the matching objects, is benefitAmount on the coverageLevelCode: "FAM" object "0"?

  • Yes → The family deductible is met. Release the claim.

  • No → Hold the claim and schedule a re-check.

A note on normalized outputs

Not every payer returns deductible status in structured EB fields. Some return it in a free-text MSG segment attached to the EB loop. When the content is ambiguous, it appears in the additionalInformation array on the relevant benefitsInformation object rather than as a discrete field.

For hold-and-release decisions, build on the structured remaining-amount pattern – code: "C" with timeQualifierCode: "29". For more on how deductible and other cost-sharing fields are returned, see Patient responsibility. When a payer returns only the annual deductible and omits the remaining amount entirely, treat the status as indeterminate and route the claim to a manual review queue rather than holding indefinitely.

One caveat worth building around

Holding claims until a deductible is met only works within your payers' timely filing windows. Most commercial payers require claims to be submitted within 90 to 365 days of the date of service, and missing that window means the claim is denied regardless of deductible status. Build your hold queue with a filing deadline per claim, and release any claim approaching that limit, whether the deductible has been met or not.

The remaining amount in a 271 response reflects claims the payer has adjudicated at the time of the query. Claims that have been submitted but not yet processed are not included. Both examples above include a payer MSG stating explicitly that accumulated amounts may change as additional claims are processed.

This makes the deductible-met signal point-in-time, not permanent. Build your re-check cadence accordingly. A response showing "0" remaining today is accurate as of when you asked – not a guarantee of how the next claim will adjudicate.

Share

Twitter
LinkedIn

Get started with Stedi

Get started with Stedi

Start free with a sandbox account. Upgrade to production when you're ready. There are no monthly minimums or setup fees. You only pay for the transactions you use. See our pricing.

Get updates on what’s new at Stedi

Get updates on what’s new at Stedi

Get updates on what’s new at Stedi

Get updates on what’s new at Stedi

Backed by

Stedi and the S design mark are registered trademarks of Stedi, Inc. All names, logos, and brands of third parties listed on our site are trademarks of their respective owners (including “X12”, which is a trademark of X12 Incorporated). Stedi, Inc. and its products and services are not endorsed by, sponsored by, or affiliated with these third parties. Our use of these names, logos, and brands is for identification purposes only, and does not imply any such endorsement, sponsorship, or affiliation.

Get updates on what’s new at Stedi

Backed by

Stedi and the S design mark are registered trademarks of Stedi, Inc. All names, logos, and brands of third parties listed on our site are trademarks of their respective owners (including “X12”, which is a trademark of X12 Incorporated). Stedi, Inc. and its products and services are not endorsed by, sponsored by, or affiliated with these third parties. Our use of these names, logos, and brands is for identification purposes only, and does not imply any such endorsement, sponsorship, or affiliation.

Get updates on what’s new at Stedi

Backed by

Stedi and the S design mark are registered trademarks of Stedi, Inc. All names, logos, and brands of third parties listed on our site are trademarks of their respective owners (including “X12”, which is a trademark of X12 Incorporated). Stedi, Inc. and its products and services are not endorsed by, sponsored by, or affiliated with these third parties. Our use of these names, logos, and brands is for identification purposes only, and does not imply any such endorsement, sponsorship, or affiliation.