Wiring Asterisk to a CRM: AMI, ARI, AGI, and which one you need
Almost every "integrate the phone system with the CRM" request is really three requests wearing one sentence: click a number in the CRM and the desk phone dials it; a call comes in and the customer's record opens on the agent's screen before they pick up; and every call lands in the CRM afterwards as an activity nobody had to type. They sound like one project. They are three, they use different parts of Asterisk, and conflating them is how integrations end up brittle.
The three interfaces, and what each is for
Asterisk exposes three integration surfaces. Picking the wrong one is the most common architectural mistake we clean up.
| Interface | What it is | Direction | Use it for |
|---|---|---|---|
| AMI (Asterisk Manager Interface) | A persistent TCP control/event socket on port 5038 | Your app connects in; sends Actions, receives Events | Click-to-call (Originate), watching call state, screen-pop triggers |
| ARI (Asterisk REST Interface) | A REST API plus a WebSocket for events; you own the call in a Stasis application | Your app drives the call | Building your own call flow, IVR, routing logic in real code |
| AGI (Asterisk Gateway Interface) | A script the dialplan invokes for a single call, synchronously | Dialplan calls out to you | A mid-call lookup: which queue does this customer belong to? |
The short version: AMI to observe and command the PBX from outside; ARI to own the call logic yourself; AGI for a quick synchronous decision inside the dialplan. Most CRM integrations need AMI and nothing else. Reach for ARI only when you are building call flows, not just reflecting them into a CRM.
Click-to-call
The agent clicks a number; the PBX rings the agent's own extension first, and when they lift the handset it dials the customer. That ordering surprises people: you Originate a call to the agent, with the customer number as the destination the channel connects to once the agent answers.
Over AMI it is an Originate action. The details that bite: set the Caller ID the customer should see (not the agent's internal extension), use the right channel technology for the agent's phone, and decide whether you originate to the extension or to a Local channel that runs through your dialplan so the call is logged and recorded like any other. Originating straight to a device skips your dialplan, and then the call is missing from exactly the records this project was supposed to populate.
Screen-pop
This is the feature that makes the whole thing feel magic, and the one with the most moving parts. The customer's record must open on the agent's screen the moment the call rings, not when they answer, and it must open on the right agent's screen.
Three things have to line up. An event source tells you a call is ringing for a given agent — the AMI Newchannel/Newstate/DialBegin events, or a StasisStart if you are on ARI. A number-matching step turns the inbound caller ID into a CRM lookup, which is where most screen-pops quietly fail: numbers arrive in a dozen formats and your CRM stores them in one, so normalise everything to E.164 before you match or half your customers pop as "unknown". And a delivery path gets the "pop record X" signal to that agent's browser or CRM client, usually a websocket or the CRM's own notification API.
Timing is the tell of a good implementation: pop on ring, so the agent sees who it is before deciding how to answer. Popping on answer is easier and worth nothing.
Call logging
The system of record for what happened is the CDR (Call Detail Record), written when the call ends. For richer, event-level history — hold, transfer, queue time — Asterisk also has CEL (Channel Event Logging). For a CRM activity, CDR is usually enough: one row per call, with direction, numbers, duration and disposition, pushed into the CRM as a completed activity linked to the matched contact.
The mistake is trying to build the activity from live AMI events instead. AMI is the right source for the real-time screen-pop, but reconstructing "the call" from a stream of channel events is fiddly and easy to get wrong on transfers and conferences. Let the CDR be the record; use the live events only for the things that must happen live.
3CX is a different conversation
If the customer runs 3CX rather than Asterisk, most of the above does not apply. 3CX integrates with CRMs through configurable templates that call the CRM's own REST API, so click-to-call and screen-pop for the common CRMs are configuration rather than code. That is a genuine advantage when the CRM is on the supported list, and more work when it is not: a bespoke or in-house CRM means writing a template against your own API — and exposing one if the CRM does not already have it. Know which situation you are in before quoting the work.
Security and resilience, which is where these break in production
Two things sink these integrations after they are "working".
- •AMI is dangerous if exposed. Port 5038 speaks a plaintext protocol, and an AMI login with broad permissions can control the entire PBX — originate calls, read configuration, hang up channels. Bind it to localhost or a management network, put it behind TLS if it must cross a link, and give the integration account only the privileges it needs, not the defaults. An AMI port open to the internet is a toll-fraud incident waiting to happen.
- •The link will drop, and your integration must survive it. AMI connections die on PBX restarts and network blips; without automatic reconnection and re-subscription the screen-pops simply stop one afternoon and nobody notices until a customer complains. Equally, the CRM will have outages — so the integration belongs in a small middleware service between PBX and CRM that can absorb a CRM being down without wedging call handling. The phones must keep working when the CRM does not.
What we actually do
The pattern that holds up: a dedicated middleware service holding one well-scoped AMI connection with automatic reconnection, normalising numbers to E.164 in one place, driving screen-pops over the live events and writing activities from the CDR, and treating the CRM as something that can fail without taking the phones with it. It is not a lot of code. It is a small amount of code with the failure modes actually handled, which is the difference between a demo and something an agent trusts at 9am on a Monday.
Phones and CRM that should talk to each other?
We build and run Asterisk, FreePBX and 3CX telephony and their CRM integrations — click-to-call, screen-pop, call logging — and keep them working when the network and the CRM do not. €65/hour, fixed-scope quotes for projects.