Call2Me
Developers

Errors and rate limits: what to retry, what to surface

HTTP status codes Call2Me returns, rate limit headers, retry-after semantics, and the patterns that make integrations survive carrier hiccups.

Updated May 6, 2026

Most production issues don't come from the happy path — they come from how integrations handle the unhappy ones. This is the reference for what the platform returns and how to react.

Status codes you'll see

CodeMeaningWhat to do
200 OKSuccess
201 CreatedResource createdRead Location header for canonical URL
400 Bad RequestValidation failedFix the request; don't retry as-is
401 UnauthorizedMissing or bad authCheck Bearer token; do NOT retry
402 Payment RequiredWallet too lowTop up, then retry
403 ForbiddenAuth okay, scope insufficientMint a key with the right scope
404 Not FoundResource doesn't existDon't retry; check the ID
409 ConflictIdempotency or state conflictInspect; usually no retry
422 UnprocessableSchema valid but logically wrongFix the request
429 Too Many RequestsRate limitedBack off; respect Retry-After
500 Internal Server ErrorPlatform side bugRetry with exponential backoff
502 / 503 / 504Upstream issueRetry with exponential backoff

Error response shape

Every error has the same body:

{
  "error": {
    "code": "validation_failed",
    "message": "to_number must be in E.164 format",
    "field": "to_number",
    "request_id": "req_abc123"
  }
}

Always log request_id. When you open a support ticket, that's the only piece of info we need to trace the request through every internal hop.

Rate limits

Limits are per-API-key, sliding window. Each response includes:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1714998000

When you hit zero:

HTTP/1.1 429 Too Many Requests
Retry-After: 12

Retry-After is in seconds. Wait that long, then retry. If you're seeing 429 frequently, contact support to discuss raising your limits — for high-volume customers we tune them per workspace.

Idempotency

For POST requests that create resources (/v1/calls, /v1/agents, /v1/schedules), pass an Idempotency-Key header:

curl -X POST https://api.call2me.app/v1/calls \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: 8c7b3a4d-1e2f-4abc-9def-0123456789ab" \
  -H "Content-Type: application/json" \
  -d '{...}'

The platform stores the response keyed by your idempotency key for ~24 hours. A retry with the same key returns the cached response — no duplicate call placed, no duplicate agent created.

Use a fresh UUID per logical request; don't reuse keys across genuinely different requests.

Retry strategy that works in production

attempt 1 → fail with 502
wait 1s
attempt 2 → fail with 502
wait 2s
attempt 3 → fail with 502
wait 4s
attempt 4 → succeed

Caps to apply:

  • max attempts: 5
  • max total wait: 30s
  • never retry 4xx (except 408, 429)
  • always honor Retry-After if present

Most HTTP client libraries have this built in — use the library, don't reinvent it.

What's next

  • Authentication — the 401 and 403 root causes
  • Webhooks — retry semantics for events you receive
  • Pricing — when 402 is right and what to do about it

Frequently asked

Q.Are 5xx errors safe to retry?

Yes — with exponential backoff. 5xx means the platform side failed; idempotent operations (GET, PUT, DELETE) can be retried as-is. For POST, use the Idempotency-Key header to make retries safe.

Q.How does rate limiting work?

Per-API-key, sliding window. Headers X-RateLimit-Limit and X-RateLimit-Remaining tell you where you stand. When you hit zero, you get 429 with a Retry-After header.

Q.What's an idempotency key?

A client-generated UUID you send with POST requests. The platform deduplicates within a short window — retrying with the same key returns the cached response instead of creating a duplicate.

Q.Why am I getting 402 Payment Required?

Wallet balance is below the minimum to start a call. Top up via dashboard or POST /v1/wallet/topup, then retry.

ShareX / TwitterLinkedIn

Ready to ship?

Spin up your first agent in 5 minutes — $10 free credit.

Start free