CheckBenefits
Overview
CheckBenefitsTask verifies insurance eligibility and retrieves benefits information (coverage status, plan details, deductibles, copays, etc.) for visits by making real-time API calls to insurance providers like Availity. It processes visits identified by a SQL query or auto-generated from eligibility settings, creates eligibility transactions, and updates visit coverage information.
Use this task when: You need to perform scheduled eligibility verification for upcoming visits, verify insurance coverage before appointments, or refresh benefits information for visits with configured insurances.
Don't use this task when:
- Checking benefits for a single visit in real-time (use
CheckBenefitsRealTimeinstead) - You don't have ExternalAPI configurations set up for insurances
- Visits have already been verified recently (task includes smart de-duplication logic)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
Query |
string |
No | Auto-generated from EligibilitySettings | SQL query that returns visits to check benefits for. Must return columns: Visit, Insurance, MemberID, ServiceType, and optionally GroupID, ProcedureCode, ExcludeMemberID, ExcludeDOB, ExcludePatientName, COB. If null or empty (only comments), the task auto-generates a query based on customer and insurance EligibilitySettings. |
Execution Flow
Processing Algorithm
The task uses an intelligent eligibility verification algorithm with de-duplication and grouping:
Query Generation (when Query is null/empty)
- Check Execution Frequency: Determines if this is a "future visits" check day by comparing
CheckBenefitsHistory.LastRun.Datewith current date - Build Base Query: Constructs a query that:
- Selects visits from
VisitorVisitBatchtable (depending on batch mode) - Joins to
Quoteto get service types (combines visit-level "30" with quote-specific service types) - Filters by
ScheduledDate >= Today(only future visits) - Excludes visits already successfully checked today for the same service type
- Excludes visits with 3 consecutive failures
- Excludes visits where the last check resulted in inactive coverage status
- Only includes primary coverage (COB=1) or non-included coverages without existing successful checks
- Selects visits from
- Apply Eligibility Settings Filters: For each insurance, adds filters based on:
WhenScheduled: Check if visit has never been verified beforeFirstOfEveryMonth: Check if today is the 1st of the monthDayBeforeAppointment: Check if scheduled date is tomorrowWeekBeforeAppointment: Check if scheduled date is 7 days outDaysOutFromAppointment: Check if scheduled date matches specific days outFirstOfScheduledMonth: Check if today is the 1st of the visit's scheduled monthFirstOfScheduledYear: Check if today is the 1st of the visit's scheduled yearStatuses: Filter visits by status (e.g., only "Scheduled")
Service Type Grouping
- Identify Multi-Service-Type APIs: Check which insurance APIs support multiple service types in a single request (e.g., Availity)
- Group Inputs: Group check inputs by
Visit,Insurance,MemberID,GroupID,ProcedureCode,COB,ExcludeDOB,ExcludeMemberID,ExcludePatientName - Aggregate Service Types: For grouped inputs, combine service types into a single comma-delimited list
- Reduction: Log reduction from original input count to final grouped count
API Execution
- Group by Provider: Group all inputs by
APIProviderType(Availity, AvailityMedicare → Availity) - For Each API Group:
- Load visits from both
VisitandVisitBatchtables (batch visits take precedence) - Load associated facilities and patients
- Generate new eligibility transaction keys
- Build
EligibilityRequestInputsfor each check - Call
EligibilityProcessor.SendBatchEligibility()with all inputs - Parse benefits responses and update visit coverage info (PlanName, PlanType, GroupName, CoverageStatus)
- Save transactions to
EligibilityTxnBatch - Save updated visits to
VisitBatch
- Load visits from both
- Copy Transactions: Move all transactions from
EligibilityTxnBatchtoEligibilityTxn
Example Execution
Scenario: Running CheckBenefits with auto-generated query on the 1st of the month for 3 visits:
Configuration:
- Customer EligibilitySettings: FirstOfEveryMonth = true, WhenScheduled = true
- Insurance "Aetna PPO": Uses customer settings
- Insurance "Blue Cross": DayBeforeAppointment = true (overrides customer settings)
Visits:
- V-1: Aetna PPO, scheduled 2025-02-15, never checked before
- V-2: Blue Cross, scheduled tomorrow (2025-01-02)
- V-3: Aetna PPO, scheduled 2025-02-20, checked today already
Execution:
1. Generate query:
- V-1 included: FirstOfEveryMonth=true AND WhenScheduled=true (first check)
- V-2 included: DayBeforeAppointment=true (tomorrow)
- V-3 excluded: Already checked today with RequestSuccess=1
2. Query returns 2 inputs (V-1 and V-2)
3. Group by API:
- Availity group: [V-1 Aetna, V-2 Blue Cross]
4. Load visits, facilities, patients
5. Call Availity API with 2 eligibility requests
6. Parse responses:
- V-1: Active coverage, Aetna PPO Plan, update visit coverage
- V-2: Active coverage, Blue Cross HMO Plan, update visit coverage
7. Save 2 EligibilityTxn records to EligibilityTxnBatch
8. Save 2 updated Visit records to VisitBatch
9. Copy transactions to EligibilityTxn table
10. Save CheckBenefitsHistory with IncludeFutureVisits=false, LastRun=2025-01-01
Usage Examples
Example 1: Scheduled daily eligibility check (auto-generated query)
// Run nightly for all visits that need eligibility verification based on settings
var task = new CheckBenefitsTask
{
Query = null // Auto-generate query from customer and insurance EligibilitySettings
// The task will check:
// - Visits scheduled for tomorrow (if DayBeforeAppointment=true)
// - Visits scheduled 7 days out (if WeekBeforeAppointment=true)
// - All visits never checked before (if WhenScheduled=true)
// - Visits on the 1st of the month (if FirstOfEveryMonth=true)
// etc.
};
Example 2: Check benefits for specific visits via custom query
var task = new CheckBenefitsTask
{
Query = @"
SELECT
Visit = v.[Key],
Insurance = v.InsuranceKey,
MemberID = v.MemberID,
GroupID = v.GroupID,
ServiceType = '30'
FROM VisitBatch v
WHERE v.FacilityKey = 'FAC-001'
AND v.ScheduledTime >= GETDATE()
AND v.Status = 'Scheduled'"
// Only check visits at facility FAC-001 scheduled in the future
};
Example 3: Check benefits for visits with multiple service types
var task = new CheckBenefitsTask
{
Query = @"
SELECT
Visit = v.[Key],
Insurance = v.InsuranceKey,
MemberID = v.MemberID,
ServiceType = q.ServiceTypeCode,
COB = c.COB
FROM VisitBatch v
INNER JOIN QuoteBatch q ON q.VisitKey = v.[Key]
CROSS APPLY v.Body.nodes('/Entity/Coverages/Coverage') AS Coverages(c)
WHERE v.ScheduledTime BETWEEN '2025-02-01' AND '2025-02-28'
AND c.value('(./Insurance/text())[1]', 'varchar(100)') = v.InsuranceKey"
// Check benefits for each quote's service type for February visits
};
Example 4: Exclude patient demographics from eligibility request
var task = new CheckBenefitsTask
{
Query = @"
SELECT
Visit = v.[Key],
Insurance = v.InsuranceKey,
MemberID = v.MemberID,
ServiceType = '30',
ExcludeMemberID = 1, -- Don't send MemberID to API
ExcludeDOB = 1, -- Don't send date of birth to API
ExcludePatientName = 0 -- Send patient name to API
FROM VisitBatch v
WHERE v.ScheduledTime >= GETDATE()"
// Use when you want to control which patient demographics are sent to the API
};
Related Tasks Comparison
| Task | Scope | Trigger | Execution Mode | Use Case |
|---|---|---|---|---|
| CheckBenefitsTask | Batch (SQL query) | Scheduled or manual | Batch API calls to provider | Scheduled verification for multiple visits |
CheckBenefitsRealTime |
Single visit | User action or API call | Single API call | Real-time verification when viewing/editing a visit |
AutoApplyBenefitsTask |
Batch (visits with eligibility txns) | After CheckBenefits | Batch processing | Apply benefits from existing eligibility transactions to visits |
Key Differentiators:
- CheckBenefitsTask makes external API calls to retrieve eligibility data
- AutoApplyBenefitsTask uses existing eligibility transactions and applies benefits via AutoBenefitsRule matching
- CheckBenefitsTask is typically run before AutoApplyBenefitsTask in a pipeline
- CheckBenefitsRealTime is for single-visit, immediate verification (UI-driven)
- Only CheckBenefitsTask supports auto-generated queries based on EligibilitySettings
Typical Pipeline:
CheckBenefitsTask → AutoApplyBenefitsTask
(Verify eligibility) → (Apply benefits to visits)
Performance Considerations
Database Impact
- Tables Read:
VisitorVisitBatch: Visits to check (depends on batch mode and query)QuoteorQuoteBatch: Service types for visitsPatient: Patient demographics for API requestsFacility: Facility NPI for API requestsInsurance: Insurance configurations and eligibility settingsExternalAPI: API provider configurationsEligibilityTxn: De-duplication checks (recent successful checks, failure counts)CheckBenefitsHistory: Determines if future visits check should run
- Tables Written:
EligibilityTxnBatch: Truncated at start, populated with new transactions during processingEligibilityTxn: New transactions copied from EligibilityTxnBatch at endVisitBatch: Updated visits with coverage informationCheckBenefitsHistory: Execution history record
- Query Patterns:
- Complex auto-generated query with multiple EXISTS subqueries for de-duplication
- Batch loads of visits, patients, facilities (1000-record batches)
- XML parsing of visit coverage data
- Bulk Operations:
- Uses
SaveManywith bulk mode for eligibility transactions and visits - Truncate operation on EligibilityTxnBatch at start
- Single INSERT INTO SELECT for copying transactions to EligibilityTxn
- Uses
External API Impact
- API Calls: One batch request per API provider group (Availity, Change Healthcare, etc.)
- Rate Limiting: Respects API provider rate limits via
IWaitercomponent - Retry Logic: Handled by
EligibilityProcessorimplementations - Timeouts: Long-running for large batches (API-dependent)
- Cost: Each eligibility check may incur a cost from the API provider
Optimization Tips
| Scenario | Recommendation | Rationale |
|---|---|---|
| Large visit counts (1000+) | Run during off-hours; monitor API quotas | External API calls are slow and may have rate limits |
| Frequent execution | Use auto-generated query with smart settings | De-duplication logic prevents redundant checks |
| Multiple service types per visit | Ensure insurance supports multi-service-type requests | Reduces API call count significantly |
| API timeouts | Reduce batch size or split by insurance | Some APIs have lower concurrency limits |
| First-time setup | Test with small custom query before using auto-generation | Verify API connectivity and configurations |