Docs / Asterisk integration
Integrate AMDY AMD with Asterisk
AI answering machine detection for Asterisk. This guide wires AMDY into your dialplan with EAGI (Extended AGI), streaming 8 kHz answered-call audio to the AMDY backend over WebSocket and routing each call on the result. It uses the same backend as ViciDial and FreeSWITCH, so results, timing, and your dashboard stay consistent across platforms.
What is AMDY AMD for Asterisk?
AMDY is an AI-powered answering machine detection service. You connect your Asterisk server to the AMDY backend over WebSocket at ws://api.amdy.io:2700. After each call is answered, Asterisk runs an EAGI script that streams live audio (8 kHz, 16-bit, mono PCM) to AMDY, which returns a classification of HUMAN or MACHINE (plus sub-classes like voicemail types). Your dialplan then routes the call accordingly.
What are the prerequisites?
- Asterisk 13+ with EAGI support enabled (standard in most builds)
- Python 3.6+ on the Asterisk host
- Root access on the Asterisk server
- Your AMDY.IO API key, from Settings
- Outbound TCP to api.amdy.io:2700
How do I run the installer?
On the Asterisk server, as root, with your API key:
curl -sL https://download.amdy.io/installamd-asterisk.sh | bash -s -- YOUR_API_KEY
The installer:
- Downloads amd.py from https://download.amdy.io/amd.py and installs it as /var/lib/asterisk/agi-bin/amdy-amd.py
- Installs Python dependencies via pip: pyst2 and websocket-client
- Stores your API key at /etc/amdy/api-key with mode 600
- Calls POST /api/v1/ips/register with your API key to activate this server's public IP on your AMDY account
The script prints a ready-to-paste dialplan snippet after the install completes. Paste it into your extensions.conf (or the relevant include file) and reload Asterisk.
How do I verify the install?
Check that the script is in place and executable:
ls -l /var/lib/asterisk/agi-bin/amdy-amd.py && cat /etc/amdy/api-key
You should see the script with execute permissions and your API key printed. If the IP registration failed, the installer output will show a non-200 response from the AMDY portal. Fix the network path and re-run.
How is the EAGI dialplan wired?
The installer prints the following dialplan example. It answers the call, runs the EAGI script, and branches on AMDSTATUS:
exten => s,1,Answer()
exten => s,n,EAGI(amdy-amd.py)
exten => s,n,GotoIf($["${AMDSTATUS}" = "HUMAN"]?human:machine)
exten => s,n(machine),Voicemail(1000@default)
exten => s,n,Hangup()
exten => s,n(human),Dial(SIP/agent)What happens step by step:
- Asterisk answers the call.
- EAGI(amdy-amd.py) runs the AMDY script. Asterisk passes the audio stream on file descriptor 3 (8 kHz, 16-bit, mono, raw PCM). The script opens a WebSocket to ws://api.amdy.io:2700, sends a config frame with the caller ID, and streams audio until it gets a result or the timeout fires.
- After EAGI returns, the channel variable ${AMDSTATUS} is set. If it is HUMAN, the call goes to the human extension; otherwise to machine handling.
What channel variables does EAGI set?
| Variable | Values | Meaning |
|---|---|---|
| AMDSTATUS | HUMAN | MACHINE | HANGUP | NOTSURE | Primary classification |
| AMDCAUSE | HUMAN, MACHINE, CONNECTION_ERROR, PROCESSING_ERROR, NO_AUDIO, AUDIO_TIMEOUT, NO_AUDIO_TIMEOUT, FATAL_ERROR | Reason code for the result |
| AMDSTATS | Raw response string | Full classification-duration-confidence payload from AMDY |
Only HUMAN should reach an agent. On any error the script defaults to HUMAN for call safety. Full status definitions: API reference.
What problems should I watch for?
| Symptom | Likely cause |
|---|---|
| No result, call ends after a few seconds | Outbound TCP to api.amdy.io:2700 blocked. Check firewall rules. |
| AMDSTATUS is NOTSURE on every call | This host's IP is not registered. Re-run the installer so it calls /api/v1/ips/register. |
| Machines reaching agents | Dialplan is matching too broadly. Branch only on AMDSTATUS=HUMAN. |
| EAGI script not found | amdy-amd.py not in agi-bin or not executable. Check /var/lib/asterisk/agi-bin/amdy-amd.py permissions. |
| ModuleNotFoundError: pyst2 or websocket-client | pip install did not complete. Run pip install pyst2 websocket-client as root. |
| Every call logs VID as Unknown | Caller ID name not set before EAGI runs. Pass it via CALLERID(name) in the dialplan. |
Frequently asked questions
Is Issabel supported?
Issabel is Asterisk-based, so the generic Asterisk installer often applies. However, Issabel support is not verified end-to-end. Contact [email protected] for integration access if you run Issabel.
Does AMDY support TLS (wss) for the WebSocket?
Currently the endpoint is ws://api.amdy.io:2700 (plain WebSocket). If you need a TLS endpoint, contact [email protected].
How long are API keys?
API keys start with the prefix amd_live_ followed by hex characters. Store them at /etc/amdy/api-key with mode 600.
What audio format does AMDY expect?
8 kHz, 16-bit, mono, raw PCM (signed little-endian). The EAGI script reads this from Asterisk on file descriptor 3 and streams it unchanged to the backend.
Ready to start?
Sign up at app.amdy.io to get your API key, then run the installer on your Asterisk server. Your dashboard at app.amdy.io/dashboard tracks detections, latency, and human rate in real time.
Support
Need help? Email [email protected] with your Asterisk version (asterisk -V) and the output of the installer.