Common questions about dental eligibility checks

Jun 17, 2025

Healthcare

Insurance verification is important for dental care. Before the provider can get paid, they need to know what a patient’s plan covers. The patient needs to know too – so they’re not surprised by a bill later.

That’s where Stedi comes in. We make it easy to check dental insurance in real time. Stedi's Eligibility Check APIs let you work with JSON or raw X12 EDI. You can check coverage with thousands of payers, including major dental insurers like Delta Dental, DentaQuest, and Guardian.

This post answers the most common questions we hear from developers using Stedi to check dental eligibility.

What STCs should I use for dental?

A Service Type Code (STC) tells the payer what kind of benefits you're checking. For general dental coverage, use STC 35 (Dental Care) in the eligibility request:

"encounter": {
  "serviceTypeCodes": ["35"]
}

If you leave it out, Stedi defaults to 30 (Health Benefit Plan Coverage). This may return incomplete or irrelevant data. Many payers only return dental benefits for STC 35.

Other common dental STCs include:

  • 4 - Diagnostic X-Ray

  • 5 - Diagnostic Lab

  • 23 - Diagnostic Dental

  • 24 - Periodontics

  • 25 - Restorative

  • 26 - Endodontics

  • 27 - Maxillofacial Prosthetics

  • 28 - Adjunctive Dental Services

  • 36 - Dental Crowns

  • 37 - Dental Accident

  • 38 - Orthodontics

  • 39 - Prosthodontics

  • 40 - Oral Surgery

  • 41 - Routine (Preventive) Dental

Most payers only support one STC per request. Don’t send multiple STCs unless you’ve tested that it works. For testing tips, see our How to avoid eligibility check errors blog.

Which payers support dental eligibility checks?

There’s no definitive list. Stedi supports eligibility checks for most major dental payers. But not all of them return dental-specific data – even if they support eligibility checks in general.

To check if a payer returns dental data, run a check with STC 35 and look at the response. In our tests, more than half of payers return active dental coverage when you use STC 35.

Can I use CDT codes in eligibility checks?

Yes – but support depends on the payer.

Current Dental Terminology (CDT) codes are procedure codes used in dental billing. For example, D0120 is a routine exam.

You can send a CDT code in your request using the productOrServiceIDQualifier and procedureCode fields. But many payers will return the same data you’d get from STC 35. Those results often include CDT code-level benefits.

To test it, send one request with the CDT code and one with STC 35 to the same payer. Then compare what you get back.

What’s included in dental eligibility responses?

This depends on the payer, but most responses include the following.

Basic coverage
These fields confirm whether the member has dental coverage and when it starts and ends:

  • Coverage status (active/inactive): benefitsInformation.code ("1" = Active, "6" = Inactive).

    Plan start and end dates: planInformation.planBeginDate and planInformation.planEndDate.

Patient responsibility
These fields tell you what the patient might owe:

  • Co-insurance and deductible: benefitsInformation.code and benefitsInformation.benefitPercent or benefitsInformation.benefitAmount.

    Coverage levels for common categories, such as diagnostic or preventative: benefitsInformation.serviceTypeCode (35 for basic or 41 for preventive).

Lifetime maximums
Many dental plans include lifetime maximums. These often show up as two entries with the same benefitsInformation.code.

For example, one for the total lifetime maximum:

{
  "code": "F",
  "serviceTypeCodes": ["38"],
  "benefitAmount": 2000,		// $2,000 amount
  "timeQualifierCode": "32"		// Lifetime maximum
}

One for the remaining amount:

{
  "code": "F",
  "serviceTypeCodes": ["38"],
  "benefitAmount": 1200,		// $1,200 amount
  "timeQualifierCode": "33"		// Lifetime remaining
}

CDT-level detail
Many payers return benefits tied to specific CDT codes, using compositeMedicalProcedureIdentifier:

{
  "code": "A",  				              // Co-insurance
  "insuranceTypeCode": "GP",  		          // Group policy
  "benefitPercent": "0",  			          // Patient owes 0% co-insurance for procedure
  "compositeMedicalProcedureIdentifier": {
    "productOrServiceIDQualifierCode": "AD",  // CDT code qualifier
    "procedureCode": "D0372"  		          // CDT code for the procedure
  },
  "benefitsDateInformation": {
    "latestVisitOrConsultation": "202420722"  // Most recent date this procedure was used
  }
}

