Skip to main content

Asterisk ARI Integration

Overview

Asterisk ARI (Asterisk REST Interface) allows you to connect IntraCord AI voice agents to your existing Asterisk PBX. ARI provides a WebSocket-based event model for controlling calls via Stasis applications, giving IntraCord full control over call flow and audio streaming.

This guide focuses on the IntraCord-specific configuration. For general Asterisk installation and administration, refer to the official Asterisk documentation.

Prerequisites

Before setting up the ARI integration, ensure you have:

  • A running Asterisk instance with chan_websocket and res_websocket_client modules available. Known-working setups: (a) Asterisk 22+, (b) Asterisk 20 LTS with these modules included
  • ARI module enabled in Asterisk
  • chan_websocket (WebSocket channel driver) and res_websocket_client (loads websocket_client.conf) enabled in your Asterisk build. Verify with asterisk -rx "module show like chan_websocket" and asterisk -rx "module show like res_websocket_client" — both should report Running.
  • Network connectivity between your IntraCord instance and Asterisk
  • IntraCord AI instance running and accessible

How setup fits together

Setup crosses between the two systems, so the order matters:

WhereWhat
1AsteriskCreate the ARI user, enable the HTTP server, and add the external-media WebSocket client — the values IntraCord asks for
2IntraCordEnter those values and save. IntraCord generates a Stasis App Name unique to this configuration
3AsteriskPut that generated name in your dialplan as Stasis(<name>) and reload
4IntraCordRegister the extensions that should reach an agent, then place a test call

The dialplan comes last because the Stasis application name does not exist until the configuration is saved. Everything else can be set up in advance.

Part 1: Asterisk connection settings

These are minimal examples focused on the IntraCord integration -- refer to the Asterisk documentation for full configuration details.

Enable ARI (ari.conf)

Create an ARI user that IntraCord will use to authenticate:

[general]
enabled = yes

[IntraCord]
type = user
read_only = no
password = your_secure_password

Enable the HTTP Server (http.conf)

ARI requires the Asterisk HTTP server to be enabled:

[general]
enabled = yes
bindaddr = 0.0.0.0
bindport = 8088

Configure External Media Streaming (websocket_client.conf)

IntraCord uses Asterisk's external media streaming to send and receive audio over WebSocket. Configure a WebSocket client connection that points to your IntraCord instance:

[IntraCord]
type = websocket_client
uri = wss://app.intracord.hu/api/v1/telephony/ws/ari
protocols = media
tls_enabled = yes
ca_list_file = /etc/ssl/certs/ca-certificates.crt

Refer to the Asterisk WebSocket documentation for additional websocket_client.conf options and TLS configuration.

Apply the configuration changes

Reload the affected Asterisk modules from the Asterisk CLI (asterisk -rvvv):

module reload res_ari.so # picks up ari.conf changes
module reload res_websocket_client.so # picks up websocket_client.conf changes

Changes to http.conf require a full Asterisk reload (core reload) or a service restart. core reload also covers both commands above if you would rather reload everything at once.

Part 2: Create the configuration in IntraCord

Step 1: Navigate to Telephony Settings

  1. Navigate to /telephony-configurations and click Add configuration
  2. Select Asterisk ARI as your provider

Step 2: Enter Your ARI Credentials

Configure the following fields:

FieldDescriptionExample
ARI Endpoint URLHTTP base URL of your Asterisk ARI serverhttp://asterisk.example.com:8088
ARI UsernameThe ARI username configured in ari.confIntraCord
App PasswordThe ARI password configured in ari.confyour_secure_password
WebSocket Client NameThe connection name from websocket_client.confIntraCord
From ExtensionsOptional SIP extensions or trunk numbers for outbound callsPJSIP/6001 or 6001
Dial String TemplateHow a dialed number reaches your trunk. See Outbound CallingPJSIP/{number}@my-trunk

Stasis App Name is not something you enter — IntraCord generates it when you save and displays it on the configuration for you to copy.

Step 3: Save and copy the Stasis App Name

Click Save Configuration. IntraCord assigns a Stasis App Name to this configuration — something like IntraCord_a1b2c3d4e5f6 — and shows it on the configuration page. Copy it; you need it for Part 3.

Part 3: Route calls into the Stasis application

Configure the Stasis Dialplan (extensions.conf)

Route incoming calls into the Stasis application IntraCord generated for your configuration:

[from-external]
exten => _X.,1,NoOp(Incoming call to ${EXTEN})
same => n,Stasis(IntraCord_a1b2c3d4e5f6)
same => n,Hangup()

Replace IntraCord_a1b2c3d4e5f6 with the Stasis App Name from your configuration, then reload the dialplan:

dialplan reload

Part 4: Add extensions and test

  1. Add each SIP extension that should be reachable as a phone number (e.g. 8000). For inbound, you'll assign a workflow to each extension separately — see Inbound Calling below.
  2. Create a test workflow and initiate a test call to verify the connection.

Outbound Calling

Asterisk dials a channel technology and a route, not a number. IntraCord builds that dial string from the Dial String Template on your configuration, replacing {number} with the number being called.

The default is PJSIP/{number}, which dials a PJSIP endpoint named after the number. That is right when your endpoints are the extensions you dial, and wrong on an install whose endpoints are trunks — there, originating PJSIP/+966500000000 fails with Allocation failed, because no endpoint by that name exists.

Pick the template that matches how your dialplan places outbound calls:

