Call Lens
Ingesting calls

Submitting a call

POST /calls, field by field.

POST /calls accepts a call for processing and returns immediately. Transcription and analysis happen asynchronously; the result reaches you as a call.completed webhook.

Audio reaches Call Lens through an upload: request one, send the bytes, and present the ticket here.

{
  "mode": "upload",
  "upload_ticket": "eyJpdiI6…",
  "started_at": "2026-08-05T09:14:00Z",
  "provider": "zoom",
  "provider_call_id": "CA123",
  "idempotency_key": "CA123"
}

Required fields

FieldNotes
modeAlways upload.
upload_ticketThe ticket from POST /uploads, verbatim.
started_atWhen the call started.

provider_call_id (max 255 characters) and idempotency_key (max 255 characters) are also required if your key has webhooks enabled — see correlation identifiers.

Optional fields

FieldNotes
ended_atMust not be before started_at.
duration_msMinimum 1. Call Lens measures duration itself and prefers its own observation.
providerThe system the call came from. Max 64 characters.
identity_keyYour identifier for the agent, used to resolve them to an employee. Max 255 characters.
employee_idThe Call Lens employee, if you already know it.
channel_layoutmono_mixed, dual_agent_customer, or multi. dual_agent_customer asks us to attribute speech by channel, which only some speech-to-text providers can do — if yours cannot, the call is refused with a 422 naming the provider rather than accepted and left unprocessed. Submit without this field, or as mono_mixed, to be transcribed with speaker diarization instead.
directioninbound, outbound, or unknown.
counterparty_e164The other party's number. Max 32 characters.
prioritylive or backfill. Use backfill for historical imports so they yield to live traffic.
provider_metadataAny JSON object. Stored on the call as submitted. Not returned to you anywhere today — not in this response, not on call.completed.

Responses

{ "success": true, "message": "Call accepted.", "data": { "id": "gQ7bYx", "status": "queued" } }

201 on a new call, 200 on a replay. See idempotency.

The id is an opaque string. Call Lens never exposes internal numeric identifiers.

status is queued when the call is on its way through the pipeline, or identity_unresolved when Call Lens could not match identity_key to an employee. The second is not a failure and the audio is not discarded — the call waits in a queue an administrator can resolve, and enters the pipeline once it is attributed.

Refusals specific to the upload are listed under uploading audio.

Modes that no longer exist

Earlier versions of this API documented mode: "pull", which took a source_url, and mode: "push", which took an audio_key. Both now return 422.

Neither could produce a transcribable call. Nothing ever fetched a source_url — the URL was validated and discarded, so the call was created with no audio and failed as soon as the pipeline reached it, having already consumed part of your ingestion allowance. push required write access to Call Lens storage, which is not something an API key has ever granted.

If you built against either, switch to uploading audio. Nothing that worked before has stopped working.

On this page