API errors and safe retry limits
Retry read operations conservatively after transient failures, but do not blindly retry POST /v1/calls because v1 has no idempotency contract; first reconcile any saved call ID, webhook, or application record.
Use the HTTP status, error value, and operation type together. A retry policy that is safe for a read can be unsafe for a call-creation command.
Error guide
Section titled “Error guide”| Result | Meaning | Default action |
|---|---|---|
400 invalid_request |
JSON or a field failed schema validation. | Correct the request; do not retry unchanged. |
401 unauthorized |
No active bearer key authenticated. | Fix or rotate the key. |
403 forbidden |
The key lacks a required scope. | Grant the narrow scope or use the correct key. |
403 compliance_blocked |
Product preflight rejected the call. | Inspect every block and correct evidence or context; never auto-bypass. |
404 not_found |
The requested call or resource does not exist. | Check the stored identifier and environment. |
502 dial_failed |
The dial operation failed. | Treat call creation as ambiguous until reconciled. |
502 pricing/source error |
A dependent read source is unavailable. | Retry the read with bounded backoff. |
503 configuration_error |
Required calling, usage, or audit configuration is unavailable. | Alert an operator; do not loop call creation. |
The call-creation boundary
Section titled “The call-creation boundary”POST /v1/calls currently has no idempotency key or idempotency contract. The service may create a call record before a later carrier or network failure becomes visible to your client. Repeating the same POST can therefore create another call.
Before any manual retry:
- check whether the first response included
idorcallId; - inspect your own request ledger for a stored CallOnline ID;
- check accepted webhook deliveries for the business operation;
- query the known call ID if one exists;
- require human review when the outcome remains ambiguous.
Create a client-side operation ID in metadata for correlation, but do not mistake that value for server-enforced idempotency.
Bounded read retries
Section titled “Bounded read retries”For GET operations, use exponential backoff with jitter and a hard limit. One reasonable application policy is 250 ms, 750 ms, and 2 seconds for three additional attempts, followed by a visible degraded state. That example is a client policy, not a CallOnline service-level promise.
Do not retry 400, 401, 403, or a stable 404 unless something relevant changed. Honor any future Retry-After header if the API adds one.
Webhook receiver retries
Section titled “Webhook receiver retries”Your receiver should safely accept duplicate delivery IDs. Return success for a previously accepted delivery instead of reapplying effects. If a webhook is delayed, reconcile with GET /v1/calls/{callId} rather than creating another call.
Purchase-session exception
Section titled “Purchase-session exception”Agent-commerce purchase session creation has its own idempotency key. That contract applies to purchase sessions only; it does not make POST /v1/calls idempotent.