Call Logs
Every interaction captured — full transcripts with speaker turns, timestamps, audio playback, and every tool call traced
Every Interaction, Fully Captured
Call logs (called Interactions in the Chanl data model) are the complete record of every conversation your agents have — voice calls, chat sessions, SMS threads, and test simulations. Each one includes full transcripts with speaker turns and timestamps, audio playback, tool call traces, sentiment analysis, cost data, and quality metrics.
You can't improve what you can't measure. This is where you measure.
What's Inside an Interaction
Every call log captures two things: the metadata about the conversation, and the content of the conversation itself.
Metadata
- Source provider (VAPI, Retell, Bland, etc.)
- Phone numbers (from/to)
- Date, time, and duration
- Agent that handled it
- Cost and provider metadata
- Simulation vs. real customer call
Content and Analysis
- Full audio recording with playback
- Complete transcript with speaker turns and timestamps
- Every tool call the agent made (traced with inputs/outputs)
- Quality score (if evaluated)
- Sentiment analysis
- Extracted data and tags
Browsing Interactions
The call logs view gives you a searchable, filterable list of every conversation. Sort by date, score, duration, or agent to find what you're looking for.
curl https://api.chanl.ai/v1/call-logs \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"limit": 50,
"sortBy": "date",
"order": "desc"
}'import Chanl from "@chanl/sdk";
const chanl = new Chanl({ apiKey: "YOUR_API_KEY" });
const logs = await chanl.callLogs.list({
limit: 50,
sortBy: "date",
order: "desc",
});
for (const call of logs.calls) {
console.log(`${call.date} — ${call.agent} — Score: ${call.score}`);
}from chanl import Chanl
chanl = Chanl(api_key="YOUR_API_KEY")
logs = chanl.call_logs.list(
limit=50,
sort_by="date",
order="desc"
)
for call in logs.calls:
print(f"{call.date} — {call.agent} — Score: {call.score}"){
"calls": [
{
"id": "call_abc123",
"source": "vapi",
"from": "+1234567890",
"to": "+1987654321",
"agent": "agent-v1",
"date": "2024-01-15T14:30:00Z",
"duration": 245,
"score": 87,
"analyzed": true,
"isSimulation": false
}
],
"total": 1247,
"page": 1
}Transcripts
The transcript is the text representation of an interaction — auto-generated from voice via speech-to-text, or captured directly from chat messages. Each segment includes a timestamp, speaker identification, and the exact words spoken.
curl https://api.chanl.ai/v1/call-logs/call_abc123/transcript \
-H "Authorization: Bearer YOUR_API_KEY"const transcript = await chanl.callLogs.getTranscript("call_abc123");
for (const segment of transcript.segments) {
console.log(`[${segment.timestamp}s] ${segment.speaker}: ${segment.text}`);
}transcript = chanl.call_logs.get_transcript("call_abc123")
for segment in transcript.segments:
print(f"[{segment.timestamp}s] {segment.speaker}: {segment.text}"){
"callId": "call_abc123",
"transcript": [
{
"speaker": "agent",
"timestamp": 0,
"text": "Thank you for calling. How can I help you today?"
},
{
"speaker": "customer",
"timestamp": 3.2,
"text": "I received a damaged product and need a replacement."
},
{
"speaker": "agent",
"timestamp": 6.8,
"text": "I'm sorry to hear that. Let me help you with a replacement right away."
}
],
"duration": 245,
"wordCount": 487
}Reading transcripts is how teams find failure patterns. Search across thousands of conversations for specific phrases, tool failures, or escalation triggers.
Tool Call Traces
Every tool call your agent made during the conversation is recorded — what it called, what inputs it sent, what came back, and how long it took. This is how you debug agent behavior without guessing.
When your agent looks up an order, checks inventory, or creates a ticket, you'll see each step in the trace. If a tool failed or returned unexpected data, you'll see that too.
Audio Playback
Stream or download the original recording:
curl https://api.chanl.ai/v1/call-logs/call_abc123/audio \
-H "Authorization: Bearer YOUR_API_KEY"const audio = await chanl.callLogs.getAudio("call_abc123");
console.log(`URL: ${audio.url}`);
console.log(`Expires: ${audio.expiresAt}`);
console.log(`Duration: ${audio.duration}s`);audio = chanl.call_logs.get_audio("call_abc123")
print(f"URL: {audio.url}")
print(f"Expires: {audio.expires_at}")
print(f"Duration: {audio.duration}s"){
"url": "https://chanl-audio.s3.amazonaws.com/...",
"expiresAt": "2024-01-15T12:00:00Z",
"format": "mp3",
"duration": 245,
"size": 3145728
}Audio URLs are signed and expire after 1 hour. Request a new URL if the link has expired.
Searching Interactions
Filter by Score, Date, Agent, or Source
Find exactly the calls you're looking for:
curl "https://api.chanl.ai/v1/call-logs?minScore=0&maxScore=70" \
-H "Authorization: Bearer YOUR_API_KEY"curl "https://api.chanl.ai/v1/call-logs" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"dateRange": {
"start": "2024-01-01",
"end": "2024-01-31"
}
}'curl "https://api.chanl.ai/v1/call-logs?agent=agent-v1" \
-H "Authorization: Bearer YOUR_API_KEY"curl "https://api.chanl.ai/v1/call-logs?isSimulation=false" \
-H "Authorization: Bearer YOUR_API_KEY"Search Within Transcripts
Find conversations where specific phrases were mentioned. This is how you discover that 80% of escalations happen when customers say "refund policy" — then fix it proactively.
curl -X POST https://api.chanl.ai/v1/call-logs/search \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "refund policy",
"dateRange": "30d",
"minScore": 0,
"maxScore": 75
}'const results = await chanl.callLogs.search({
query: "refund policy",
dateRange: "30d",
minScore: 0,
maxScore: 75,
});
console.log(`Found ${results.totalResults} calls`);
for (const r of results.results) {
console.log(`Call ${r.callId} — Score: ${r.score}`);
}results = chanl.call_logs.search(
query="refund policy",
date_range="30d",
min_score=0,
max_score=75
)
print(f"Found {results.total_results} calls")
for r in results.results:
print(f"Call {r.call_id} — Score: {r.score}"){
"results": [
{
"callId": "call_xyz789",
"date": "2024-01-14T10:22:00Z",
"score": 68,
"matches": [
{
"speaker": "customer",
"text": "What's your refund policy?",
"timestamp": 45
},
{
"speaker": "agent",
"text": "Our refund policy allows returns within 30 days",
"timestamp": 48
}
]
}
],
"totalResults": 23
}Analyzing Interactions
Score a Call After the Fact
Got calls that weren't evaluated when they happened? Run analysis with any scorecard:
curl -X POST https://api.chanl.ai/v1/call-logs/call_abc123/analyze \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"scorecard": "customer-service-quality"
}'const analysis = await chanl.callLogs.analyze("call_abc123", {
scorecard: "customer-service-quality",
});
console.log(`Overall score: ${analysis.overallScore}`);
console.log(`Strengths: ${analysis.analysis.strengths.join(", ")}`);
console.log(`Recommendations: ${analysis.analysis.recommendations.join(", ")}`);analysis = chanl.call_logs.analyze("call_abc123",
scorecard="customer-service-quality"
)
print(f"Overall score: {analysis.overall_score}")
print(f"Strengths: {', '.join(analysis.analysis.strengths)}")
print(f"Recommendations: {', '.join(analysis.analysis.recommendations)}"){
"callId": "call_abc123",
"overallScore": 87,
"analysis": {
"strengths": [
"Showed immediate empathy for customer's issue",
"Offered solution within first minute",
"Confirmed customer satisfaction before ending"
],
"weaknesses": [
"Didn't verify customer identity before processing",
"Missed opportunity to mention protection plan"
],
"recommendations": [
"Add identity verification step to prompt",
"Include relevant product suggestions during replacement scenarios"
]
},
"categoryScores": {
"Communication": 92,
"Problem Resolution": 88,
"Compliance": 79
}
}Batch Analysis
Score an entire week's worth of calls at once:
const results = await chanl.callLogs.batchAnalyze({
filters: {
dateRange: { start: "2024-01-08", end: "2024-01-15" },
analyzed: false,
},
scorecard: "customer-service-quality",
});
console.log(`Analyzed ${results.count} calls`);
console.log(`Average score: ${results.avgScore}`);results = chanl.call_logs.batch_analyze(
filters={
"date_range": {"start": "2024-01-08", "end": "2024-01-15"},
"analyzed": False
},
scorecard="customer-service-quality"
)
print(f"Analyzed {results.count} calls")
print(f"Average score: {results.avg_score}")Exporting Data
Pull call data into your own tools for deeper analysis or compliance records.
curl -X POST https://api.chanl.ai/v1/call-logs/export \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"format": "csv",
"dateRange": "30d",
"fields": ["date", "agent", "score", "duration"]
}' > calls_export.csvcurl -X POST https://api.chanl.ai/v1/call-logs/export \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"format": "json",
"dateRange": "30d",
"includeTranscripts": true,
"includeAnalysis": true
}' > calls_export.jsoncurl -X POST https://api.chanl.ai/v1/call-logs/export \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"format": "zip",
"dateRange": "7d",
"includeAudio": true,
"includeTranscripts": true
}' > calls_with_audio.zipFinding Training Data
Your best and worst calls are training data. Use them.
High-Quality Examples
Find top-scoring calls to use as fine-tuning data:
const topCalls = await chanl.callLogs.list({
minScore: 90,
dateRange: "90d",
limit: 50,
sortBy: "score",
order: "desc",
});
const trainingData = await chanl.fineTuning.prepareDataset({
calls: topCalls.map((c) => c.id),
format: "conversational",
});
console.log(`Prepared ${topCalls.length} high-quality examples for training`);Failure Pattern Detection
Find recurring problems across low-scoring calls:
const patterns = await chanl.callLogs.analyzePatterns({
filters: { maxScore: 70, dateRange: "30d" },
groupBy: "issue_type",
});
for (const p of patterns) {
console.log(`${p.issue}: ${p.count} occurrences (${p.percentage}%)`);
}
// Output:
// Refund policy confusion: 23 occurrences (34%)
// Unable to verify customer: 15 occurrences (22%)
// Tool failure: 12 occurrences (18%)Compliance and Auditing
Find calls that are missing required disclosures for regulatory review:
curl -X POST https://api.chanl.ai/v1/call-logs/compliance-search \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dateRange": {
"start": "2024-01-01",
"end": "2024-01-31"
},
"requiredDisclosures": [
"data_privacy_notice",
"call_recording_notice"
],
"onlyFlagged": true
}'{
"flaggedCalls": [
{
"callId": "call_compliance123",
"date": "2024-01-15T09:30:00Z",
"missingDisclosures": ["call_recording_notice"],
"severity": "high"
}
],
"totalFlagged": 3,
"complianceRate": 98.7
}