# Voicemail detection for AI phone calls: how it works and what to do next

> Voicemail detection (answering machine detection, AMD) tells an AI caller if a person or a machine answered. See how it works and how Hail handles it.

- URL: https://hail.so/blog/voicemail-detection
- Type: Guide
- Tags: voice-agent, outbound
- Published: 2026-11-06
- Reading time: 6 min

Voicemail detection checks what answered a call: a person, voicemail, or another automated system.
It helps an AI agent avoid speaking over a recorded greeting.
Hail checks outbound calls for voicemail. It ends the call without speaking if it detects voicemail or a message saying the person is unavailable.
It can navigate phone menus.

This guide explains how answering machine detection works, where it fails, and how to check results through your AI assistant.
You can also use code for automatic follow-up.

## What is answering machine detection (AMD)?

Answering machine detection (AMD) is the same thing as voicemail detection. The system listens to the greeting after the line connects and puts it in a class. The usual classes are:

- **Human.** A short "hello?", then silence while the person waits.
- **Voicemail.** A long greeting, often with "leave a message after the tone".
- **Unavailable.** A carrier message, such as "the person you called is not available".
- **Phone menu (IVR).** "Press 1 for sales."
- **Uncertain.** Not enough sound to decide.

Older systems decided from timing alone: the length of the first words and the silence after them. Newer systems also turn the greeting into text and classify the words.

## The trade-offs of voicemail detection

Every AMD system makes the same trade between speed and accuracy.

| Problem | What happens | Effect |
| --- | --- | --- |
| Detection takes time | The system waits for the greeting before the agent speaks | The person hears a short silence after "hello" |
| A person is classed as a machine | The call ends while a person is on the line | You lose a real conversation |
| A machine is classed as a person | The agent talks to the greeting | The call wastes minutes, and the recording may hold a partial message |
| A greeting is short and human-like | "Hi, it's Sam" can sound like a live answer | More machine-as-person errors |

No setting removes all errors. Plan for both kinds of mistake in your workflow.

## Voicemail detection on Hail

Hail's behavior is in the [architecture docs](https://github.com/hail-hq/hail/blob/main/docs/public/architecture.md#answering-machine-detection-and-dtmf). In short:

- **When it runs.** Detection runs automatically on outbound calls. It does not run on inbound calls.
- **On voicemail or an unavailable message.** When Hail detects either, the agent ends the call without speaking. It does not leave a message. The call ends with `status: "no_answer"`.
- **On a person, or unsure.** On a human or uncertain verdict, the call goes on as normal. If detection fails, the call also goes on as if a person answered.
- **On a phone menu.** The agent does not speak its greeting to a menu. It reads the menu and can press keys with the `send_dtmf` tool. The AI disclosure waits until a person speaks.
- **Timing.** Hail listens to the greeting before the agent speaks. Longer greetings and extra checks can mean a longer wait.
- **Billing.** A call that a machine answered is billed, because billing starts when the line goes active. Short calls still cost something. See [pricing](https://hail.so/pricing).
- **No options.** There is no field to turn detection off or to leave a voicemail message.

## Check voicemail results with your AI assistant

Connect Hail to your AI assistant through the [MCP setup guide](https://hail.so/mcp).
Then paste this request:

```prompt
Check my latest Hail call. Show its status and end reason. Did voicemail answer?
```

Your assistant can read call results through MCP.
A result of `voicemail_reached` means Hail detected voicemail. `machine_unavailable` means it detected an unavailable message.

This checks a call when you ask. For automatic follow-up, use the optional code section below.

## Test voicemail detection

1. Turn off your phone, or decline the call so it goes to voicemail.
2. Place a test call to your number, as in [your first AI phone call](https://hail.so/blog/first-ai-phone-call).
3. Ask your assistant for the result. Detected voicemail should show `status: "no_answer"` and `end_reason: "voicemail_reached"`.
4. Call again and answer with a short "hello". Check that the agent speaks.
5. Answer with a long, slow greeting, like a voicemail. Note what happens. This shows you the edge cases your workflow must handle.

For outbound calls in general, read the [AI outbound calls guide](https://hail.so/blog/ai-outbound-calls). To reach a business that answers with a phone menu, read about [IVR service providers](https://hail.so/blog/ivr-service-providers). For the rules on calling people who did not ask for a call, read [AI cold calling and the law](https://hail.so/blog/ai-cold-calling).

## Handle voicemail in your code (optional)
Your code can choose the next step after Hail detects voicemail or an unavailable message.
Hail sends a webhook when a call ends without an answer.

### The end_reason values to read

When a call ends, read `status` and `end_reason` on `GET /v1/calls/{id}`, or in the webhook payload.

| `status` | `end_reason` | Meaning | What to do |
| --- | --- | --- | --- |
| `no_answer` | `voicemail_reached` | A voicemail greeting answered | Try another time, or send a text |
| `no_answer` | `machine_unavailable` | A carrier "not available" message answered | Check the number later. Do not retry at once |
| `completed` | `normal_hangup` | The call connected and ended normally | Read the result of the conversation |
| `busy` | | The line was busy or the call was rejected | Retry later |
| `failed` | (see the value) | The call did not run, for example `sip_trunk_failure` | Check the reason before you retry |

### 1. Subscribe to the call events

```bash
curl -X POST https://api.hail.so/v1/webhooks \
  -H "Authorization: Bearer $HAIL_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{
    "target_url": "https://example.com/hooks/hail",
    "event_types": ["call.completed", "call.no_answer", "call.busy", "call.failed"]
  }'
```

Save the signing secret from the response. Verify each webhook's signature before you handle it.
The [webhook guide](https://hail.so/docs/webhooks) explains how. Each `call.*` payload has the call `id`, `status`, `direction`, `from`, `to`, and, once the call ends, `end_reason`.

### 2. Decide the next step

A simple rule set:

- **`voicemail_reached`.** Wait a few hours, then call again. Stop after a small number of tries, such as two or three.
- **`machine_unavailable`.** The phone may be off. Wait longer before the next try.
- **No answer after the last try.** Send one short text through the [SMS API](https://hail.so/sms), if you have consent for texts. Say who you are and how to reach you.

Put a cap on retries in your own code. Calling the same person many times in a day annoys them and can break the rules in your country.

### 3. Keep the message out of voicemail

Hail does not offer a voicemail message feature. Do not write a prompt that depends on leaving one.
Use a text or email when you need to send a message. Those channels give you delivery events you can check.
