Skip to content
ViciDial AI ViciDial AI ViciDial AI

The VICIdial Community Blog

ViciDial AI ViciDial AI ViciDial AI

The VICIdial Community Blog

  • Home
  • Vicidial Hosting
  • Home
  • Vicidial Hosting
Close

Search

  • Home
  • Vicidial Hosting
Subscribe
InboundVICIdial

Inbound DID Routing and In-Groups in VICIdial

By raghavan
September 23, 2023 4 Min Read
0

VICIdial’s inbound side is less documented than its dialer, and the configuration is spread across four screens that have to agree with each other. Get one wrong and calls arrive, go nowhere, and hang up.

This walks the full chain from carrier to agent.

The Chain

An inbound call passes through five stages:

  1. Carrier delivers a SIP INVITE to your server
  2. The trunk’s context sends it to trunkinbound
  3. agi-DID_route.agi matches the dialled number against the DID table
  4. The DID’s route sends it to an in-group
  5. The in-group finds an available agent

Break any link and the call dies. Diagnosis is a matter of establishing how far down the chain it got.

Stage 1 and 2: Getting Into the Right Context

Your carrier entry’s Account Entry must specify the inbound context:

[myprovider]
type=friend
host=sip.provider.com
context=trunkinbound
insecure=port,invite
disallow=all
allow=ulaw
canreinvite=no

For PJSIP, the endpoint needs the same:

[myprovider]
type=endpoint
context=trunkinbound
disallow=all
allow=ulaw
direct_media=no
aors=myprovider

context=default is the classic mistake. Inbound calls then hit your outbound dialplan and fail with “extension not found in context default.”

Stage 3: DID Matching

The trunkinbound context passes the dialled number to the routing AGI:

[trunkinbound]
exten => _X.,1,AGI(agi-DID_route.agi)
exten => _X.,n,Hangup()

Then add the DID under Admin → Inbound → Show DIDs → Add A New DID.

The critical field is DID Pattern, and it must match exactly what your carrier sends. Not what you assume they send. Capture it:

asterisk -rvvvvv
sip set debug peer myprovider

Place a test call and read the request URI:

INVITE sip:15551234567@203.0.113.10 SIP/2.0

That user part — 15551234567 — is your DID pattern. If the carrier sends +15551234567, either include the + in the pattern or normalise it in dialplan:

[trunkinbound]
exten => _+X.,1,Goto(trunkinbound,${EXTEN:1},1)
exten => _X.,1,AGI(agi-DID_route.agi)
exten => _X.,n,Hangup()

Set the DID’s other fields:

  • DID Route: IN_GROUP
  • In-Group: the group you are about to create
  • Active: Y
  • Filter Phone Group: leave as NONE unless you are blocking specific numbers

Other route options are worth knowing: AGENT sends directly to one named agent, EXTENSION to a dialplan extension, PHONE to a specific phone, VOICEMAIL straight to a mailbox, and CALLMENU into an IVR.

Stage 4: The In-Group

The settings that matter most:

  • Group Name / ID — keep IDs short, they appear in reports
  • Active: Y
  • Web Form Address — opens a URL with the caller’s details when a call connects, useful for CRM integration
  • Drop Call Seconds — how long a caller waits before the drop action fires
  • Drop Action — VOICEMAIL, HANGUP, EXTENSION or CALLMENU
  • Queue Priority — higher numbers win when an agent is eligible for several groups
  • Next Agent Call — how VICIdial picks among available agents

That last setting shapes how work is distributed:

SettingBehaviour
randomRandom among available agents
oldest_call_startAgent idle longest since their last call started
oldest_call_finishAgent idle longest since their last call ended
fewest_callsAgent with fewest calls this session
ring_allRings every available agent at once

oldest_call_finish distributes most evenly in practice. fewest_calls sounds fair but penalises agents who handle quick calls. ring_all gets fast pickup at the cost of agents racing each other.

Stage 5: Agent Assignment

Two places must agree, and this is where most “the call rings nowhere” reports come from.

  • Allow Inbound and Blended: Y
  • The in-group ticked under Allowed Inbound Groups

Then the agent, at login, must actually select the in-group. If they log into a campaign without selecting it, they will not receive calls from it no matter how the rest is configured.

