Your sales team makes 50 calls a day. Each call is 8–15 minutes of negotiation, objection handling, and valuable customer insight. At the end of the day, your CRM has entries like:
"Called John. Interested. Follow up next week."
That's it. The actual conversation — the customer's pain points, the objections they raised, the specific numbers they mentioned — is gone. Lost to memory decay and rushed note-taking.
This isn't a laziness problem. It's a physics problem. You can't be fully present in a conversation and take detailed notes at the same time.
What We're Building
A post-call intelligence pipeline that:
- Captures every inbound/outbound call through VoIPBin
- Fires a webhook when the call ends (with the recording URL)
- Transcribes the audio using OpenAI Whisper
- Extracts structured data with GPT-4o: summary, sentiment, action items, deal signals
- Pushes a clean, structured record to your CRM or Notion
The output looks like this:
{
"caller": "+1-555-0123",
"duration": 847,
"summary": "John from Acme Corp wants to expand their license from 50 to 200 seats. Main blocker is Q3 budget freeze. He asked for a written proposal by Friday and mentioned a competitor (Twilio) is also in evaluation.",
"sentiment": "positive",
"action_items": [
"Send written proposal by Friday",
"Include volume discount for 200-seat tier",
"Schedule follow-up for Q4 budget cycle"
],
"next_follow_up": "2026-05-01",
"deal_signals": {
"competitor_mentioned": "Twilio",
"deal_size": "200 seats",
"blocker": "Q3 budget freeze"
}
}
No manual notes. No forgotten details. Every call, automatically.
Setting Up VoIPBin
Sign up and get your API token in one request:
curl -X POST https://api.voipbin.net/v1.0/auth/signup \
-H "Content-Type: application/json" \
-d '{
"username": "yourname",
"password": "securepassword",
"email": "you@company.com"
}'
You'll immediately receive an accesskey.token. No email verification, no OTP.
Next, configure a webhook that fires when a call recording is ready:
curl -X POST https://api.voipbin.net/v1.0/webhooks \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/call-ended",
"events": ["call.recording.completed"]
}'
The Post-Call Pipeline
Here's the complete Python implementation:
import os
import json
import httpx
import openai
from fastapi import FastAPI, Request
from datetime import datetime
app = FastAPI()
client = openai.OpenAI(api_key=os.environ["OPENAI_API_KEY"])
VOIPBIN_TOKEN = os.environ["VOIPBIN_TOKEN"]
@app.post("/webhooks/call-ended")
async def handle_call_ended(request: Request):
payload = await request.json()
recording_url = payload["recording_url"]
caller_number = payload.get("caller", "unknown")
duration = payload.get("duration_seconds", 0)
call_id = payload["call_id"]
# Step 1: Download the recording
async with httpx.AsyncClient() as http_client:
response = await http_client.get(
recording_url,
headers={"Authorization": f"Bearer {VOIPBIN_TOKEN}"}
)
audio_bytes = response.content
audio_path = f"/tmp/{call_id}.mp3"
with open(audio_path, "wb") as f:
f.write(audio_bytes)
# Step 2: Transcribe with Whisper
with open(audio_path, "rb") as audio_file:
transcription = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
response_format="text"
)
# Step 3: Extract structured intelligence with GPT-4o
intelligence = await extract_call_intelligence(
transcription, caller_number, duration
)
# Step 4: Push to CRM
await push_to_crm(intelligence)
return {"status": "processed", "call_id": call_id}
async def extract_call_intelligence(
transcript: str,
caller: str,
duration: int
) -> dict:
prompt = f"""Analyze this sales call transcript and extract structured data.
Caller: {caller}
Duration: {duration} seconds
Transcript:
{transcript}
Return a JSON object with these fields:
- summary: 2-3 sentence summary of the conversation
- sentiment: positive, neutral, or negative
- action_items: list of specific next steps mentioned
- next_follow_up: suggested follow-up date (YYYY-MM-DD) if mentioned, else null
- deal_signals: object with any of: competitor_mentioned, deal_size, budget, timeline, blocker
- topics: list of main topics discussed
Return only valid JSON, no markdown."""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"}
)
data = json.loads(response.choices[0].message.content)
data["caller"] = caller
data["duration"] = duration
data["processed_at"] = datetime.utcnow().isoformat()
return data
async def push_to_crm(intelligence: dict):
notion_token = os.environ.get("NOTION_TOKEN")
notion_db_id = os.environ.get("NOTION_DB_ID")
if not notion_token:
print(json.dumps(intelligence, indent=2))
return
async with httpx.AsyncClient() as http_client:
await http_client.post(
"https://api.notion.com/v1/pages",
headers={
"Authorization": f"Bearer {notion_token}",
"Notion-Version": "2022-06-28",
"Content-Type": "application/json"
},
json={
"parent": {"database_id": notion_db_id},
"properties": {
"Caller": {
"title": [{"text": {"content": intelligence["caller"]}}]
},
"Summary": {
"rich_text": [{"text": {"content": intelligence["summary"]}}]
},
"Sentiment": {
"select": {"name": intelligence["sentiment"]}
}
}
}
)
Running the Server
pip install fastapi uvicorn httpx openai
export VOIPBIN_TOKEN=your_token_here
export OPENAI_API_KEY=your_openai_key
uvicorn main:app --host 0.0.0.0 --port 8080
For local development, expose it with ngrok:
ngrok http 8080
# Copy the HTTPS URL and set it as your VoIPBin webhook
What You Actually Get
Every call automatically produces structured data your team can act on.
For sales teams: Full conversation context in the CRM before the follow-up call. Your rep knows the competitor was mentioned, the deal size, the budget cycle — without bullet-point notes.
For support teams: Every resolution is documented. If a customer calls back, the previous issue is already in context.
For founders: Aggregate call data across all reps. Which objections come up most? Which topics are trending? Which deals stall at the same stage? You have the data now.
The Pattern, Not Just the Feature
This webhook-to-intelligence pipeline generalizes well:
- Candidate interviews: Extract skills mentioned, red flags, questions asked
- Partner calls: Track commitments made, follow-ups promised, relationship health
- Board calls: Auto-generate meeting minutes and decision logs
- Support escalations: Document resolution steps for future agent training data
VoIPBin handles the telephony layer — recording, storage, delivery via webhook — so your code is pure business logic. The ~80 lines above are doing the actual work; the infrastructure is invisible.
The insight has always been in those calls. Now you can actually capture it.
Try it: Sign up at voipbin.net — API token in 30 seconds, no credit card required for the trial.
Top comments (0)