Docs / Integrations / Vicidial

Integrate AMDY AMD with Vicidial / ViciBox

AMDY.IO is an AI answering machine detection service that runs as an EAGI script on your existing Vicidial or ViciBox server. It intercepts each outbound call at extension 8370, streams 8 kHz PCM audio to the AMDY backend over WebSocket, and exposes the result as the AMDSTATUS channel variable for your dialplan to route on. This page covers the install, the wiring it injects, and the channel variables you branch on.

New to AMDY on ViciDial? Start with the ViciDial AMD guide for the product-level walkthrough, then come back here for the install commands and dialplan reference. Running Asterisk or FreeSWITCH? See the Asterisk install and FreeSWITCH install pages.

What does the installer do on a Vicidial server?

The unified installer installamd-v2.sh performs every step needed to wire AMDY into a running Vicidial or ViciBox host:

  • Auto-detects the OS (openSUSE, CentOS, Debian or Ubuntu) and the ViciBox major version by reading /etc/vicidial/version or /usr/src/astguiclient/VERSION, defaulting to 9+ when it cannot tell.
  • Downloads the matching tarball (amdy.tar.gz, amdy8.tar.gz for ViciBox 8, or amdy360.tar.gz with --360) over HTTPS from download.amdy.io and verifies it against a published sha256.
  • Extracts amd.py to /var/lib/asterisk/agi-bin/ and makes it executable.
  • Installs the Python dependencies (pyst2, websocket-client, mysql-connector-python, configparser, versions vary by ViciBox 7/8/9+).
  • Calls POST /api/v1/ips/register with your API key and the server's detected public IP, activating the account.
  • Appends the AMDY block to /etc/asterisk/extensions.conf after extension 8369 and reloads Asterisk with asterisk -rx "reload".

Vicidial runs as root, so the installer never chowns files to asterisk. TLS verification is required on every outbound call the installer makes.

How do I run the installer?

As root on the ViciBox host, with your API key. Any of the three forms below works:

curl -fsSL https://download.amdy.io/installamd-v2.sh | bash -s <API_KEY>

Or, with explicit options:

curl -fsSL https://download.amdy.io/installamd-v2.sh | bash -s -- --api-key <KEY> [--360] [-v 8]

Or, against a local copy of the script:

AMDY_API_KEY=<KEY> bash installamd-v2.sh [options]

Installer options:

FlagEffect
-v, --versionForce a ViciBox major version (7 through 12).
-o, --osForce an OS: opensuse, centos, debian or ubuntu.
-3, --360Install the ViciBox 360 variant (amdy360.tar.gz).
--skip-registerSkip the POST /api/v1/ips/register step.
--script-onlyDrop amd.py and dependencies only; do not touch extensions.conf.
--portal-baseOverride the portal base URL written into /etc/amdy/amdy.conf.

The installer writes the API key to /etc/amdy/api-key (mode 600) and a small config to /etc/amdy/amdy.conf containing the key, the portal base and the WebSocket endpoint ws://api.amdy.io:2700.

What dialplan does the installer inject?

The installer appends the following block to /etc/asterisk/extensions.conf immediately after extension 8369, then reloads Asterisk. It is identical on ViciBox 7 and ViciBox 8+:

