Your integration is live. The AI assistant is calling resolveScheduling. And then, sometimes β nothing. options: []. The user sees "no availability" and leaves. You lost the booking. You don't know why.
This is the zero-results problem. It's not a bug in your code β it's a configuration gap in your provider network. Orita's analytics endpoint surfaces exactly which rules are excluding providers, so you can fix the right thing instead of guessing.
The Problem in Detail
When resolveScheduling returns zero results, Orita evaluated every provider in your network and found that none of them satisfied the constraints. The resolution completes successfully β it's not an error. But the status is "zero_results" and options is empty.
The user experience is a dead end. The business impact is a lost booking. And without analytics, you have no way to know whether the issue is:
- A provider missing a language configuration
- Every provider's calendar being full
- A constraint that's too narrow for your current network
- A single misconfigured provider who's being excluded for the wrong reason
The analytics endpoint tells you the answer with data.
The Analytics Endpoint
curl "https://api.orita.online/api/v1/analytics?days=30" \
-H "Authorization: Bearer $ORITA_API_KEY"
Full response shape:
{
"resolutions": {
"total": 1240,
"resolved": 987,
"zeroResults": 253,
"confirmed": 612,
"successRate": 0.796,
"zeroResultRate": 0.204,
"resolutionToBookingConversion": 0.620,
"topExclusions": [
{ "code": "NO_LANGUAGE_MATCH", "count": 189 },
{ "code": "NO_AVAILABLE_SLOTS", "count": 98 },
{ "code": "MODALITY_NOT_SUPPORTED", "count": 41 }
],
"zeroResultReasons": [
{ "code": "NO_LANGUAGE_MATCH", "count": 134 },
{ "code": "NO_AVAILABLE_SLOTS", "count": 71 },
{ "code": "SERVICE_NOT_SUPPORTED", "count": 48 }
]
},
"bookings": {
"total": 612,
"pending": 45,
"confirmed": 498,
"cancelled": 69,
"cancellationRate": 0.113
}
}
Key Metrics to Monitor
| Field | What It Tells You |
|-------|------------------|
| zeroResultRate | % of resolutions that returned no options β your network health score |
| topExclusions | Rules that excluded providers across all resolutions (including ones that still returned results) |
| zeroResultReasons | Rules that caused complete zero-result responses β most actionable |
| resolutionToBookingConversion | % of non-zero resolutions that became confirmed bookings |
topExclusions vs zeroResultReasons:
topExclusions tells you which rules are trimming your option lists (you might still get results, just fewer). zeroResultReasons tells you which rules caused total failure. Fix zeroResultReasons first β they're directly losing bookings.
Reading the Exclusion Codes
Here's what each exclusion code means and what to do about it:
NO_LANGUAGE_MATCH
What it means: The resolution required a provider with languageCodes: { anyOf: ["es"] }, but the matched providers have no language set or have a different language code.
Common causes:
- Provider's
languagesarray is empty[] - Language code format mismatch β
"spanish"vs"es"(Orita uses ISO 639-1 codes) - Provider added to network but language never configured
How to fix: Update the provider's agent profile with the correct language codes:
curl -X PUT "https://api.orita.online/api/v1/providers/:providerId/profile" \
-H "Authorization: Bearer $ORITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"languages": ["es", "en"],
"agentProfile": {
"languageCodes": ["es", "en"]
}
}'
MODALITY_NOT_SUPPORTED
What it means: The resolution required modalityCodes: { anyOf: ["virtual"] }, but the provider is configured for in-person only and their agentProfile does not include telehealth.
Common causes:
agentProfile.telehealthisfalseor missing- Provider added before telehealth was enabled on the platform
- Provider updated their preferences to in-person only
How to fix:
curl -X PUT "https://api.orita.online/api/v1/providers/:providerId/profile" \
-H "Authorization: Bearer $ORITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentProfile": {
"telehealth": true,
"modalityCodes": ["virtual", "in_person"]
}
}'
SERVICE_NOT_SUPPORTED
What it means: The resolution requested service: "therapy", but no active event type on this provider matches that service name.
Common causes:
- Provider's event types are named differently β
"Therapy Session"vs"therapy" - Event type exists but is set to inactive/draft
- Provider never set up their event types after onboarding
How to fix: Create or activate the matching event type:
curl -X POST "https://api.orita.online/api/v1/providers/:providerId/event-types" \
-H "Authorization: Bearer $ORITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"serviceCode": "therapy",
"name": "Therapy Session",
"durationMinutes": 60,
"active": true
}'
NO_AVAILABLE_SLOTS
What it means: The provider matches all constraints but has no open slots in the requested date range. Either their calendar is fully booked, or they haven't configured availability for that period.
Common causes:
- Provider hasn't set up a recurring availability schedule
- Requested week is fully booked
- Provider is on vacation / out-of-office
How to fix: Check if availability is configured:
curl "https://api.orita.online/api/v1/providers/:providerId/availability" \
-H "Authorization: Bearer $ORITA_API_KEY"
If empty, set a schedule:
curl -X POST "https://api.orita.online/api/v1/providers/:providerId/availability" \
-H "Authorization: Bearer $ORITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"timezone": "America/New_York",
"weeklySchedule": {
"monday": [{ "start": "09:00", "end": "17:00" }],
"tuesday": [{ "start": "09:00", "end": "17:00" }],
"wednesday": [{ "start": "09:00", "end": "17:00" }],
"thursday": [{ "start": "09:00", "end": "17:00" }],
"friday": [{ "start": "09:00", "end": "13:00" }]
}
}'
Tracking Conversion
resolutionToBookingConversion is the ratio of confirmed bookings to resolved (non-zero) resolutions. A low conversion rate with a low zero-result rate is a different problem than a high zero-result rate.
| Scenario | Likely Cause |
|----------|-------------|
| High zeroResultRate | Network configuration gaps β fix exclusion codes |
| Low conversion, low zeroResultRate | UX issue β options shown but not booked |
| Low conversion + high cancellationRate | Booking intent mismatch β wrong providers surfaced |
If your conversion is below ~50%, the issue probably isn't your provider network β it's how you're presenting options or what happens after the resolution. Consider A/B testing the option presentation UI, or checking whether the reason field in each option is surfaced to the user.
Weekly Monitoring Pattern
Set up a simple cron that alerts when zeroResultRate exceeds 20%:
// Runs weekly β e.g., Monday 9AM via Vercel cron or GitHub Actions
async function monitorResolutionHealth() {
const res = await fetch(
"https://api.orita.online/api/v1/analytics?days=7",
{ headers: { Authorization: `Bearer ${process.env.ORITA_API_KEY}` } }
);
const { resolutions } = await res.json();
const { zeroResultRate, topExclusions, zeroResultReasons, total } = resolutions;
if (zeroResultRate > 0.2) {
const topReason = zeroResultReasons[0];
const message = [
`β οΈ Orita zero-result rate: ${(zeroResultRate * 100).toFixed(1)}% over last 7 days`,
`Total resolutions: ${total}`,
`Top reason: ${topReason?.code} (${topReason?.count} resolutions affected)`,
``,
`All exclusion codes:`,
...zeroResultReasons.map((r: any) => ` β’ ${r.code}: ${r.count}`),
].join("\n");
await sendSlackAlert(message);
console.error(message);
} else {
console.log(`β
Zero-result rate: ${(zeroResultRate * 100).toFixed(1)}% β within threshold`);
}
}
You can also add a zeroResultRate > 0.5 escalation level that pages on-call. A 50%+ zero-result rate usually indicates something systemic β a constraint that's too strict, or a major provider whose configuration is broken.
Visual Debugging with the Resolution Explorer
For one-off investigations β "why did this specific user get zero results?" β use the Resolution Explorer at /resolution-explorer in your Orita dashboard. Enter a resolutionId and it shows you a provider-by-provider breakdown of which rules excluded each one, the constraint values that were checked, and what the provider's configured values actually were.
This is faster than reading raw logs when you're debugging a specific complaint from a user. The analytics endpoint is for trends; the Resolution Explorer is for individual incidents.
Summary: Your Zero-Results Debug Checklist
When zeroResultRate spikes:
- Fetch analytics β
GET /api/v1/analytics?days=7 - Read
zeroResultReasonsβ focus on the top code - Match the code to a fix:
NO_LANGUAGE_MATCHβ update providerlanguageCodesMODALITY_NOT_SUPPORTEDβ setagentProfile.telehealth: trueSERVICE_NOT_SUPPORTEDβ create/activate the event typeNO_AVAILABLE_SLOTSβ configure availability schedule
- Fix the provider(s) β use the profile or availability API
- Re-run a test resolution β verify options now return
- Monitor for 24h β confirm
zeroResultRatedrops
The analytics endpoint gives you the data. The fix is almost always a provider configuration update. Once you build this into your monitoring workflow, zero-result spikes become a quick 15-minute investigation instead of a guessing game.
