This model applies to agent-initiated dialing. Originating a call from
the SDK with an explicit
trunkId bypasses ARS selection entirely.The resolution chain end to end
The resolver evaluates one dialed string in a fixed order:- COR check — is this agent’s class of restriction allowed to place this call type at all?
- ARS digit analysis — match the dialed string against the digit-analysis table to find a route pattern.
- Route pattern — walk the pattern’s preferences in order.
- FRL gating — skip any preference whose FRL is above the agent’s FRL.
- Digit manipulation and CPN — delete leading digits, prepend an insert string, pick the calling-party number.
- Trunk — send the INVITE on the chosen trunk.
Classes of restriction and call types
A class of restriction (COR) is a named record with acor_code, an
optional description, and a list of allowed call types. Agents are
assigned a COR on the Agent routing tab. A COR with no call types
listed grants nothing by that list.
The canonical call types used across the screen are:
Call type is stored as free text on the wire, so other values are
accepted, but the list above is what the console offers and what
digit-analysis entries are tagged with. The COR check compares the call
type on the matched digit-analysis entry against the agent’s COR, so a
destination is only as restricted as the entry that classifies it.
CORs can be toggled inactive rather than deleted.
Digit analysis: partitions, prefixes and digit windows
Each digit-analysis entry maps a dialed-string prefix to a route pattern. An entry carries:
Matching rule: the longest matching dialed-string prefix whose digit
count falls within
[min_digits, max_digits] wins, and the call routes
to that entry’s route pattern. Typical prefixes are the empty
catch-all, 0, 00, or 1.
The console validates the numeric fields when you save. partition_pgn
must be between 1 and 2000; min_digits between 0 and 28;
max_digits between 1 and 28; and max_digits must be greater than or
equal to min_digits. These bounds mirror the Avaya-style limit of
28-digit dial strings.
You cannot create a digit-analysis entry before at least one route
pattern exists — the screen blocks the New entry action and points you
at the Route patterns tab.
Route patterns and ordered trunk preferences
A route pattern is a named container: arp_code (for example
RP-1, RP-INTL), an optional description, an active flag, and an
ordered list of trunk preferences. The route-patterns table shows
each pattern’s preference count so you can spot patterns that were
created but never populated.
Each preference row holds:
The resolver walks preferences top-down and takes the first one the
agent is entitled to use. Ordering is therefore the mechanism for
least-cost routing and for overflow: put the cheapest or most preferred
carrier at the lowest
preference_no, and a fallback behind it.
Deleting a route pattern also deletes its preferences and any
digit-analysis entries that point at it, via foreign-key cascade. The
console confirms this before the delete. If you want to take a pattern
out of service without losing its digit analysis, clear the active
flag instead.
FRL gating
Every preference carries anfrl, and every agent carries an frl.
When the resolver reaches a preference, it compares the two and skips
the preference if the agent’s FRL is below the preference’s FRL. The
walk continues to the next preference.
This is how one route pattern serves agents with different
entitlements: the same dialed digits reach an expensive international
carrier for a high-FRL agent and fall through to a restricted or blocked
outcome for a low-FRL agent, with no separate digit-analysis table per
team.
Because gating happens per preference and not per pattern, an agent
whose FRL is below every preference in the matched pattern gets no
route at all — even though COR permitted the call type.
Digit manipulation and caller-ID selection
Once a preference is selected, the dialed string is rewritten before the INVITE goes out:- Delete
del_digitsleading digits from the dialed string. - Prepend
insert_digits.
outbound_cpn → preference cpn → trunk outbound_cpn
The first value present wins. Set the agent CPN when an individual must
present their own number, the preference CPN when the presented number
must vary by carrier, and the trunk CPN as the org-wide default. The
console offers your DIDs as choices when picking a CPN, so the value you
select is a number you actually control.
Per-agent entitlements
The Agent routing tab is where the chain binds to people. Each agent row carries a display name, an email, and three routing fields:
An agent with no COR assigned has no call-type grant to check against,
and an agent whose FRL is lower than every preference in the matched
pattern will not route. When a single agent reports “I can’t dial that
number” while the team can, these three fields are the first place to
look.
How a change reaches the engine
Every write from this screen lands in Postgres and re-hydrates the org’s ARS cache key (telequick:ars:<org>), which the engine’s
outbound resolver in mod_sip reads. Saves are live: you do not restart
or redeploy the engine to pick up a new digit-analysis entry, a
reordered preference, or a changed FRL.
The screen also exposes an explicit Re-sync to engine action in the
page header. Use it if you suspect the cached snapshot has drifted from
Postgres — for example after a direct database change made outside the
console, or after a cache flush. The re-sync rebuilds the snapshot for
the active org from the stored rows; it does not modify configuration.
Deletes propagate the same way. When you remove a digit-analysis entry,
the engine stops routing that dialed-string prefix once the snapshot is
rewritten.
Related
- Telemetry — the
trunklabel on call metrics tells you which preference actually won - Telephony Metrics — ASR and PDD per trunk, for judging preference order