Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Block quote

Ordered list

  1. Item 1
  2. Item 2
  3. Item 3

Unordered list

Text link

Bold text

Emphasis

Superscript

Subscript

Pricing
Get started
Get started

Read more

Speech-To-Text

How decision intelligence improves customer service consistency in contact centers

TL;DR: Contact centers fail to deliver consistent service when routing infrastructure runs on static rules engines that cannot handle the complexity of real human conversation. Modern speech-to-text infrastructure addresses this by processing raw audio and feeding structured outputs to your CRM, using machine learning to analyze intent, sentiment, and speaker characteristics. Transcription accuracy sets the ceiling for every downstream action: a wrong word silently corrupts a CRM entry, a missed intent misfires a routing decision, and a misread sentiment score delays escalation. This playbook covers how to build and deploy that architecture without blowing your latency budget or your unit economics.

Speech-To-Text

Real-time speech analytics for live agent assist

TL;DR: Live agent assist only works when the transcription layer delivers partial results fast enough for downstream NLP to process within a sub-second window. If the pipeline exceeds 1,000ms total, prompts arrive after agents have already spoken, which inflates Average Handle Time and erodes agent trust. This playbook covers the full real-time pipeline architecture, from streaming transcription through intent analysis to agent desktop rendering, and shows how contact centers can expand QA coverage from a 1-3% manual sample to 100% of interactions without adding headcount.

Speech-To-Text

How to identify prospect companies from sales call transcripts

TL;DR: Most product teams try to run LLM extraction on raw, undiarized transcripts and end up with CRM records polluted by the sales rep's own company names, tools, and competitor mentions. The fix is an async-first pipeline that separates speaker dialogue before any entity extraction happens. This guide walks through a working Python and Claude API pipeline using our async transcription, pyannoteAI Precision-2 diarization, and Solaria-3 or Solaria-1 depending on your language mix, so you extract clean prospect-side signals and sync accurate data to your CRM.

How to identify prospect companies from sales call transcripts

Published on July 17, 2026
by Ani Ghazaryan
How to identify prospect companies from sales call transcripts

TL;DR: Most product teams try to run LLM extraction on raw, undiarized transcripts and end up with CRM records polluted by the sales rep's own company names, tools, and competitor mentions. The fix is an async-first pipeline that separates speaker dialogue before any entity extraction happens. This guide walks through a working Python and Claude API pipeline using our async transcription, pyannoteAI Precision-2 diarization, and Solaria-3 or Solaria-1 depending on your language mix, so you extract clean prospect-side signals and sync accurate data to your CRM.

Building a pipeline to extract prospect insights from sales calls sounds straightforward until your downstream LLM starts tagging your own sales reps' tools and employer as the buyer's profile. The culprit is almost always the same: undiarized or poorly diarized transcripts fed directly into an extraction prompt. Without speaker attribution, the LLM has no way to distinguish who said what, and every competitor name the rep drops to anchor their pitch gets extracted as a prospect signal. This guide shows you exactly how to build that pipeline using our async API with speaker diarization powered by pyannoteAI Precision-2, the Claude API for structured entity extraction, and enrichment APIs to sync clean data into your CRM.

Why diarization unlocks prospect extraction

Speaker diarization is the process of partitioning an audio recording into segments grouped by individual speaker identity. In a sales call, this means the transcript comes back with every utterance labeled (speaker_0 or speaker_1) with timestamps and word-level confidence scores attached to each segment.

Diarization is async-only in our pipeline, and that's intentional. Because the model processes the full audio context before generating output, it builds speaker embeddings across the entire conversation rather than making real-time guesses with limited context. This approach delivers significantly improved diarization accuracy. For post-call prospect extraction, that accuracy gap compounds directly into CRM data quality.

Fixing speaker overlap for cleaner data

Sales calls frequently feature interruptions, back-channels, and cross-talk, especially when a prospect is engaged and probing the rep.

The practical output is a timeline of labeled segments: 0:00-0:05 speaker_0, 0:05-0:07 speaker_1, 0:07-0:10 speaker_0. When a prospect interrupts a rep mid-sentence, the system splits the utterance at the transition rather than merging both speakers' text into a single block. Merged blocks are where your entity extraction fails, because the LLM cannot tell where one speaker ends and another begins.

Mapping speakers to prospect insights