Cigna is a known edge case. It puts CDT info in additionalInformation.description as free text.

Age limitations
Age limitations use one of the following quantityQualifierCode values:

  • S8 - Age, Minimum

  • S7 - Age, Maximum

The benefitQuantity is the minimum or maximum age allowed.

{
  // Age limit: patient must be at least 18 years old
  "quantityQualifierCode": "S8",	// Age (minimum)
  "benefitQuantity": "18"

}

Frequency limitations
 Frequency limitations typically use one of the following quantityQualifierCode values:

  • P6 - Number of Services or Procedures

  • VS - Visits

The timePeriodQualifierCode defines the time window (such as 7 for per year). The benefitQuantity sets the frequency limit.

{
  // Frequency limit: 2 services per calendar year
  "quantityQualifierCode": "VS",  			// Visits
  "benefitQuantity": "2",
  "timePeriodQualifierCode": "7",  			// Annual
  "numOfPeriods": "1",
}

History
Many payers include the last time a procedure was done. This shows up in benefitsDateInformation.latestVisitOrConsultation.

Example at the STC level:

{
  // STC-level entry
  "code": "A",                                // Co-insurance
  "insuranceTypeCode": "GP",                  // Group policy
  "benefitPercent": "80",                     // 80% covered
  "serviceTypeCodes": ["41"],                 // Routine (Preventive) Dental
  "benefitsDateInformation": {
    "latestVisitOrConsultation": "20240301"   // Last preventive service date
  }
}

At the CDT level:

{
  // CDT code-level entry
  "compositeMedicalProcedureIdentifier": {
    "productOrServiceIDQualifierCode": "AD",  // CDT code qualifier
    "procedureCode": "D0150"                  // Comprehensive oral evaluation
  },
  "benefitsDateInformation": {
    "latestVisitOrConsultation": "20240404"   // Last time this procedure was used
  }
}

Free-text details
Some payers add notes as free text in additionalInformation.description, like:

  • Frequency limits shared between CDT codes.

  • Waiting periods.

  • Restrictions, such as the missing tooth clause.

For more tips on reading eligibility responses, see our How to read a 271 eligibility response in plain English blog.

How “real time” are Stedi’s real-time eligibility checks?

Most responses come back in 3-4 seconds.

But it depends on the payer. Some take longer – up to 60 seconds.

To handle slow responses, Stedi keeps the request open for up to 2 minutes. During that time, we retry the request in the background if needed.

Can I run dental eligibility checks in batches?

Yes. Use the Batch Eligibility Check API to send up to 1,000 checks at once. This works well if you want to refresh coverage data before appointments.

Batch checks are asynchronous. They don’t count toward your real-time concurrency limit. But the response can take longer – sometimes up to 8 hours.

Got more questions?

Contact us to talk to a dental eligibility expert at Stedi.

Insurance verification is important for dental care. Before the provider can get paid, they need to know what a patient’s plan covers. The patient needs to know too – so they’re not surprised by a bill later.

That’s where Stedi comes in. We make it easy to check dental insurance in real time. Stedi's Eligibility Check APIs let you work with JSON or raw X12 EDI. You can check coverage with thousands of payers, including major dental insurers like Delta Dental, DentaQuest, and Guardian.

This post answers the most common questions we hear from developers using Stedi to check dental eligibility.

What STCs should I use for dental?

A Service Type Code (STC) tells the payer what kind of benefits you're checking. For general dental coverage, use STC 35 (Dental Care) in the eligibility request:

"encounter": {
  "serviceTypeCodes": ["35"]
}

If you leave it out, Stedi defaults to 30 (Health Benefit Plan Coverage). This may return incomplete or irrelevant data. Many payers only return dental benefits for STC 35.

Other common dental STCs include:

  • 4 - Diagnostic X-Ray

  • 5 - Diagnostic Lab

  • 23 - Diagnostic Dental

  • 24 - Periodontics

  • 25 - Restorative

  • 26 - Endodontics

  • 27 - Maxillofacial Prosthetics

  • 28 - Adjunctive Dental Services

  • 36 - Dental Crowns

  • 37 - Dental Accident

  • 38 - Orthodontics

  • 39 - Prosthodontics

  • 40 - Oral Surgery

  • 41 - Routine (Preventive) Dental

