Conversations API

List, search and read analysed calls with a workspace API key: paging, filters, the summary shape and the full analysis object with faults, latency, slots, sentiment and transcript.

Conversations are analysed calls. With a workspace API key you can list them, search their transcripts and read the complete analysis of any one of them. All endpoints are GET, scoped to the key's workspace, and rate-limited to 600 requests per minute per key.

GET /api/conversations?take=50&status=Completed HTTP/1.1
Host: voicelens.app
X-Api-Key: vlk_9d1e…

List conversations

GET/api/conversations

Cursor-paged list of conversations, newest first unless sorted otherwise.

Query parameterDefaultMeaning
take50Page size, 1 to 200.
cursorOpaque cursor from the previous page's nextCursor. Only valid with the same sort.
sortcreatedAtColumn to order by: createdAt, title, channel, status, health, faults, slots, line, latency or duration.
dirasc or desc. Defaults to asc for title, channel and status, desc otherwise.
channelIdOnly calls from this channel.
agentIdOnly calls with exactly this agentId.
statusComma-separated list of PendingUpload, Pending, Transcribing, Analyzing, Completed, Failed, Skipped.
qFree-text filter on title and source name.
unreviewedtrue to return only completed calls nobody has marked as reviewed.
includeTestCallsfalseInclude calls flagged as test calls.

Metric sorts (health through duration) only apply to completed calls: calls still processing, failed or skipped have no metrics and are always returned after the completed ones, whichever direction you ask for. faults orders by severity (danger count, then warning, then info), and line puts calls whose line quality was not measured last as well. Ties are broken by id, so paging through a sorted list visits every call exactly once.

Date ranges and health filters are not available on the list; use the analytics endpoints for aggregates over time, or filter client-side on createdAtUtc and healthScore.

Response

{
  "items": [ { "…": "ConversationSummary" } ],
  "totalCount": 1284,
  "countsByStatus": { "Completed": 1201, "Failed": 3, "Skipped": 80 },
  "nextCursor": "eyJj…",
  "take": 50
}

Conversation summary

FieldTypeMeaning
iduuidConversation id.
title, sourceNamestringTitle and original file or source name.
status, processingErrorstringProcessing status and, when failed, the reason.
channelId, channelNameThe channel the call belongs to.
agentId, agentName, agentTypeAgent identity from the ingest metadata.
createdAtUtc, reviewedAtUtcISO 8601Receipt time and, if reviewed, when.
durationSec, turnCountnumberLength and number of transcript turns.
healthScore0 to 100See Health score.
totalFaults, dangerFaultCount, warningFaultCount, infoFaultCountnumberOpen fault counts by severity.
completionRate0 to 1Share of required slots captured.
agentLatencyMeansecondsMean agent response latency.
silenceRatio0 to 1Share of the call with nobody speaking.
lineQualityScore, snrDbnumberAcoustic line quality (0 to 100) and signal-to-noise ratio.
modelNamestringTranscription model used.
isTestCall, testCallRunIdSet for calls placed by the test-call feature.

Search transcripts

GET/api/conversations/search

Phrase search across transcript turns, returning matching calls newest first with the turns that matched. Cursor-paged.

Query parameterDefaultMeaning
qrequired2 to 200 characters, matched literally and case-insensitively inside a single turn.
speakeranyany, agent or customer: restrict matches to one side.
channelId, agentIdFilters as on the list.
from, toISO 8601 bounds on the call's receipt time; from inclusive, to exclusive.
cursorOpaque cursor from the previous page's nextCursor; omit for the newest matches.
take20Page size, 1 to 50.
includeTestCallsfalse

The page carries no grand totals: the server stops looking as soon as the page is full, which is what keeps the first results fast on large workspaces. nextCursor is null on the last page. For the totals, call the endpoint below.

{
  "query": "cancel my contract",
  "speaker": "customer",
  "take": 20,
  "nextCursor": "MjAyNi0wOS0x…",
  "items": [
    {
      "conversation": { "…": "ConversationSummary" },
      "matchCount": 2,
      "turns": [
        { "turnIndex": 14, "speakerLabel": "customer", "start": 182.4, "end": 186.9, "snippet": "…I want to cancel my contract today…", "sentiment": -0.42 }
      ]
    }
  ]
}
GET/api/conversations/search/totals