Once you have a diarized transcript, the next step is mapping speaker IDs to roles. The goal is to identify which speaker ID belongs to the sales rep and which belongs to the prospect, so you can filter out the rep's dialogue before passing text to the LLM.

A common approach is to scan the opening segment of the call. The rep typically speaks first, introduces themselves by name and company, and uses internal product names or pricing language early in the exchange. You can match these signals against a known keyword list to assign rep_speaker_id. If no speaker uses known company keywords in the opening segment, consider flagging the call for manual review rather than defaulting to a guess.

How rep filler distorts prospect data

Sales reps talk a lot about themselves during calls. They name competitors to anchor positioning ("unlike Competitor X, we handle Y"), reference internal product SKUs, and describe their company's tech stack. If this text is not isolated by speaker ID before LLM extraction, the model extracts all of it as prospect data.

A rep saying "We outperform Salesforce in this workflow" produces competitor: Salesforce in the prospect's CRM record. A rep saying "We're built on AWS" produces current_tools: AWS as a buyer signal. The LLM is not doing anything wrong: it's following the prompt. The problem is the input data, and filtering the rep's speaker_id out before the extraction prompt runs is the fix.

Extracting actionable prospect signals from audio

A clean, diarized transcript filtered to prospect-only utterances gives you the raw material for structured extraction. The signals worth targeting fall into four categories.

Parsing company mentions from audio

Prospects mention their employer, parent company, subsidiaries, and key vendors within the first few minutes of a discovery call. Our named entity recognition layer extracts these company mentions directly from the transcript, returning structured JSON that maps entity type to string value, which you can pass to Claude for normalization before writing to CRM fields. Validate extraction output against a manually annotated sample of your own calls before relying on it in a production CRM pipeline.

For teams dealing with complex corporate structures, custom vocabulary allows you to inject known subsidiary names, holding company variants, and industry-specific brand names into the model before transcription runs. This biases the Automatic Speech Recognition (ASR) system toward correct spelling and capitalization of terms like "BNP Paribas" or "3M" rather than phonetically approximate variants.

Mapping the competitive landscape

Accurately extracting key data from call recordings (competitors, tools, pain points) requires a transcript where the prospect's utterances are cleanly separated from the rep's.

Recommended tech stack for pipeline

The architecture that produces reliable results at scale has four layers:

  1. Audio capture: Our API handles native meeting recording, eliminating a separate capture provider.
  2. Async transcription and diarization: POST to our async transcription endpoint at /v2/pre-recorded with diarization enabled, returning speaker-labeled utterances via the Audio-to-LLM pipeline.
  3. LLM extraction: Claude API (using the anthropic Python SDK) running a structured extraction prompt against prospect-only utterances.
  4. CRM enrichment: An enrichment API for account normalization, then a write to HubSpot or Salesforce via their REST APIs.

Each layer feeds the next without lossy transformations. Diarization must happen in the async transcription step, not as a post-processing afterthought on an already-merged transcript.

Detecting revenue signals in audio

Beyond named entities, prospect utterances contain budget signals, timeline language, and hesitation markers. Phrases like "we were hoping to have this live before Q4" or "we've already allocated budget for this" carry deal velocity information that your LLM extraction prompt can surface. Equally useful is what prospects avoid: a prospect who deflects pricing questions is signaling a different deal stage than one who asks about enterprise contract terms in the first call.

Solving data quality issues at scale

When you scale a prospect extraction pipeline from 10 calls per day to 1,000, you surface failure modes that single-call testing never reveals. The four most common ones follow.

Rep self-mentions counted as buyer signals

The most frequent failure is misattributing the rep's dialogue to the prospect when the speaker_id assignment logic breaks down. This happens when the call starts with hold music or an automated recording prompt, which disrupts the opening-segment heuristic used to identify the rep. Build a fallback that flags ambiguous calls for manual review rather than defaulting to a guess, because corrupted CRM data is harder to remediate than a small manual review queue.

Fixing entity loss during code-switching

Global sales teams frequently switch languages mid-call. Standard ASR models handle this poorly. They either lock to one language and garble the other, or they return fragmented output with dropped entities at the switch point.

Our Solaria-1 model detects and transcribes mid-conversation language changes automatically across 100+ supported languages without requiring you to pre-specify switch points.

Normalizing corporate name variations