For agents who should always be on certain groups, set Agent Choose Ingroups to 0 on the user and define the groups centrally — that removes the per-login step and the mistakes that come with it.

Blended Campaigns

Blended means agents take inbound calls while outbound dialling continues in the background, with inbound given priority.

On the campaign:

  • Allow Inbound and Blended: Y
  • Dial Method: RATIO or ADAPT_HARD_LIMIT
  • Auto Dial Level: lower than a pure outbound campaign, because agents will be pulled away by inbound

The tension is real. Set the dial level too high and inbound callers queue while your agents are on outbound calls. Too low and agents sit idle between inbound calls. Watch the real time screen during a typical hour and adjust rather than calculating it.

Verifying the Chain

Place a test call with the CLI open. You want to see:

-- Executing [15551234567@trunkinbound:1] AGI("SIP/myprovider-0000001a", "agi-DID_route.agi")

Where it stops tells you the stage:

Confirm queue state directly:

SELECT campaign_id, user, status, closer_campaigns
FROM vicidial_live_agents
WHERE status IN ('READY','CLOSER');

If closer_campaigns does not contain your in-group for any agent, that is your answer.

After-Hours Routing

Route by time of day at the dialplan level before the AGI sees the call:

[trunkinbound]
exten => _X.,1,GotoIfTime(09:00-17:00,mon-fri,*,*?open,1)
exten => _X.,n,Goto(closed,1)

exten => open,1,AGI(agi-DID_route.agi)
exten => open,n,Hangup()

exten => closed,1,Answer()
exten => closed,n,Playback(office-closed)
exten => closed,n,Voicemail(2000@default,u)
exten => closed,n,Hangup()

GotoIfTime uses the server’s timezone, so confirm that matches your business hours before trusting it.

Tags:

agi-DID_routeblendedcall routingdidinboundingroupqueuevicidial
Author

raghavan

Follow Me
Other Articles
Two parallel signalling rails converging at endpoints, representing chan_sip and PJSIP running side by side.
Previous

PJSIP Trunks in VICIdial: A Working Asterisk 18 Configuration

Measurement ruler over a row of character cells, marking a substring offset and length.
Next

Asterisk Variable Manipulation: Substrings, Math and Caller ID Rewriting

No Comment! Be the first one.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

About This Site

Vicidial, Asterisk, GoAutoDial and FreePBX tutorials — with practical guides to AI answering machine detection and AI agent integration.

Search

Recent Posts

  • AI Answering Machine Detection for VICIdial: Integrating VM Hunter
  • Piping VICIdial Call Recordings Into a Speech-to-Text Workflow
  • Fixing ‘Extension s Rejected Because Extension Not Found’ on Inbound Calls
  • Connecting FreePBX to VICIdial Over a SIP Trunk
  • Asterisk Variable Manipulation: Substrings, Math and Caller ID Rewriting

ViciDial AI

Vicidial, Asterisk, GoAutoDial and FreePBX tutorials — with practical guides to AI answering machine detection and AI agent integration.

Recent Posts

  • AI Answering Machine Detection for VICIdial: Integrating VM Hunter
  • Piping VICIdial Call Recordings Into a Speech-to-Text Workflow
  • Fixing ‘Extension s Rejected Because Extension Not Found’ on Inbound Calls
  • Connecting FreePBX to VICIdial Over a SIP Trunk
  • Asterisk Variable Manipulation: Substrings, Math and Caller ID Rewriting

Archives

  • June 2025 (1)
  • April 2024 (1)
  • January 2024 (1)
  • December 2023 (1)
  • October 2023 (1)
  • September 2023 (1)
  • August 2023 (1)
  • June 2023 (1)
  • May 2023 (1)
  • March 2023 (1)
  • February 2023 (1)
  • December 2022 (1)
  • November 2022 (1)
  • October 2022 (1)
  • September 2022 (1)
  • August 2022 (1)
  • July 2022 (1)
  • June 2022 (1)
  • April 2022 (1)
  • March 2022 (1)

Find Us

Contact Us:

email: info@vicidialai.com

Copyright 2026 — ViciDial AI. All rights reserved. | Privacy Policy