Chanl

Live Calls

Listen in on every call — monitor live AI conversations in real time with transcripts, scores, and instant intervention

Listen In on Every Call

Live call monitoring lets you hear exactly what your agent is saying — right now, as it's happening. You get a live audio stream, a real-time transcript, and a quality score that updates with every turn. If something goes sideways, you can flag it, transfer to a human, or end the call.

What You See During a Live Call

Each active call shows you everything you need to decide whether to watch, intervene, or move on:

Call Information

  • From/To phone numbers
  • Call duration (live timer)
  • Agent handling the call
  • Customer context and scenario

Real-Time Data

  • Live transcript updating as they speak
  • Running quality score
  • Active alerts on this call
  • Every tool call the agent makes

Viewing Active Calls

Your live calls dashboard shows every conversation in progress. Filter by agent, alert status, or duration to find the calls that need your attention.

# List all active calls
curl https://api.chanl.ai/v1/live-calls \
  -H "Authorization: Bearer YOUR_API_KEY"
import Chanl from "@chanl/sdk";

const chanl = new Chanl({ apiKey: "YOUR_API_KEY" });

const activeCalls = await chanl.liveCalls.list();

for (const call of activeCalls.calls) {
  console.log(`${call.id} — Agent: ${call.agent}, Score: ${call.currentScore}`);
}
from chanl import Chanl

chanl = Chanl(api_key="YOUR_API_KEY")

active_calls = chanl.live_calls.list()

for call in active_calls.calls:
    print(f"{call.id} — Agent: {call.agent}, Score: {call.current_score}")
{
  "activeCalls": [
    {
      "id": "call_abc123",
      "from": "+1234567890",
      "to": "+1987654321",
      "agent": "agent-v1",
      "duration": 142,
      "status": "in_progress",
      "currentScore": 87,
      "alerts": [],
      "isSimulation": false
    }
  ],
  "totalActive": 1
}

Real Customer Calls vs. Test Simulations

Calls come from two sources. Knowing which is which helps you prioritize:

  • Customer calls ("isSimulation": false) — Real conversations with real business impact. If something's wrong, it matters now.
  • Test simulations ("isSimulation": true) — Automated test runs from your scenarios. Lower urgency, but useful for watching how agents handle edge cases.

Following the Transcript

The transcript updates live alongside the audio stream. You'll see each speaker turn with timestamps and the exact words spoken — so you can read along or catch up on a call already in progress.

curl https://api.chanl.ai/v1/live-calls/call_abc123/transcript \
  -H "Authorization: Bearer YOUR_API_KEY"
const transcript = await chanl.liveCalls.getTranscript("call_abc123");

for (const segment of transcript.segments) {
  console.log(`[${segment.timestamp}s] ${segment.speaker}: ${segment.text}`);
}
transcript = chanl.live_calls.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?"
    },
    {
      "speaker": "customer",
      "timestamp": 3.2,
      "text": "I need to return a product."
    }
  ],
  "lastUpdate": "2024-01-15T10:30:42Z"
}

Expect a 2-5 second delay between the spoken word and the transcript update. This is normal — it's the time for speech-to-text processing.

Taking Action on a Call

Flag for Follow-Up

See something worth reviewing later? Add a note without disrupting the conversation:

curl -X POST https://api.chanl.ai/v1/live-calls/call_abc123/notes \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "note": "Agent handled the objection well — good empathy shown",
    "timestamp": 145,
    "category": "positive"
  }'
await chanl.liveCalls.addNote("call_abc123", {
  note: "Agent handled the objection well — good empathy shown",
  timestamp: 145,
  category: "positive",
});
chanl.live_calls.add_note("call_abc123",
    note="Agent handled the objection well — good empathy shown",
    timestamp=145,
    category="positive"
)

Transfer to a Human

When the agent's stuck or a customer needs a real person, hand off the call:

curl -X POST https://api.chanl.ai/v1/live-calls/call_abc123/transfer \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transferTo": "human-agent-queue",
    "reason": "Complex issue requiring human judgment",
    "context": "Customer requesting exception to return policy"
  }'
await chanl.liveCalls.transfer("call_abc123", {
  transferTo: "human-agent-queue",
  reason: "Complex issue requiring human judgment",
  context: "Customer requesting exception to return policy",
});
chanl.live_calls.transfer("call_abc123",
    transfer_to="human-agent-queue",
    reason="Complex issue requiring human judgment",
    context="Customer requesting exception to return policy"
)

When to transfer:

  • The agent is clearly failing to resolve the issue
  • The customer is visibly frustrated and escalating
  • Compliance or legal concerns come up
  • The request is outside the agent's capabilities

End a Call

Terminate the conversation if absolutely necessary:

curl -X POST https://api.chanl.ai/v1/live-calls/call_abc123/end \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Abusive customer",
    "note": "Customer using inappropriate language"
  }'

Use this sparingly. Ending calls abruptly creates a poor customer experience and should be a last resort.

Real-Time Alerts on Live Calls

Calls that trigger alerts get flagged automatically. You don't have to watch every call — just the ones Chanl tells you about.

What Triggers an Alert

Filter to Alert Calls Only

curl https://api.chanl.ai/v1/live-calls?hasAlerts=true \
  -H "Authorization: Bearer YOUR_API_KEY"

Streaming Updates

For programmatic monitoring, subscribe to live updates via WebSocket. You'll get notified as calls start, update, trigger alerts, and end.

const stream = chanl.liveCalls.stream({
  agents: ["agent-v1", "agent-v2"],
  includeTranscript: true,
  alertsOnly: false,
});

stream.on("call_started", (call) => {
  console.log(`New call: ${call.id} — Agent: ${call.agent}`);
});

stream.on("call_updated", (update) => {
  console.log(`Call ${update.id} — Score: ${update.currentScore}`);
});

stream.on("alert_triggered", (alert) => {
  console.log(`Alert on ${alert.callId}: ${alert.message}`);
  if (alert.severity === "high") {
    notifyTeam(alert);
  }
});

stream.on("call_ended", (call) => {
  console.log(`Call ended: ${call.id}, Final score: ${call.finalScore}`);
});
stream = chanl.live_calls.stream(
    agents=["agent-v1", "agent-v2"],
    include_transcript=True,
    alerts_only=False
)

for event in stream:
    if event.type == "call_started":
        print(f"New call: {event.call.id} — Agent: {event.call.agent}")
    elif event.type == "alert_triggered":
        print(f"Alert on {event.alert.call_id}: {event.alert.message}")

Monitoring Multiple Agents

When you're running several agents, the overview gives you a bird's-eye view of what's happening across all of them:

curl https://api.chanl.ai/v1/live-calls/stats \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "activeCalls": 12,
  "avgDuration": 4.2,
  "longestCall": {
    "id": "call_long123",
    "duration": 847,
    "agent": "agent-v1"
  },
  "callsWithAlerts": 3,
  "callsOverThreshold": 2
}

Troubleshooting

What's Next?

Alerts

Get notified the way you work — Slack, email, SMS, or webhooks

Call Logs

Review completed interactions with full transcripts and analysis

Analytics

Turn conversation data into performance trends

Agents

Use what you've seen to make your agents better

On this page