Most payers only support one STC per request. Don’t send multiple STCs unless you’ve tested that it works. For testing tips, see our How to avoid eligibility check errors blog.

Which payers support dental eligibility checks?

There’s no definitive list. Stedi supports eligibility checks for most major dental payers. But not all of them return dental-specific data – even if they support eligibility checks in general.

To check if a payer returns dental data, run a check with STC 35 and look at the response. In our tests, more than half of payers return active dental coverage when you use STC 35.

Can I use CDT codes in eligibility checks?

Yes – but support depends on the payer.

Current Dental Terminology (CDT) codes are procedure codes used in dental billing. For example, D0120 is a routine exam.

You can send a CDT code in your request using the productOrServiceIDQualifier and procedureCode fields. But many payers will return the same data you’d get from STC 35. Those results often include CDT code-level benefits.

To test it, send one request with the CDT code and one with STC 35 to the same payer. Then compare what you get back.

What’s included in dental eligibility responses?

This depends on the payer, but most responses include the following.

Basic coverage
These fields confirm whether the member has dental coverage and when it starts and ends:

  • Coverage status (active/inactive): benefitsInformation.code ("1" = Active, "6" = Inactive).

    Plan start and end dates: planInformation.planBeginDate and planInformation.planEndDate.

Patient responsibility
These fields tell you what the patient might owe:

  • Co-insurance and deductible: benefitsInformation.code and benefitsInformation.benefitPercent or benefitsInformation.benefitAmount.

    Coverage levels for common categories, such as diagnostic or preventative: benefitsInformation.serviceTypeCode (35 for basic or 41 for preventive).

Lifetime maximums
Many dental plans include lifetime maximums. These often show up as two entries with the same benefitsInformation.code.

For example, one for the total lifetime maximum:

{
  "code": "F",
  "serviceTypeCodes": ["38"],
  "benefitAmount": 2000,		// $2,000 amount
  "timeQualifierCode": "32"		// Lifetime maximum
}

One for the remaining amount:

{
  "code": "F",
  "serviceTypeCodes": ["38"],
  "benefitAmount": 1200,		// $1,200 amount
  "timeQualifierCode": "33"		// Lifetime remaining
}

CDT-level detail
Many payers return benefits tied to specific CDT codes, using compositeMedicalProcedureIdentifier:

{
  "code": "A",  				              // Co-insurance
  "insuranceTypeCode": "GP",  		          // Group policy
  "benefitPercent": "0",  			          // Patient owes 0% co-insurance for procedure
  "compositeMedicalProcedureIdentifier": {
    "productOrServiceIDQualifierCode": "AD",  // CDT code qualifier
    "procedureCode": "D0372"  		          // CDT code for the procedure
  },
  "benefitsDateInformation": {
    "latestVisitOrConsultation": "202420722"  // Most recent date this procedure was used
  }
}

Cigna is a known edge case. It puts CDT info in additionalInformation.description as free text.

Age limitations
Age limitations use one of the following quantityQualifierCode values:

  • S8 - Age, Minimum

  • S7 - Age, Maximum

The benefitQuantity is the minimum or maximum age allowed.

{
  // Age limit: patient must be at least 18 years old
  "quantityQualifierCode": "S8",	// Age (minimum)
  "benefitQuantity": "18"

}

Frequency limitations
 Frequency limitations typically use one of the following quantityQualifierCode values:

  • P6 - Number of Services or Procedures

  • VS - Visits

The timePeriodQualifierCode defines the time window (such as 7 for per year). The benefitQuantity sets the frequency limit.

{
  // Frequency limit: 2 services per calendar year
  "quantityQualifierCode": "VS",  			// Visits
  "benefitQuantity": "2",
  "timePeriodQualifierCode": "7",  			// Annual
  "numOfPeriods": "1",
}

History
Many payers include the last time a procedure was done. This shows up in benefitsDateInformation.latestVisitOrConsultation.

Example at the STC level:

{
  // STC-level entry
  "code": "A",                                // Co-insurance
  "insuranceTypeCode": "GP",                  // Group policy
  "benefitPercent": "80",                     // 80% covered
  "serviceTypeCodes": ["41"],                 // Routine (Preventive) Dental
  "benefitsDateInformation": {
    "latestVisitOrConsultation": "20240301"   // Last preventive service date
  }
}

At the CDT level:

