Skip to main content

Error Code Reference

Every Orbit API error response includes a machine-readable code, human-readable message, HTTP status, and contextual details. Use this reference to diagnose and resolve errors programmatically.

Error Response Format

{
  "error": {
    "code": "INVALID_PHONE_NUMBER",
    "message": "The 'to' field must be a valid E.164 phone number",
    "status": 422,
    "details": {
      "field": "to",
      "value": "+1234",
      "expected": "E.164 format e.g. +14155552671"
    }
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2026-03-08T00:00:00Z",
    "docs_url": "https://orbit-docs.devotel.io/errors/INVALID_PHONE_NUMBER"
  }
}

Authentication & Authorization

CodeHTTPDescriptionResolution
UNAUTHORIZED401Missing or invalid authenticationInclude a valid X-API-Key header or Authorization: Bearer token
INVALID_API_KEY401API key is malformed, revoked, or does not existGenerate a new key in Settings > API Keys
EXPIRED_TOKEN401JWT bearer token has expiredRe-authenticate to obtain a fresh token
INSUFFICIENT_PERMISSIONS403Authenticated identity lacks the required RBAC roleCheck the user’s role (owner, admin, developer, viewer, billing)
FORBIDDEN403Access to the resource is deniedVerify the resource belongs to your organization

Validation

CodeHTTPDescriptionResolution
VALIDATION_ERROR400/422One or more fields failed validationCheck details.field and details.expected for specifics
INVALID_PHONE_NUMBER422Phone number not in E.164 formatFormat as +[country code][number] (e.g., +14155552671)
INVALID_EMAIL422Email address is syntactically invalidVerify the email format
INVALID_TEMPLATE422Message template is malformed or has missing parametersCheck template variables match the content
MISSING_REQUIRED_FIELD422A required field was omittedSee details.field for the missing field name
INVALID_CURSOR400Pagination cursor is malformed or expiredStart pagination from the beginning without a cursor
INVALID_WEBHOOK_URL422Webhook URL is unreachable or returned an errorEnsure the URL is publicly accessible and returns 2xx

Resource

CodeHTTPDescriptionResolution
NOT_FOUND404Resource does not existVerify the ID or path
ALREADY_EXISTS409Duplicate unique key (e.g., phone number in contacts)Use a different identifier or update the existing resource
CONFLICT409Operation conflicts with current resource stateCheck the resource status before retrying
TENANT_NOT_FOUND404Organization not found for this API keyVerify your API key is associated with an active organization

Rate Limiting

CodeHTTPDescriptionResolution
RATE_LIMIT_EXCEEDED429Too many requests in the current windowWait details.retry_after seconds, then retry. See Rate Limits
QUOTA_EXCEEDED429Plan-level quota reachedUpgrade your plan or wait for the next billing cycle
BURST_LIMIT_EXCEEDED429Too many requests per secondSpread requests more evenly across time

Messaging

CodeHTTPDescriptionResolution
MESSAGE_SEND_FAILED500Downstream provider rejected the messageRetry with POST /v1/messages/{id}/retry
CHANNEL_UNAVAILABLE503Channel is temporarily offline or not configuredVerify channel configuration in dashboard; retry later
TEMPLATE_NOT_APPROVED422WhatsApp/RCS template not approved by carrierSubmit for approval in Messages > Templates
INVALID_RECIPIENT422Recipient is unreachable or blocked by carrierVerify the number is active and not on a block list
RECIPIENT_OPTED_OUT422Recipient opted out of communicationsRemove from send list; do not retry
MESSAGE_TOO_LONG422Message body exceeds maximum lengthReduce content or split into multiple messages
MEDIA_TOO_LARGE422Attached media exceeds size limitCompress or resize media (max 16 MB for WhatsApp)
SENDER_NOT_CONFIGURED422No sender number configured for the channelPurchase and configure a number for this channel

Voice

CodeHTTPDescriptionResolution
CALL_FAILED500Outbound call could not be placedCheck the destination number and SIP trunk config
SIP_ERROR502SIP-level error from the trunkSee details.sip_code for the SIP response code
VOICE_GATEWAY_ERROR502Voice gateway internal errorRetry; contact support if persistent
CALL_NOT_FOUND404Call ID does not exist or has expiredVerify the call ID
CALL_ALREADY_ENDED409Attempted to modify a completed callNo action needed

AI Agents

CodeHTTPDescriptionResolution
AGENT_ERROR500Agent failed during executionCheck agent logs in the dashboard
LLM_PROVIDER_ERROR502LLM provider returned an errorTransient — retry with backoff
GUARDRAIL_VIOLATION422Output blocked by Portkey guardrailReview guardrail config in agent settings
AGENT_NOT_DEPLOYED422Agent is in draft or paused stateDeploy or resume the agent first
TOOL_EXECUTION_FAILED500Agent tool call failedCheck tool endpoint availability
CONTEXT_TOO_LONG422Conversation context exceeds model limitStart a new conversation or reduce context

Numbers

CodeHTTPDescriptionResolution
NUMBER_NOT_AVAILABLE409Number was claimed by another customerSearch for a different number
NUMBER_ALREADY_OWNED409Number is already on your accountNo action needed
PORT_REQUEST_FAILED422Number porting request was rejectedVerify carrier info and authorization name

Billing

CodeHTTPDescriptionResolution
PAYMENT_REQUIRED402Valid payment method requiredAdd a card in Settings > Billing
SUBSCRIPTION_INACTIVE403Subscription is paused or cancelledReactivate in Settings > Billing
INSUFFICIENT_CREDITS402Prepaid credit balance too lowTop up credits via API or dashboard
CHECKOUT_EXPIRED410Checkout session has expiredCreate a new checkout session

System

CodeHTTPDescriptionResolution
INTERNAL_ERROR500Unexpected server errorInclude request_id when contacting support
SERVICE_UNAVAILABLE503Service temporarily down or overloadedRetry with exponential backoff
WEBHOOK_DELIVERY_FAILED500Webhook delivery to your endpoint failedCheck endpoint availability and response time
MAINTENANCE_MODE503Scheduled maintenance in progressCheck status.devotel.io

Handling Errors in Code

Node.js

import { Devotel, DevotelApiError } from '@devotel/sdk'

try {
  await devotel.messages.send({ channel: 'sms', to: 'invalid', body: 'Hi' })
} catch (error) {
  if (error instanceof DevotelApiError) {
    console.error(`[${error.code}] ${error.message}`)
    console.error(`Status: ${error.status}`)
    console.error(`Request ID: ${error.requestId}`)
  }
}

Python

from devotel import Devotel, DevotelApiError

try:
    devotel.messages.send(channel="sms", to="invalid", body="Hi")
except DevotelApiError as e:
    print(f"[{e.code}] {e.message}")
    print(f"Status: {e.status}")
    print(f"Request ID: {e.request_id}")
Always include the request_id from the error response meta when contacting Orbit support. This allows us to trace the exact request through our infrastructure.