Skip to main content
Search saved call text without opening every call. The API and MCP return call record IDs and short verbatim excerpts. They include older Retell calls when their transcripts are stored locally. Search does not fetch recordings or missing provider transcripts.

Matching rules

A query node contains exactly one of word, phrase, all or any. all requires every child, across the call’s turns. any requires one child. A phrase requires adjacent words in one turn. It cannot cross speakers or primary and transfer text. Matching ignores case and preserves accents. Punctuation, apostrophes and hyphens separate words. AI matches ai; robot does not match robotic. cafe does not match café. This is literal evidence search. It does not classify intent, expand synonyms or accept regular expressions. Use speaker: "lead" when every matched word must come from a lead turn. The default any includes lead, agent, team and unknown turns. Unlabelled or ambiguous text stays unknown and cannot prove a lead-only hit.
A phrase hit needs review. It does not establish that someone questioned whether the caller was AI. Search counts matching calls, not unique leads. For a percentage, use the same tenant scope, date window, duration filter and observation basis for both numerator and denominator.

Request fields

Send POST /api/call-history/transcript-search with calls:read. In MCP, use search_call_transcripts with this JSON inside body. In search mode, run it through call_read_tool. JSON is limited to 32 KiB UTF-8, including after decompression. Unknown fields, blank leaves and excessive query complexity are rejected.

Response fields

The usual success and data envelope contains: A count’s status is available with value and kind, or unavailable with null value and kind and reason: stale_index_candidates when the page finds stale source access or filter data. An available kind is exact or lower_bound. The lower-bound threshold is 1,000; below it the count is exact. Exact refers to this indexed query. Aggregate rows are not all individually rechecked against the current source. Coverage uses unit: call_records, basis: indexed_projection, observedAt and total. transcriptStates, primaryStates and transferStates count missing, empty, present, invalid and oversized text. speakerCoverage counts known, partial, unknown and not_applicable attribution. Missing transfer text does not prove a transfer happened. Coverage is not a live source census. Oversized text is omitted whole, rather than reported as fully searched.

Boundaries and errors

  • Search is eventually consistent. Inserts, updates and deletes can change later pages. Pagination is not a snapshot.
  • A scope change, different user or credential, or index generation change invalidates the cursor. Restart the search.
  • Each page examines at most 200 candidates and reads at most 8 MiB of copied text in batches of ten. The total deadline is eight seconds; count and coverage each have a five-second cap inside it. Serialized data stays within 80,000 JavaScript string characters.
  • The feature stays unavailable until its operator enables and prepares it. A failure never becomes a successful zero result.

In the API