exten => 8370,1,AGI(agi://127.0.0.1:4577/call_log)
exten => 8370,n,Playback(sip-silence)
exten => 8370,n,EAGI(/var/lib/asterisk/agi-bin/amd.py)
exten => 8370,n,GotoIf($["${AMDSTATUS}" = "HONEYPOT"]?honeypot)
exten => 8370,n,GotoIf($["${AMDCAUSE}" = "NETERR" | "${AMDCAUSE}" = "INTERR"]?amd_fallback:continue)
exten => 8370,n(amd_fallback),AMD(2000,2000,1000,5000,120,50,4,256)
exten => 8370,n(continue),AGI(VD_amd.agi,${EXTEN})
exten => 8370,n,AGI(agi-VDAD_ALL_outbound.agi,NORMAL-----LB-----${CONNECTEDLINE(name)})
exten => 8370,n(honeypot),Hangup()

What each priority does:

  1. AGI(agi://127.0.0.1:4577/call_log) logs the call through the local AGI listener, matching the surrounding Vicidial dialplan.
  2. Playback(sip-silence) primes the audio path before AMDY starts reading EAGI fd 3.
  3. EAGI(/var/lib/asterisk/agi-bin/amd.py) runs AMDY. The script opens a WebSocket to ws://api.amdy.io:2700, sends one JSON config frame {"config":{"sample_rate":8000,"VID":"<caller id name or Unknown>"}}, then streams 8 kHz 16-bit mono PCM in 9.5 kB reads from EAGI fd 3. It sends at elapsed 0.7, 1.0, 2.0 and 3.0 seconds, then switches to 8 kB size-based chunks, and closes with a text frame {"eof":1} to force the final verdict.
  4. On AMDSTATUS = HONEYPOT the call is hung up at the honeypot label.
  5. On AMDCAUSE = NETERR or INTERR the dialplan falls back to Asterisk's built-in AMD() application so the call still gets a verdict.
  6. Otherwise control falls through to VD_amd.agi and agi-VDAD_ALL_outbound.agi, which hand the result back to Vicidial with the connected line name attached.

If you install with --script-only, the installer does not touch extensions.conf. Hook EAGI into your own dialplan with EAGI(/var/lib/asterisk/agi-bin/amd.py).

Which channel variables do I route on?

After EAGI(/var/lib/asterisk/agi-bin/amd.py) returns, three channel variables are set. Branch your dialplan on these values:

VariableValuesMeaning
AMDSTATUSHUMAN, MACHINE, HANGUP, NOTSURETop-level verdict. On any internal error the script defaults to HUMAN for call safety.
AMDCAUSEHUMAN, MACHINE, CONNECTION_ERROR, PROCESSING_ERROR, NO_AUDIO, AUDIO_TIMEOUT, NO_AUDIO_TIMEOUT, FATAL_ERRORReason the verdict was reached. The injected dialplan also checks NETERR and INTERR to trigger the built-in AMD fallback.
AMDSTATSRaw AMDY responseThe original detection string returned by the backend. Useful for debugging.

The rule mirrors the ViciDial container setting HUMAN,HUMAN: only HUMAN should reach an agent. Everything else is dispositioned automatically. Full classification taxonomy: API reference.

How do I verify the install?

  1. Confirm the script is in place and executable: ls -l /var/lib/asterisk/agi-bin/amd.py.
  2. Confirm the key file is readable only by root: stat -c '%a %U' /etc/amdy/api-key should return 600 root.
  3. Confirm the extension block is present: asterisk -rx "dialplan show 8370".
  4. Place an outbound call to a known mobile number and check the CDR for AMDSTATUS=HUMAN.
  5. Place an outbound call to a known voicemail and check the CDR for AMDSTATUS=MACHINE.

If your portal dashboard shows the server IP as active under app.amdy.io, the one-time registration call succeeded.

What if something goes wrong?

SymptomLikely cause
Installer fails the sha256 checkCorrupt or intercepted download. Re-run on the same host; if it fails again, email support.
AMDSTATUS always HANGUPOutbound TCP to api.amdy.io:2700 blocked. Check egress firewall and proxy.
AMDCAUSE is CONNECTION_ERROR on every callServer IP is not registered. Re-run the installer without --skip-register.
NO_AUDIO on every callPlayback(sip-silence) removed, or EAGI fd 3 not delivering audio. Restore the injected block.
Machines reaching agentsRouting matches too broadly in your container. Bridge only on AMDSTATUS=HUMAN.
Every call logs VID as UnknownCaller ID name not set in Vicidial before the AGI step. Set it on the lead or the campaign.
Extension 8370 not found after installextensions.conf was not reloaded. Run asterisk -rx "reload".

Frequently asked questions

Do I need to edit my dialplan by hand?

No. The installer appends the extension 8370 block to /etc/asterisk/extensions.conf and reloads Asterisk for you. Use --script-only only if you want to wire EAGI into an existing custom dialplan yourself.

Does AMDY work on ViciBox 7 and 8?

Yes. The installer supports ViciBox 7 through 12. Use -v 7 or -v 8 if auto-detection picks the wrong major version. ViciBox 8 and ViciBox 360 each get a different tarball.

Where is my API key stored after install?

In /etc/amdy/api-key (mode 600, root-owned) and referenced from /etc/amdy/amdy.conf. The key is also sent in the Bearer header on the one-time registration call and used by amd.py for every WebSocket connection.

Is there a wss:// (TLS) endpoint for the WebSocket?

The installers and amd.py ship with ws://api.amdy.io:2700. If you need a TLS-terminated endpoint for your network policy, contact us for integration access.

Does the installer run as root?

Yes. Vicidial and ViciBox run as root, and the installer must too. It intentionally does not chown files to the asterisk user.

Start detecting

Run the installer on your ViciBox host, place a test call, and watch the verdicts appear in your dashboard.

Open the AMDY console

Support

Need help? Email [email protected] with your ViciBox version (cat /etc/vicidial/version) and the output of asterisk -rx "dialplan show 8370".