How to migrate to Stedi's redesigned JSON Real-Time Eligibility Check API
We've released a redesigned version of our JSON Real-Time Eligibility Check API endpoint. It returns the same benefits information as our legacy JSON real-time eligibility endpoint with an improved response shape.
The new shape is easier for developers and AI coding agents, like Claude Code and Codex, to parse. Each benefit type has its own schema, and benefits are grouped by health plan.
If you're building a new Stedi integration, start with the new endpoint.
If you're still on the legacy endpoint, this guide can help you migrate to the new endpoint. It covers what's changed and explains the new response shape. The guide also includes migration tips and a prompt for your coding agent.
Migration tips
Use Stedi's SDKs for TypeScript and Python
If you use TypeScript or Python, Stedi's TypeScript and Python SDKs include methods and runnable examples for the new endpoint:
| SDK | Method | Runnable examples |
|---|---|---|
| TypeScript | createEligibilityCheck | TypeScript SDK examples |
| Python | create_eligibility_check | Python SDK examples |
The SDKs give you a reusable client, types, retries, and error handling. You only need to write the parts that are specific to your product.
Use a coding agent
The new endpoint is designed to work well with coding agents like Claude Code and Codex. Give your agent this prompt to kick off the migration process:
Migrate this codebase from Stedi's legacy JSON Real-Time Eligibility Check API endpoint to the redesigned endpoint, using the appropriate Stedi SDK or REST API:
- TypeScript: https://www.npmjs.com/package/@stedi/sdk
- Python: https://pypi.org/project/stedi/
- REST API:
- API reference: https://www.stedi.com/docs/healthcare/api-reference/post-eligibility-check.mdx
- OpenAPI spec: https://github.com/Stedi/openApi/blob/main/healthcare.json
Fetch the following migration guides and apply the appropriate changes:
- https://www.stedi.com/docs/healthcare/eligibility-response-shapes
- https://www.stedi.com/blog/migrate-to-the-redesigned-json-real-time-eligibility-check-api
Do not touch more files than necessary for the migration.
Request body changes
You provide the same information to run eligibility checks with either endpoint:
- The payer ID, which you can get from the Payers API or the Stedi Payer Network.
- The provider's name and identifier, typically their National Provider Identifier (NPI).
- The patient's first name, last name, date of birth, and, if you have it, member ID.
- The Service Type Code (STC) or procedure code you want benefits for. If you don't specify an STC or procedure code, Stedi defaults to STC
30(Health Benefit Plan Coverage).
Legacy endpoint request
An example curl request using the legacy endpoint:
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3 \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "19700101",
"memberId": "UHC202649"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
New endpoint request
The new endpoint groups related request fields into nested objects. It also replaces the separate serviceTypeCodes and procedureCode fields with a single services array.
A few field names were renamed to be clearer. For example, tradingPartnerServiceId is now payerId. The dateOfBirth format also changed. It uses YYYY-MM-DD instead of YYYYMMDD.
The same curl request using the new endpoint:
curl --request POST \
--url https://healthcare.us.stedi.com/2026-06-01/eligibility-check \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"payerId": "87726",
"provider": {
"name": {
"organization": "Provider Name"
},
"npi": "1999999984"
},
"subscriber": {
"name": {
"person": {
"firstName": "John",
"lastName": "Doe"
}
},
"dateOfBirth": "1970-01-01",
"memberId": "UHC202649"
},
"encounter": {
"services": [
{
"system": "STC",
"value": "30"
}
]
}
}'
To get more details on individual request fields, see the related guide and API reference in our docs.
Response changes
Most providers run eligibility checks to answer two questions:
- Does this patient have active insurance coverage?
- If so, what do they need to pay out of pocket for this service or procedure? This includes co-payments, deductibles, and co-insurance.
The eligibility response's benefits answer those questions. Both endpoints return the same benefits information. The biggest change is that each benefit type now has its own schema. The new endpoint also groups benefits by plan.
This section gives you the highlights. For more information, see response shapes in our docs.
Benefits grouped by plan
Legacy endpoint
The legacy endpoint returns every benefit in a single, flat benefitsInformation array with no plan grouping. When a patient has more than one plan, entries for every plan appear in the array. Only planCoverage tells you which plan each entry belongs to.
"benefitsInformation": [
{
"code": "C", // Deductible
"coverageLevelCode": "IND", // Individual coverage
"serviceTypeCodes": ["30"], // Health Benefit Plan Coverage
"timeQualifierCode": "23", // Calendar year
"benefitAmount": "1000", // $1,000 per year deductible
"planCoverage": "OPEN ACCESS PLUS" // Medical plan
},
{
"code": "C", // Deductible
"coverageLevelCode": "IND", // Individual coverage
"serviceTypeCodes": ["35"], // Dental care
"timeQualifierCode": "23", // Calendar year
"benefitAmount": "50", // $50 per year deductible
"planCoverage": "PPO DENTAL" // Dental plan
}
]
New endpoint
The new endpoint returns benefits in a nested plans array, which groups benefits under their associated health plan. A response can contain multiple plans.
For example, a patient with medical and dental coverage through the same payer receives a separate plans object for each plan. Each plan's name is in plans[].name.
"plans": [
{
"name": "Open Access Plus",
"benefits": {
"deductible": [
{
"amount": "1000",
"coverageLevel": "INDIVIDUAL",
"service": {
"system": "STC",
"value": "30",
"definition": "Health Benefit Plan Coverage"
},
"timePeriod": "CALENDAR_YEAR"
}
]
}
},
{
"name": "PPO Dental",
"benefits": {
"deductible": [
{
"amount": "50",
"coverageLevel": "INDIVIDUAL",
"service": {
"system": "STC",
"value": "35",
"definition": "Dental Care"
},
"timePeriod": "CALENDAR_YEAR"
}
]
}
}
]
Different schema for different benefit types
Legacy endpoint
In the legacy endpoint's benefitsInformation array, every benefit entry reuses the same object schema. As a result, the schema can't tell you which fields are expected from a payer for each entry type.
Each benefitsInformation entry includes a code that tells you what the rest of the entry means.
For example, an entry with a code of C is a deductible. The entry's benefitAmount field includes a dollar amount for the deductible. The schema lists benefitAmount as optional. But payers should always return a benefitAmount for deductible entries.
{
"benefitsInformation": [
{
"code": "C", // Deductible
"benefitAmount": "1000", // $1,000 deductible
...
},
...
]
}
An entry with a code of A indicates co-insurance. The entry's benefitPercent field includes a percent for the co-insurance. The schema lists benefitPercent as optional, but payers should always return a benefitPercent for co-insurance entries. The benefitAmount field is also listed as optional, but payers shouldn't return benefitAmount for co-insurance entries.
{
"benefitsInformation": [
{
"code": "A", // Co-insurance
"benefitPercent": "0", // 0% co-insurance
...
},
...
]
}
New endpoint
In plans responses, benefit types use a named key instead of a code field. For example, objects in the statuses array tell you whether the patient has insurance coverage and which services it applies to. Every other kind of benefit is its own named array, such as coPayment or deductible.
Each benefit type also has its own object schema. That schema matches what's expected in the payer response. For example, deductible objects require an amount. coInsurance objects have no amount field. They require a percent instead.
{
"plans": [
{
"benefits": {
"deductible": [
{
"amount": "1000", // $1,000 deductible
...
}
],
"coInsurance": [
{
"percent": "0", // 0% co-insurance
...
}
],
...
}
},
...
]
}
Invalid response data
Stedi builds both the new and legacy JSON eligibility responses from the same underlying X12 271 eligibility response we receive from the payer. The response shapes differ in how they handle data that doesn't conform to the X12 spec.
Legacy endpoint
If a payer returns an invalid X12 response, legacy responses pass that data through as is in the benefitsInformation entry.
For example, the response could include an entry for a co-payment that contains an invalid benefitPercent and is missing benefitAmount.
"benefitsInformation": [
{
"code": "B", // Co-payment
"benefitPercent": "0.2" // Invalid X12 for a co-payment entry
// benefitAmount is missing
}
]
New endpoint
The new endpoint validates benefit entries in the response against their types. Invalid entries appear in benefits.invalidEntries instead of the standard array. For example:
{
"plans": [
{
"benefits": {
"invalidEntries": {
"coPayment": [
{
"percent": "0.2",
...
"invalidReasons": [
{
"code": "MISSING_AMOUNT",
"description": "Co-payment requires an amount value, but none was provided."
},
{
"code": "UNEXPECTED_PERCENT",
"description": "Co-payment has an unexpected percent value."
}
]
}
]
}
}
}
]
}
Parsing benefits for services or procedures
Providers commonly want every benefit for a specific STC or procedure code – coverage status, deductibles, co-insurance. Both endpoints name the service each benefit applies to, but they name it differently, so your filter changes.
Legacy endpoint
You can parse legacy benefitsInformation responses with TypeScript code like this:
const STC = "30";
// One entry can list several STCs, so check the whole array.
const benefits = response.benefitsInformation.filter((benefit) =>
benefit.serviceTypeCodes?.includes(STC),
);
New endpoint
Using the new plans responses, you'd update that code to the following:
const STC = "30";
// Check the system too. A procedure code can have the same value as an STC.
const forStc = (benefit) =>
benefit.service?.system === "STC" && benefit.service.value === STC;
const benefits = (response.plans ?? []).flatMap((plan) => {
// invalidEntries is an object of arrays. Pull it out first.
const { invalidEntries, ...standard } = plan.benefits ?? {};
return [
...Object.values(standard).flat(),
// Include invalid entries to match the legacy endpoint's behavior.
...Object.values(invalidEntries ?? {}).flat(),
].filter(forStc);
});
FAQs
Are you deprecating the legacy endpoint?
No. We're continuing to support the legacy endpoint, and there's no deadline for migration. Your existing integrations will keep working.
Does the new JSON Real-Time Eligibility Check API endpoint support test mode?
Yes. You can use the new endpoint to run pre-defined mock eligibility checks in test mode with a test API key.
Mock eligibility checks are available on all Stedi accounts, including free sandbox accounts.
Does the new response shape contain different benefits information?
No. Stedi builds both JSON response shapes from the same underlying X12 271 eligibility response.
The responses only differ in how they organize that information, what they name each property, and how they handle data that doesn't conform to the spec.
What endpoints use the new response shape?
Only the redesigned JSON Real-Time Eligibility Check API endpoint returns the new plans response shape.
Other eligibility-related endpoints use the benefitsInformation response shape.
| Top-level array | Endpoints |
|---|---|
plans | Real-Time Eligibility Check JSON |
benefitsInformation | Batch Eligibility Check, Insurance Discovery, Real-Time Eligibility Check Raw X12, Real-Time Eligibility Check JSON - Legacy |
Do the Stedi SDKs support the legacy eligibility endpoint?
No. Stedi's TypeScript and Python SDKs only support the new JSON Real-Time Eligibility Check API endpoint.
Availability and pricing
The redesigned JSON Real-Time Eligibility Check API endpoint is available on all Stedi accounts.
Production eligibility checks are priced per transaction. For pricing, see our Pricing page.