{
  // CDT code-level entry
  "compositeMedicalProcedureIdentifier": {
    "productOrServiceIDQualifierCode": "AD",  // CDT code qualifier
    "procedureCode": "D0150"                  // Comprehensive oral evaluation
  },
  "benefitsDateInformation": {
    "latestVisitOrConsultation": "20240404"   // Last time this procedure was used
  }
}

Free-text details
Some payers add notes as free text in additionalInformation.description, like:

  • Frequency limits shared between CDT codes.

  • Waiting periods.

  • Restrictions, such as the missing tooth clause.

For more tips on reading eligibility responses, see our How to read a 271 eligibility response in plain English blog.

How “real time” are Stedi’s real-time eligibility checks?

Most responses come back in 3-4 seconds.

But it depends on the payer. Some take longer – up to 60 seconds.

To handle slow responses, Stedi keeps the request open for up to 2 minutes. During that time, we retry the request in the background if needed.

Can I run dental eligibility checks in batches?

Yes. Use the Batch Eligibility Check API to send up to 1,000 checks at once. This works well if you want to refresh coverage data before appointments.

Batch checks are asynchronous. They don’t count toward your real-time concurrency limit. But the response can take longer – sometimes up to 8 hours.

Got more questions?

Contact us to talk to a dental eligibility expert at Stedi.

Insurance verification is important for dental care. Before the provider can get paid, they need to know what a patient’s plan covers. The patient needs to know too – so they’re not surprised by a bill later.

That’s where Stedi comes in. We make it easy to check dental insurance in real time. Stedi's Eligibility Check APIs let you work with JSON or raw X12 EDI. You can check coverage with thousands of payers, including major dental insurers like Delta Dental, DentaQuest, and Guardian.

This post answers the most common questions we hear from developers using Stedi to check dental eligibility.

What STCs should I use for dental?

A Service Type Code (STC) tells the payer what kind of benefits you're checking. For general dental coverage, use STC 35 (Dental Care) in the eligibility request:

"encounter": {
  "serviceTypeCodes": ["35"]
}

If you leave it out, Stedi defaults to 30 (Health Benefit Plan Coverage). This may return incomplete or irrelevant data. Many payers only return dental benefits for STC 35.

Other common dental STCs include:

  • 4 - Diagnostic X-Ray

  • 5 - Diagnostic Lab

  • 23 - Diagnostic Dental

  • 24 - Periodontics

  • 25 - Restorative

  • 26 - Endodontics

  • 27 - Maxillofacial Prosthetics

  • 28 - Adjunctive Dental Services

  • 36 - Dental Crowns

  • 37 - Dental Accident

  • 38 - Orthodontics

  • 39 - Prosthodontics

  • 40 - Oral Surgery

  • 41 - Routine (Preventive) Dental

Most payers only support one STC per request. Don’t send multiple STCs unless you’ve tested that it works. For testing tips, see our How to avoid eligibility check errors blog.

Which payers support dental eligibility checks?

There’s no definitive list. Stedi supports eligibility checks for most major dental payers. But not all of them return dental-specific data – even if they support eligibility checks in general.

To check if a payer returns dental data, run a check with STC 35 and look at the response. In our tests, more than half of payers return active dental coverage when you use STC 35.

Can I use CDT codes in eligibility checks?

Yes – but support depends on the payer.

Current Dental Terminology (CDT) codes are procedure codes used in dental billing. For example, D0120 is a routine exam.

You can send a CDT code in your request using the productOrServiceIDQualifier and procedureCode fields. But many payers will return the same data you’d get from STC 35. Those results often include CDT code-level benefits.

To test it, send one request with the CDT code and one with STC 35 to the same payer. Then compare what you get back.

What’s included in dental eligibility responses?

This depends on the payer, but most responses include the following.

Basic coverage
These fields confirm whether the member has dental coverage and when it starts and ends:

  • Coverage status (active/inactive): benefitsInformation.code ("1" = Active, "6" = Inactive).

    Plan start and end dates: planInformation.planBeginDate and planInformation.planEndDate.

Patient responsibility
These fields tell you what the patient might owe:

  • Co-insurance and deductible: benefitsInformation.code and benefitsInformation.benefitPercent or benefitsInformation.benefitAmount.

    Coverage levels for common categories, such as diagnostic or preventative: benefitsInformation.serviceTypeCode (35 for basic or 41 for preventive).

