Call Lens
Ingesting calls

Idempotency and replays

Why resubmitting a call is safe.

Submitting the same call twice returns 200 with the same call. Not a 409, not a duplicate, not an error.

{ "success": true, "message": "Call already ingested.", "data": { "id": "gQ7bYx", "status": "completed" } }

This is deliberate. Providers retry, and answering a retry with an error status makes them retry harder. A replay is a normal event, so it gets a normal response.

What makes a call the same call

A submission is recognized as a replay of an existing call — not a new one — if either of two independent checks matches, scoped to your organization:

  1. idempotency_key matches a call already on file.
  2. It didn't (or you didn't send one), and provider together with provider_call_id matches a call already on file.

Either match is enough on its own. That has a consequence worth knowing: if you regenerate idempotency_key between attempts but resend the same provider and provider_call_id, the second request is still recognized as the same call — the natural key catches what the new synthetic one missed.

The two checks are independent, not layered. Sending a fresh idempotency_key does not give you a new call if provider + provider_call_id still match a call you already submitted.

Practical consequences

  • Retry freely on network failures. If you did not get a response, resend the identical body. Either it was never received, or you get a 200 naming the call that already exists.
  • Use a key you can regenerate. Your own call identifier is usually the right value — if you need to resubmit after a crash, you can derive the same key again. A random UUID generated at send time cannot be.
  • Send provider and provider_call_id together if you have them, even alongside idempotency_key. They form a second, independent match on the same call.
  • data.status tells you where the call is. A replay of a call that has already finished returns its terminal status, not queued.

On this page