Prospects rarely use the legally precise name of their own company or their vendors. "Google" and "Alphabet", "Coke" and "Coca-Cola", "Meta" and "Facebook" all refer to the same entities but produce duplicate or unmatched CRM records if treated as separate strings. The normalization step belongs after LLM extraction and before CRM write: build a Python dictionary mapping known variants to canonical names, then fall back to fuzzy matching with rapidfuzz for uncovered variants.

Fixing non-English entity extraction

Entity extraction accuracy degrades when the underlying transcript has a high word error rate, and word error rate climbs when the ASR model is not optimized for the language and audio conditions of your calls. For European business audio across English, French, German, Spanish, and Italian, Solaria-3 is the model to use. Its performance on real-world business audio, including noisy calls and accented speech, directly reduces the entity loss that stems from transcription errors.

Syncing audio transcripts to CRM prospect data

The following Python walkthrough takes a raw audio file through the full pipeline: upload to our async API, isolate prospect dialogue, extract structured entities with Claude, and prepare the CRM payload.

Step 1: Upload audio to Gladia async API

POST the audio file to /v2/pre-recorded with diarization enabled and poll for results.

import requests
import time

GLADIA_API_KEY = "your_gladia_api_key"
AUDIO_URL = "https://example-bucket.s3.amazonaws.com/sales-call.mp3"

headers = {
    "x-gladia-key": GLADIA_API_KEY,
    "Content-Type": "application/json"
}

payload = {
    "audio_url": AUDIO_URL,
    "diarization": True,
    "diarization_config": {
        "min_speakers": 2,
        "max_speakers": 3
    },
    "named_entity_recognition": True,
    "custom_vocabulary": True,
    "custom_vocabulary_config": {
        "vocabulary": ["Salesforce", "HubSpot", "your-company-name"]
    }
}

response = requests.post(
    "https://api.gladia.io/v2/pre-recorded",
    headers=headers,
    json=payload
)

result = response.json()
transcription_id = result["id"]
result_url = result["result_url"]

# Poll for completion
while True:
    poll_response = requests.get(result_url, headers=headers)
    poll_data = poll_response.json()
    if poll_data["status"] == "done":
        transcript_data = poll_data
        break
    time.sleep(5)

Setting custom_vocabulary to true and passing your terms in custom_vocabulary_config.vocabulary improves recognition accuracy for known company names and product brands by boosting their probability during transcription, reducing phonetic variants that break downstream entity matching.

Step 2: Isolate dialogue by speaker ID

Parse the JSON response to group all utterances by speaker_id. Each utterance object contains the speaker label, start and end timestamps, and transcript text.

from collections import defaultdict

utterances_by_speaker = defaultdict(list)

for utterance in transcript_data["result"]["transcription"]["utterances"]:
    speaker_id = utterance["speaker"]
    utterances_by_speaker[speaker_id].append({
        "start": utterance["start"],
        "end": utterance["end"],
        "text": utterance["text"]
    })

Step 3: Isolating relevant prospect text

Scan the opening segment of the call for known company keywords to identify the rep's speaker_id, then filter that speaker out.

INTERNAL_KEYWORDS = ["our product", "your-company-name", "our pricing", "our platform"]

def identify_rep_speaker(utterances_by_speaker, keywords, time_limit=120):
    """
    Scan the opening segment to identify the rep's speaker_id.
    time_limit is in seconds and should be adjusted based on your call patterns.
    """
    for speaker_id, utterances in utterances_by_speaker.items():
        early_text = " ".join(
            u["text"] for u in utterances if u["start"] < time_limit
        ).lower()
        if any(kw.lower() in early_text for kw in keywords):
            return speaker_id
    return None

rep_speaker_id = identify_rep_speaker(utterances_by_speaker, INTERNAL_KEYWORDS)

prospect_text = " ".join(
    u["text"]
    for speaker_id, utterances in utterances_by_speaker.items()
    if speaker_id != rep_speaker_id
    for u in utterances
)

Step 4: Entity recognition with Claude API

Pass the prospect-only text to Claude with a structured extraction prompt. The system prompt explicitly constrains extraction to the input text, preventing hallucination of entities not present in the transcript.

# Install required library: pip install anthropic
import anthropic

client = anthropic.Anthropic(api_key="your_anthropic_api_key")