Lifetime maximums
Many dental plans include lifetime maximums. These often show up as two entries with the same benefitsInformation.code.

For example, one for the total lifetime maximum:

{
  "code": "F",
  "serviceTypeCodes": ["38"],
  "benefitAmount": 2000,		// $2,000 amount
  "timeQualifierCode": "32"		// Lifetime maximum
}

One for the remaining amount:

{
  "code": "F",
  "serviceTypeCodes": ["38"],
  "benefitAmount": 1200,		// $1,200 amount
  "timeQualifierCode": "33"		// Lifetime remaining
}

CDT-level detail
Many payers return benefits tied to specific CDT codes, using compositeMedicalProcedureIdentifier:

{
  "code": "A",  				              // Co-insurance
  "insuranceTypeCode": "GP",  		          // Group policy
  "benefitPercent": "0",  			          // Patient owes 0% co-insurance for procedure
  "compositeMedicalProcedureIdentifier": {
    "productOrServiceIDQualifierCode": "AD",  // CDT code qualifier
    "procedureCode": "D0372"  		          // CDT code for the procedure
  },
  "benefitsDateInformation": {
    "latestVisitOrConsultation": "202420722"  // Most recent date this procedure was used
  }
}

Cigna is a known edge case. It puts CDT info in additionalInformation.description as free text.

Age limitations
Age limitations use one of the following quantityQualifierCode values:

  • S8 - Age, Minimum

  • S7 - Age, Maximum

The benefitQuantity is the minimum or maximum age allowed.

{
  // Age limit: patient must be at least 18 years old
  "quantityQualifierCode": "S8",	// Age (minimum)
  "benefitQuantity": "18"

}

Frequency limitations
 Frequency limitations typically use one of the following quantityQualifierCode values:

  • P6 - Number of Services or Procedures

  • VS - Visits

The timePeriodQualifierCode defines the time window (such as 7 for per year). The benefitQuantity sets the frequency limit.

{
  // Frequency limit: 2 services per calendar year
  "quantityQualifierCode": "VS",  			// Visits
  "benefitQuantity": "2",
  "timePeriodQualifierCode": "7",  			// Annual
  "numOfPeriods": "1",
}

History
Many payers include the last time a procedure was done. This shows up in benefitsDateInformation.latestVisitOrConsultation.

Example at the STC level:

{
  // STC-level entry
  "code": "A",                                // Co-insurance
  "insuranceTypeCode": "GP",                  // Group policy
  "benefitPercent": "80",                     // 80% covered
  "serviceTypeCodes": ["41"],                 // Routine (Preventive) Dental
  "benefitsDateInformation": {
    "latestVisitOrConsultation": "20240301"   // Last preventive service date
  }
}

At the CDT level:

{
  // CDT code-level entry
  "compositeMedicalProcedureIdentifier": {
    "productOrServiceIDQualifierCode": "AD",  // CDT code qualifier
    "procedureCode": "D0150"                  // Comprehensive oral evaluation
  },
  "benefitsDateInformation": {
    "latestVisitOrConsultation": "20240404"   // Last time this procedure was used
  }
}

Free-text details
Some payers add notes as free text in additionalInformation.description, like:

  • Frequency limits shared between CDT codes.

  • Waiting periods.

  • Restrictions, such as the missing tooth clause.

For more tips on reading eligibility responses, see our How to read a 271 eligibility response in plain English blog.

How “real time” are Stedi’s real-time eligibility checks?

Most responses come back in 3-4 seconds.

But it depends on the payer. Some take longer – up to 60 seconds.

To handle slow responses, Stedi keeps the request open for up to 2 minutes. During that time, we retry the request in the background if needed.

Can I run dental eligibility checks in batches?

Yes. Use the Batch Eligibility Check API to send up to 1,000 checks at once. This works well if you want to refresh coverage data before appointments.

Batch checks are asynchronous. They don’t count toward your real-time concurrency limit. But the response can take longer – sometimes up to 8 hours.

Got more questions?

Contact us to talk to a dental eligibility expert at Stedi.

Share

Twitter
LinkedIn

Get started with Stedi

Get started with Stedi

Automate healthcare transactions with developer-friendly APIs that support thousands of payers. Contact us to learn more and speak to the team.

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 is a registered trademark 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 is a registered trademark 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 is a registered trademark 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.