Your AsteriskTemplateDials
Endpoints named after extensionsPJSIP/{number}PJSIP/1001
One outbound trunkPJSIP/{number}@my-trunkPJSIP/+966500000000@my-trunk
FreePBX, or any dialplan with outbound routesLocal/{number}@from-internalLocal/+966500000000@from-internal

Routing through a Local channel is usually the right choice on FreePBX: the call enters your dialplan, and your own outbound routes handle number translation and trunk selection exactly as they do for a deskphone.

Campaign contacts

A campaign's phone_number column is a destination for this Asterisk, not necessarily a phone number. Extensions (1001), SIP URIs (sip:1001@pbx.local) and dial strings (PJSIP/1001@my-trunk) are all accepted alongside E.164 numbers, and each row goes through the same template above.

Two rules still apply: a destination cannot contain spaces, commas or ampersands, because each of those means something else inside a dial string; and destinations must be unique within a campaign.

Inbound Calling

Unlike other telephony providers that use HTTP webhooks for inbound calls, ARI delivers inbound calls as StasisStart events on the ARI WebSocket. IntraCord automatically detects these events and activates the workflow assigned to the called extension.

How It Works

  1. An external call arrives at Asterisk and the dialplan routes it into your configuration's Stasis application
  2. Asterisk fires a StasisStart event over the ARI WebSocket with the channel in Ring state and the dialed extension in the dialplan context
  3. IntraCord looks up the called extension in your telephony configuration's phone numbers, finds the assigned workflow, validates quota, and creates a workflow run
  4. The call is answered, bridged to an external media channel, and your voice agent workflow begins

Workflow assignment is per extension, so different extensions on the same Asterisk can route to different agents.

Setting Up Inbound Calls

Step 1: Configure the Asterisk dialplan

Ensure your dialplan routes the extensions you care about into the Stasis application you configured in Part 3. Either route a specific extension:

[from-external]
exten => 8000,1,NoOp(Incoming call to 8000)
same => n,Stasis(IntraCord_a1b2c3d4e5f6)
same => n,Hangup()

…or use a pattern that catches every extension you'll register in IntraCord:

[from-external]
exten => _X.,1,NoOp(Incoming call to ${EXTEN})
same => n,Stasis(IntraCord_a1b2c3d4e5f6)
same => n,Hangup()

Replace IntraCord_a1b2c3d4e5f6 with the Stasis App Name shown on your IntraCord configuration.

Step 2: Add the extension as a phone number in IntraCord

  1. Go to /telephony-configurations and open your Asterisk ARI configuration

  2. In the Phone numbers section, add a phone number whose address is the SIP extension (e.g. 8000)

  3. Set its Inbound workflow to the agent that should answer

  4. Save

Repeat Step 2 for each extension that should reach a voice agent.

Step 3: Test an inbound call

Place a call to one of the extensions you configured. You should see the assigned workflow activate and the voice agent respond.

Inbound Call Context

When an inbound call activates a workflow, the following context is available to your workflow:

FieldDescription
caller_numberThe caller's phone number or extension
called_numberThe dialed number or extension
directionAlways inbound
call_idThe Asterisk channel ID
providerAlways ari

Troubleshooting

Cannot connect to ARI endpoint
  • Verify the ARI endpoint URL is correct and reachable from your IntraCord instance
  • Check that the Asterisk HTTP server is running (http.conf has enabled = yes)
  • Ensure firewall rules allow traffic on the ARI port (default: 8088)
  • Confirm the ARI module is loaded: run module show like res_ari in the Asterisk CLI
Authentication failed
  • Verify the ARI Username matches the ARI user section name in ari.conf
  • Check the App Password matches the password in ari.conf
  • Ensure there are no extra spaces in the credentials
No audio during calls
  • Verify chan_websocket is loaded: run module show like chan_websocket in the Asterisk CLI
  • Check that websocket_client.conf is correctly configured with the right IntraCord URI
  • Ensure the WebSocket Client Name in IntraCord matches the section name in websocket_client.conf
  • Verify network connectivity and firewall rules allow WebSocket traffic between Asterisk and IntraCord
Calls not reaching IntraCord
  • Ensure the dialplan routes calls to Stasis(...) using the Stasis App Name from your IntraCord configuration, not the ARI username
  • Confirm you ran dialplan reload after editing extensions.conf
  • If two IntraCord configurations point at this Asterisk, check that they do not name the same Stasis application — the one that connected most recently takes the application over and the other stops receiving calls entirely
  • Check Asterisk CLI for errors: asterisk -rvvv
  • Confirm the ARI WebSocket connection is active
Inbound calls are immediately hung up
  • Verify the called extension is added as a phone number under your ARI configuration in /telephony-configurations and has an Inbound workflow assigned
  • Confirm the workflow exists and belongs to the same organization as the ARI config
  • Check that your organization has available quota
  • Review IntraCord logs for warnings like "no matching phone number registered for config" or "has no inbound_workflow_id assigned"
WebSocket client connection issues
  • Check the URI in websocket_client.conf points to the correct IntraCord host and port
  • Verify the IntraCord instance is running and accepting WebSocket connections
  • If using TLS, ensure certificates are correctly configured on both sides

Best Practices

  • Keep your Asterisk instance on the same network or a low-latency connection to IntraCord for optimal audio quality
  • Use strong passwords for ARI authentication
  • Restrict ARI access to known IP addresses using firewall rules
  • Monitor Asterisk logs alongside IntraCord logs when debugging call issues
  • Keep Asterisk updated to the latest stable version for security and compatibility

Further Reading