system_prompt = """You are a sales intelligence extraction system.
Extract the following entities from the prospect's speech only.
Return a valid JSON object with these fields:
- company_name: the prospect's employer (string or null)
- competitors: list of competitor products or companies mentioned (list of strings)
- current_tools: tools, platforms, or vendors the prospect currently uses (list of strings)
- pain_points: specific problems or frustrations the prospect describes (list of strings)

Extract only from the provided text. Do not infer or add entities not explicitly mentioned."""

message = client.messages.create(
    model="claude-3-opus-20240229",
    max_tokens=1024,
    system=system_prompt,
    messages=[
        {"role": "user", "content": f"Extract entities from this prospect transcript:\n\n{prospect_text}"}
    ]
)

import json
extracted_entities = json.loads(message.content[0].text)

Step 5: Resolve duplicate company mentions

Before writing to CRM, deduplicate and normalize the extracted entities using a corporate name mapping dictionary with fuzzy matching fallback.

# Install required library: pip install rapidfuzz
from rapidfuzz import process, fuzz

CANONICAL_NAMES = {
    "google": "Alphabet",
    "alphabet": "Alphabet",
    "meta": "Meta Platforms",
    "facebook": "Meta Platforms",
    "coke": "Coca-Cola",
    "coca cola": "Coca-Cola"
}

def normalize_company_name(name, canonical_map, threshold=80):
    """
    Normalize company name using fuzzy matching.
    threshold: similarity score (0-100) above which a match is accepted.
    Adjust based on your data quality needs.
    """
    name_lower = name.lower().strip()
    if name_lower in canonical_map:
        return canonical_map[name_lower]
    best_match, score, _ = process.extractOne(
        name_lower, canonical_map.keys(), scorer=fuzz.token_sort_ratio
    )
    if score >= threshold:
        return canonical_map[best_match]
    return name

if extracted_entities.get("company_name"):
    extracted_entities["company_name"] = normalize_company_name(
        extracted_entities["company_name"], CANONICAL_NAMES
    )

Once local normalization is applied, pass the resolved name to a company enrichment API to retrieve a canonical domain and account record, which you then match against existing CRM accounts before writing. This prevents the most common CRM hygiene failure: a single prospect company fragmenting into three records under slightly different name strings.

Mapping transcripts to CRM fields

Structure your CRM schema before your first extraction run, and map each entity category to a field type that supports your call center voice analytics workflow.

Entity type Common CRM field approach Notes
Company name Text or lookup field Link to Account object after enrichment API match
Competitors Multi-select or text field Consider maintaining a controlled list
Current tools Multi-select or text field Same controlled vocabulary approach
Pain points Long text area Store verbatim quote alongside label
Call date Date Auto-populate from audio metadata

Pain points belong in a long-text field that sales reps can read before their next call. Competitor mentions map to a multi-select field that feeds your competitive win/loss reporting. Tool mentions populate a "current tech stack" property that informs integration prioritization.

Standardizing global pipeline data via diarization

For sales teams operating across multiple regions, the pipeline must handle linguistic variation that a single-language model cannot cover reliably.

Code-switching in enterprise sales calls

Enterprise sales calls frequently feature mid-sentence language switches, whether between English and French in a European deal or English and Tagalog in a Southeast Asian BPO context. When standard ASR models encounter these transitions, they either lock to one language and return garbled output for the other, or they drop the switched segment entirely, creating a gap in the transcript exactly where entity extraction breaks.

Solaria-1's native code-switching support processes these transitions in a single pass without requiring you to pre-specify switch boundaries, preserving company names and entity mentions that would otherwise be lost — a failure mode that shows up consistently in multilingual customer support and enterprise sales pipelines alike.

Accuracy benchmarks for European languages

For sales teams covering European markets, model selection matters. On real-world business audio, Solaria-3 reaches 6.4% WER on Earnings22 financial calls (the only model under 7% in that dataset) and 33.9% WER on Switchboard conversational speech (the only model under 35%), accuracy gaps that translate directly into fewer missed entity extractions per call.

Transcribing noisy contact center calls

Sales calls routed through VoIP infrastructure and recorded on headsets in open offices carry background noise, compression artifacts, and variable audio quality. These are the conditions where transcription accuracy degrades most sharply on models trained primarily on clean audio. Solaria-3's optimization for noisy conversational speech means company names and entity mentions that would be garbled or dropped on lower-accuracy models come through accurately.

Validating your extraction logic with sample audio

Testing pipeline accuracy on sample audio

