Skip to main content
All Yotel API errors return a consistent JSON shape. This page catalogs every error type, including domain-specific errors from voice agents and AI sessions.

Error response format

{
  "detail": "Human-readable error description"
}
For validation errors (422), Pydantic returns a list:
{
  "detail": [
    {
      "loc": ["body", "predictive_target_abandon"],
      "msg": "ensure this value is less than or equal to 0.03",
      "type": "value_error.number.not_le"
    }
  ]
}

Standard HTTP status codes

StatusMeaningWhen
200OKSuccessful read or update
201CreatedResource created (campaigns, leads, voice agents, keys, webhooks)
204No ContentSuccessful delete
400Bad RequestMalformed request or query param out of range
401UnauthorizedMissing, malformed, or expired auth token
403ForbiddenValid token but insufficient scope or permission
404Not FoundResource doesn’t exist or belongs to another tenant
409ConflictState-based conflict (see domain-specific errors below)
422Validation ErrorRequest body fails Pydantic validation
429Too Many RequestsRate limit exceeded — check Retry-After header
500Internal Server ErrorUnexpected server error
Cross-tenant access always returns 404, never 403. This prevents attackers from confirming whether a resource exists in another tenant.

Authentication errors

ErrorStatusdetailCause
Malformed key401"API key must start with yt_live_ or yt_test_"Key doesn’t match expected format
Invalid key401"Invalid API key"Key not found or revoked
Scope denied403"Scope 'X' required"Key lacks the required scope for this endpoint
Rate limited429"Rate limit exceeded"Per-key request budget exhausted

Campaign errors

ErrorStatusCause
InvalidCampaignState409Invalid state transition (e.g., starting a completed campaign)
Abandon rate validation422predictive_target_abandon exceeds 0.03 (TRAI hard cap)
Predictive ratio range422predictive_max_ratio < predictive_min_ratio
Delete while running409Cannot delete a running campaign — pause or stop first

Voice agent errors

ErrorStatusdetailCause
NoVoiceAgentConfigured424"No voice agent resolved"The override hierarchy (flow → campaign → tenant default) resolved no agent. Set a tenant default or pin one per campaign.
VoiceAgentInUse409"Voice agent has active sessions"Cannot hard-delete a voice agent with in-progress calls. Use archive instead.
MaxConcurrentExceeded429"Max concurrent sessions reached"The voice agent’s max_concurrent limit is hit. Wait for active sessions to end or increase the limit.

AI session errors

ErrorStatusdetailCause
AISessionTerminated410"AI session already ended"Sending a control verb to a call that has already hung up.
ConferenceMembershipRequired403"Whisper requires conference membership"whisper, barge, or monitor verbs require the call to be in an active conference. Call conference_start first.
Token mismatch403"Token call_id mismatch"The callback token’s embedded call_id doesn’t match the URL path.
Cross-tenant404"Call not found"The call belongs to a different tenant than the auth context.

Recording errors

ErrorStatusCause
Not yet available409Recording upload pipeline still processing. Wait for the call.recording_ready webhook.
Call not found404Call doesn’t exist or belongs to another tenant.

Webhook management errors

ErrorStatusCause
URL not HTTPS422Webhook URL must use https://
Test tenant URL422Test tenants can only register localhost, 127.0.0.1, *.ngrok.io, or *.test.yotel.in

Validation patterns

Common validation rules enforced across the API:
RuleEndpointsdetail
Indian phone formatLeads10 digits, optional 0/91 prefix; 5–20 chars raw
WebSocket URL formatVoice agentsMust start with ws:// or wss://
TRAI abandon capCampaignspredictive_target_abandon ≤ 0.03
Rate limit rangeAPI keysrate_limit_per_min must be 1–100,000
Stats window rangeAgentswindow_hours must be 1–720
Bulk lead limitLeadsMax 500 leads per :bulk request

Rate limit headers

Successful responses include:
HeaderDescription
X-RateLimit-LimitPer-minute budget
X-RateLimit-RemainingRemaining requests this window
On 429 responses:
HeaderDescription
Retry-AfterSeconds until the next minute boundary
Both SDKs auto-retry on 429 with exponential backoff (configurable).