Documentation
VM Hunter documentation
Real-time answering machine detection for outbound dialers. Stream the first seconds of a call over a WebSocket and get HUMAN or MACHINE back in about two seconds.
Integrations
Pick the guide for your dialer. Each one ships a ready-made client, so you install a file, set your API key and add a dialplan entry.
VICIdial / Asterisk
EAGI Python client. Works with any Asterisk dialplan; VICIdial campaign settings included.
Read guideFreeSWITCH
Lua script plus a drop-in XML dialplan. Uses mod_audio_fork or mod_audio_stream.
Read guideTwilio
Bridge Twilio Media Streams to VM Hunter and redirect the call on the verdict.
Read guideWebSocket API
Build your own client: config frame, PCM streaming, response codes and timing.
Read guideAll clients are open source under the MIT licence at github.com/vmhunterhq.
How it works
VM Hunter never touches your SIP trunk. Your dialer keeps the call and forks the callee's audio to us the moment the call is answered.
| Step | What happens |
|---|---|
| 1. Answer | The dialer answers the outbound call and runs the VM Hunter client on the callee leg. |
| 2. Connect | The client opens a WebSocket to ws://app.vmhunter.com:2701 and sends a config frame with your API key. |
| 3. Stream | The first seconds of far-end audio are streamed as raw 8 kHz PCM while the callee is greeting. |
| 4. Classify | The SpeechLLM engine transcribes and analyses the greeting, tones and signal, and replies AMDSTATUS + AMDCAUSE. |
| 5. Route | Your dialplan connects HUMAN calls to an agent and drops or dispositions MACHINE calls. |
The engine listens to the first 2 seconds of audio. If the callee is still mid-sentence at that point and nothing decisive has been heard yet, it keeps listening for up to 3 seconds and stops as soon as the speaker pauses or a decisive phrase arrives.
Before you start
| Requirement | Notes |
|---|---|
| API key | Create one in Dashboard → API Keys. The free plan includes 5,000 calls a month. |
| Outbound network | Your dialer must reach app.vmhunter.com on TCP port 2701. No inbound ports are needed. |
| Audio | 8 kHz, 16-bit signed little-endian, mono. The bundled clients produce this for you. |
| Python 3 | For the Asterisk and Twilio clients. FreeSWITCH uses its built-in Lua. |
Every analysed call counts
A call is billed once its config frame is accepted, including calls that turn out to be silent. Calls that come backAMDSTATUS=FAILED are not charged.What you get back
One JSON text frame, then the server closes the socket:
{"AMDSTATUS": "MACHINE", "AMDCAUSE": "MACHINE_BEEP"}| AMDSTATUS | Route it |
|---|---|
HUMAN | A live person answered. Connect to an agent. |
MACHINE | Voicemail, IVR, beep, static or a disconnected number. Drop or disposition; AMDCAUSE says which. |
CALLGUARD | Call screening (iPhone, Google Call Screen). A person is listening. Screened calls always carry AMDCAUSE=CALLGUARD_PHRASE:…, so branch on that; the bundled dialplans do. |
FAILED | Detection could not run. The clients apply a fail-safe, MACHINE by default. |
The full list of AMDCAUSE values, the config frame and timing details are in the WebSocket API reference.