Run your POC with this methodology:

  1. Select 5-10 representative sales calls covering the audio conditions you expect in production (different rep accents, varying background noise, and calls with multilingual moments if relevant), then POST each file to /v2/pre-recorded with diarization and Named Entity Recognition (NER) enabled.
  2. Run your speaker ID assignment logic and manually verify it correctly identifies the rep's speaker_id against the original recording, then pass the filtered prospect text through your Claude extraction prompt.
  3. Compare extracted entities against a manually annotated ground truth for each call, tracking which failure modes (rep misattribution, code-switching gaps, corporate name variants) appear most frequently, since the distribution will tell you where to focus engineering effort first.

API pricing for this pipeline

Audio intelligence features (diarization, NER, translation, and summarization) are included in the base rate on Starter and Growth plans, with no add-on fees per feature. For this async pipeline, that means $0.61/hr on Starter or as low as $0.20/hr on Growth, covering the full feature set at both tiers.

Measuring WER for low quality call audio

To validate transcription quality on your own audio, calculate word error rate by transcribing a sample of calls, manually correcting a reference transcript for each, and measuring insertions, deletions, and substitutions against the reference. Segment this by language and audio condition: a model with acceptable WER on clean English audio may perform substantially worse on French calls recorded through a browser. Your extraction accuracy tracks directly with your transcription accuracy, so this measurement tells you where your pipeline's ceiling is.

Estimated setup time for API pipeline

Most product teams complete their integration and deploy to production in under 24 hours using our lightweight Python and JavaScript SDKs.

Model training and data retention rules

On Growth and Enterprise plans, customer audio and transcripts are never used for model training. No opt-out action is required. On the Starter plan, customer data can be used for model training by default. Our compliance hub covers our security and privacy certifications in detail. On Enterprise plans, zero data retention is available: audio is processed in memory and never written to storage, so no deletion step is required. If your sales calls contain personally identifiable information, PII redaction is available as an optional feature that must be explicitly enabled in your API request.

Capturing intent from call transcripts

The most underused output of a well-functioning prospect extraction pipeline is its signal for product strategy. When you aggregate competitor mentions across hundreds of calls, you see which vendors your prospects evaluate most frequently against you. When you aggregate pain points, the recurring themes map directly to feature gaps and integration requests.

Teams that close this loop between sales intelligence and roadmap prioritization gain a durable advantage: their product decisions are grounded in what buyers are actually saying, not what internal stakeholders assume they're saying. Accurate extraction starts with accurate transcription, which starts with precise speaker diarization. Get started with Gladia and have your integration in production in less than a day.

FAQs

Is speaker diarization available in real-time workflows?

No, diarization is only available in async workflows. Async processing allows the model to analyze the full audio context before generating output, which improves speaker identification accuracy. For real-time workflows, speaker attribution must be handled in post-processing.

Does Gladia use my sales call audio to train its models?

On Growth and Enterprise plans, customer audio and transcripts are never used for model training. No opt-out action is required. On the Starter plan, customer data can be used for model training by default.

What is the cost of transcribing 1,000 hours of sales calls?

At Starter plan rates, 1,000 hours of async transcription costs approximately $610 ($0.61/hr). On Growth, the rate drops to as low as $0.20/hr, bringing the same volume to approximately $200. Enterprise pricing is custom and typically negotiated on annual volume.

How long does it take to integrate the Gladia API into a production pipeline?

Most product teams complete their integration and deploy to production in less than 24 hours using our lightweight Python and JavaScript SDKs.

Key terms glossary

Word Error Rate (WER): The standard metric for measuring speech recognition accuracy, expressed as the ratio of errors (insertions, deletions, and substitutions) to the total number of words in the reference transcript (lower is better).

Diarization Error Rate (DER): The metric used to evaluate speaker diarization performance, calculated as the fraction of time that is not attributed correctly to a speaker or to non-speech. DER includes three error types: missed speech, false alarm speech, and speaker confusion (attributing speech to the wrong speaker).

Speaker diarization: The process of partitioning an audio recording into segments grouped by individual speaker identity, returning labeled utterances with timestamps rather than a single merged transcript.

Code-switching: The practice of alternating between two or more languages or dialects within a single conversation or utterance, common in multilingual sales calls and BPO environments.

Contact us

280
Your request has been registered
A problem occurred while submitting the form.

Read more