How many calls and turns match a search across every page.

Takes the same q, speaker, channelId, agentId, from, to and includeTestCalls as the search; cursor and take are ignored. This is the one request that has to read every searched call's transcript, so ask for it after the first page rather than before.

{ "query": "cancel my contract", "speaker": "customer", "totalCalls": 37, "totalTurns": 41 }

Read one conversation

GET/api/conversations/{id}

The complete analysis. Large; fetch it per call rather than in bulk.

The object is organised in groups. Field names are camelCase.

Identity and metadata

id, workspaceId, channelId, status, processingError, skipReason, processingAttempts, source, sourceName, title, externalCallId, agentId, agentName, agentType, customMetadata (your custom object), language, isTestCall, createdAtUtc, and audio { container, blobName, contentType, sizeBytes, durationSec }.

Transcription metadata

metadata { requestId, duration, channels, modelName, createdUtc, rawConfidence, speakerAttribution } plus agentSpeaker and customerSpeaker (which speaker label was identified as which party). speakerAttribution is multichannel or diarized.

speakerRoleSource says how agentSpeaker was decided: firstSpeaker (the parser's default, whoever spoke first, unverified), modelConfirmed or modelCorrected (the AI read the opening turns and agreed with, or overturned, that guess) or manual (an operator swapped the roles in the dashboard). speakerRoleNote carries the model's one-sentence reason when the source is a model decision, otherwise null. Outbound calls are the usual case for modelCorrected: the customer picks up and says "hello" before the agent introduces itself.

Talk time, latency and confidence

  • talkTime: seconds and share of the call per party, and silence.
  • latency.agentResponse and latency.customerResponse: { mean, median, p95, max, count } over the response gaps; latency.perAgentTurn: the gap before each agent turn. See Latency.
  • confidence { averageWordConfidence, averageSpeakerConfidence, lowConfidenceWordCount, lowConfidenceWords[], lowSpeakerConfidenceCount }.

Capture, coverage and compliance

  • completion and coverage: the two rates with their numerators and denominators.
  • slots[]: { key, label, category, type, required, status, value, valueHistory[], volunteered, corrected, turnIndex } with status one of Captured, Corrected, Missing, NotApplicable.
  • questions[]: { key, label, required, asked, turnIndex }.
  • compliance and compliancePhrases[]: verdict per required or forbidden phrase.
  • resolvedCasePath, resolvedCaseLabel: the case branch the call was graded under.

Faults

{
  "code": "MISSED_CORRECTION",
  "label": "Missed correction",
  "description": "Customer corrected the appointment day; the agent did not acknowledge it.",
  "severity": "warning",
  "atSec": 143.2,
  "endSec": 151.8,
  "turnIndices": [11, 12],
  "evidence": [
    { "turnIndex": 11, "atSec": 143.2, "text": "No, Thursday, not Tuesday." },
    { "turnIndex": 12, "atSec": 147.0, "text": "Great, so Tuesday at ten." }
  ],
  "id": "…",
  "verdict": null
}

severity is danger, warning or info; verdict is null, confirmed or falsePositive once a reviewer has acted. Counts by severity and the healthScore sit alongside the array. See Fault codes.

Sentiment

sentiment { customerAverage, agentAverage, trajectory[], … } for English calls; absent otherwise. See Sentiment.

Transcript

turns[]: { index, speaker, speakerLabel, start, end, text, numWords, avgWordConfidence, avgSpeakerConfidence, sentiment }, and gaps[] with the silences between turns.

Line quality

lineQuality { version, score, snrDb, perChannel[], events[], … }. See Transcription quality.

Other

callSummary (generated summary, when enabled), the review state, the rubric template version stamp (evaluationTemplateVersionId), and capability flags canReevaluate, canRetranscribe, canSummarize.

Audio

Audio bytes are not available through API keys. Use a share link with audio enabled, or download from the dashboard.

Errors

401 for a missing or invalid key, 403 with code: "api_key_read_only" for any non-GET method, 404 for an id outside the key's workspace, 429 when the per-key rate limit is exceeded.