Getting startedEnd-to-end examples
Sales call intelligence
Transcribe a sales call with speaker labels and sentiment analysis, identify speakers by role, then use LLM Gateway to generate a coaching scorecard with talk/listen ratio and sentiment insights.
Products used: Pre-recorded STT + speaker diarization + Speaker Identification + sentiment analysis + LLM Gateway
Model selection: Uses universal-3-pro for the highest English accuracy. For multilingual sales teams, add universal-2 as a fallback.
Python
JavaScript
1 import requests 2 import time 3 from collections import Counter 4 5 # ── Config ──────────────────────────────────────────────────── 6 base_url = "https://api.assemblyai.com" 7 headers = {"authorization": "YOUR_API_KEY"} 8 9 audio_url = "https://assembly.ai/wildfires.mp3" 10 11 # ── Step 1: Transcribe with speaker labels + sentiment analysis ── 12 data = { 13 "audio_url": audio_url, 14 "speech_models": ["universal-3-pro"], 15 "speaker_labels": True, 16 "sentiment_analysis": True, 17 } 18 19 response = requests.post(base_url + "/v2/transcript", headers=headers, json=data) 20 response.raise_for_status() 21 transcript_id = response.json()["id"] 22 23 while True: 24 result = requests.get(f"{base_url}/v2/transcript/{transcript_id}", headers=headers).json() 25 if result["status"] == "completed": 26 break 27 elif result["status"] == "error": 28 raise RuntimeError(f"Transcription failed: {result['error']}") 29 time.sleep(3) 30 31 # ── Step 2: Identify speakers by role ── 32 understanding_response = requests.post( 33 "https://llm-gateway.assemblyai.com/v1/understanding", 34 headers=headers, 35 json={ 36 "transcript_id": transcript_id, 37 "speech_understanding": { 38 "request": { 39 "speaker_identification": { 40 "speaker_type": "role", 41 "known_values": ["Sales Rep", "Customer"], 42 } 43 } 44 }, 45 }, 46 ) 47 understanding_response.raise_for_status() 48 identified = understanding_response.json() 49 50 # ── Step 3: Calculate talk/listen ratio per speaker ── 51 speaker_durations = Counter() 52 for utterance in identified["utterances"]: 53 duration_ms = utterance["end"] - utterance["start"] 54 speaker_durations[utterance["speaker"]] += duration_ms 55 56 total_ms = sum(speaker_durations.values()) 57 talk_ratios = { 58 speaker: round(dur / total_ms * 100, 1) 59 for speaker, dur in speaker_durations.items() 60 } 61 62 # ── Step 4: Summarize sentiment shifts ── 63 sentiment_by_speaker = {} 64 for s in result["sentiment_analysis_results"]: 65 speaker = s.get("speaker", "Unknown") 66 sentiment_by_speaker.setdefault(speaker, []).append(s["sentiment"]) 67 68 sentiment_summary = "" 69 for speaker, sentiments in sentiment_by_speaker.items(): 70 counts = Counter(sentiments) 71 sentiment_summary += ( 72 f"{speaker}: " 73 f"{counts.get('POSITIVE', 0)} positive, " 74 f"{counts.get('NEUTRAL', 0)} neutral, " 75 f"{counts.get('NEGATIVE', 0)} negative\n" 76 ) 77 78 # ── Step 5: Format transcript and generate coaching scorecard ── 79 speaker_transcript = "\n".join( 80 f"{u['speaker']}: {u['text']}" for u in identified["utterances"] 81 ) 82 83 llm_response = requests.post( 84 "https://llm-gateway.assemblyai.com/v1/chat/completions", 85 headers=headers, 86 json={ 87 "model": "claude-sonnet-4-5-20250929", 88 "messages": [ 89 { 90 "role": "user", 91 "content": ( 92 "You are a sales coaching assistant. Analyze this sales call and produce a scorecard.\n\n" 93 f"Talk/listen ratios: {talk_ratios}\n\n" 94 f"Sentiment breakdown:\n{sentiment_summary}\n" 95 f"Transcript:\n{speaker_transcript}\n\n" 96 "Produce:\n" 97 "1. Call summary (2-3 sentences)\n" 98 "2. Talk/listen ratio analysis (ideal is 40/60 for the rep)\n" 99 "3. Customer sentiment shifts and what caused them\n" 100 "4. Top 3 coaching suggestions for the sales rep" 101 ), 102 } 103 ], 104 "max_tokens": 2000, 105 }, 106 ) 107 llm_response.raise_for_status() 108 109 print("=== Sales Call Scorecard ===\n") 110 print(llm_response.json()["choices"][0]["message"]["content"])
Example output
=== Sales Call Scorecard === ## Call summary This call discussed the environmental and health impacts of wildfire smoke on US communities. The speakers covered air quality data, health risks, and recommended precautions for the public. ## Talk/listen ratio Sales Rep: 65.3% | Customer: 34.7% Analysis: The ratio is inverted from the ideal 40/60 split. The rep dominated the conversation — focus on asking more open-ended questions. ## Customer sentiment shifts - Started neutral during introductions - Shifted negative when discussing health risks and poor air quality readings - Returned to neutral during the action-planning portion ## Coaching suggestions 1. Ask more discovery questions early to understand the customer's specific concerns 2. When the customer expresses concern, acknowledge before pivoting to solutions 3. Summarize key points at the end and confirm next steps with clear ownership
See the End-to-end examples overview for all available pipelines.