Answering machine detection
Detection listens to each answered line and decides whether a person or a machine picked up. People are connected to the agent. Voicemail, phone trees and call screeners are dropped before the agent hears them.
Detection works on the words spoken
When a line is answered, its audio is transcribed word by word as it comes in. Machine phrases such as "leave a message", "press 1" or "please state your name" end the line right away. A short greeting followed by a pause, such as "Hello?" or "Ridgeline Roofing, this is Dana", is a person, and the line is bridged as soon as they stop talking.
The agent hears the person about 1 second after they finish saying hello (median, our network). The speech_ended_to_bridge_ms field on each event gives the time for that call.
Detection runs on every answered line in a dial session and on single calls with amd=true. It is part of the per-minute rate, and lines dropped as machines are never billed.
Results
Every answered line gets exactly one result.
| Result | Meaning |
|---|---|
human | A person answered. The line is bridged to the agent. |
machine_voicemail | A voicemail greeting, personal or carrier default. |
machine_ivr | A phone tree or auto attendant, for example "press 1 for sales". |
machine_screener | A call screening service asking the caller to say their name and reason for calling. |
machine_silent | The line was answered and nobody spoke within 5 seconds. |
Settings
Set detection on the dial session or on a single call. The default is to hang up on machines. Use notify when your app handles machines itself, for example to log the voicemail greeting.
| Parameters | Type | Description |
|---|---|---|
amd | boolean | Turns detection on. Default true for dial sessions and single calls. |
amd_on_machine | hangup | notify | hangup drops the line. notify keeps the line open, sends amd.completed with the result and leaves the next step to your app. Default hangup. |
curl https://api.liveleg.dev/v1/calls \
-H "Authorization: Bearer $LIVELEG_API_KEY" \
-d to=+13035550112 \
-d from=+13035550184 \
-d agent_id=agt_207 \
-d amd=true \
-d amd_on_machine=notifyconst res = await fetch('https://api.liveleg.dev/v1/calls', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
to: '+13035550112',
from: '+13035550184',
agent_id: 'agt_207',
amd: true,
amd_on_machine: 'notify',
}),
});
const call = await res.json();import os, requests
call = requests.post(
"https://api.liveleg.dev/v1/calls",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
json={
"to": "+13035550112",
"from": "+13035550184",
"agent_id": "agt_207",
"amd": True,
"amd_on_machine": "notify",
},
).json() Events
Each answered line sends amd.completed with the result and the action taken. For a person, call.bridged follows with the same speech_ended_to_bridge_ms.
{
"id": "evt_5Rt09Kd3",
"type": "amd.completed",
"created_at": "2026-11-03T15:42:07.390Z",
"livemode": true,
"data": {
"call_id": "cal_8Jq2mT4x",
"leg_id": "leg_a1",
"result": "human",
"speech_ended_to_bridge_ms": 980,
"action": "bridge",
"agent_id": "agt_114"
}
} With amd_on_machine=notify, machine results include the words heard on the line.
{
"id": "evt_5Rt0A1x8",
"type": "amd.completed",
"created_at": "2026-11-03T15:44:12.006Z",
"livemode": true,
"data": {
"call_id": "cal_Z71nP0qe",
"leg_id": "leg_b4",
"result": "machine_voicemail",
"action": "notify",
"transcript": "Hi, you've reached Hollis Family Dental. Please leave a message after the tone."
}
}