A screen pop rule takes a call that the CTI layer has just delivered to an agent and opens a URL for that agent — a CRM contact record, an order lookup, an internal page. Each rule stores the match conditions (ANI, DNIS, direction, trunk), the event it fires on, an action, a render surface, and a URL template whose {{token}} placeholders are substituted with the call’s own values. Rules live in the screen_pop_rule table, one set per org, and are managed from Admin → Screen pop in the TeleQuick agent suite.

How a rule is matched

When a call reaches the delivered or established state, the rule set for the org is evaluated. A rule matches only if all four of its conditions hold for that call: In addition, the rule’s trigger_event must equal the event being processed, and the rule must be active. Inactive rules are never matched; they are kept so that you can stage a rule before turning it on, and they are hidden from the console list unless you check Include inactive. Only one rule pops per event: the first match wins. The remaining rules are not evaluated once a match is found.

Pattern grammar and priority order

ani_pattern, dnis_pattern, and trunk_pattern are globs. * matches anything, which makes * the “don’t care” value for that field. All three default to * in the form, and an empty input is stored as * rather than as an empty string — a blank pattern field can never accidentally narrow a rule. direction is not a glob. It is one of three literal values: priority is an integer between 0 and 10000 and decides which rule is consulted first. Give every rule a distinct priority. Two rules that can match the same call at the same priority leave the outcome dependent on the tie-break, and the console shows you nothing but the Prio column — there is no visible secondary ordering to reason about. The console lists rules with the priority as the first column precisely so that the evaluation order is the thing you scan. A practical layout is: specific rules (one customer’s ANI, one DID) at low priority numbers, and a catch-all * → * rule as the last resort at a much higher number, with gaps in between so that you can insert rules later without renumbering.

Trigger events: delivered vs established

trigger_event pins the rule to exactly one point in the call’s lifecycle. A rule fires on one event, not both. If you want the record on screen at ring time and a second surface after answer, create two rules with the same patterns and different trigger_event values. See Routing events for the definitions of the delivered and established events themselves.

Action kinds and render surfaces

Two separate fields describe what happens. action classifies the kind of target; render names the surface the agent suite uses. action is one of: render is one of new_tab, iframe, modal, or side_panel, and selects where the agent suite puts the result — a new browser tab, an inline frame, a modal dialog over the agent’s current screen, or the suite’s side panel. url_template is validated the same way for every action value, so an internal or crm_webhook rule is still stored with (and still requires) a well-formed http/https template. url_template is nullable: if you clear the field, null is stored. title is an optional label — for example Customer — carried with the rule so the render surface can be captioned. It is stored as null when left blank.

URL template tokens and encoding

url_template is a plain http or https URL containing {{token}} placeholders. The supported tokens are: Substituted values are URL-encoded server-side. Do not pre-encode them and do not wrap a token in your own escaping — a + in an E.164 ANI is handled for you, and double-encoding is the usual cause of a CRM lookup that returns “no such contact” for a number that plainly exists. Whitespace inside the braces is tolerated: {{ani}} and {{ ani }} are both recognised as tokens. A typical template:
Tokens may appear in the path as well as the query string, and a template with no tokens at all is valid — it pops the same static page for every matching call.

Managing rules from the console

The screen is a thin CRUD surface over four procedures: The Active checkbox only appears when editing an existing rule, because create does not accept it. To stage a rule as inactive, create it and then open it again and clear Active. The search box filters on rule name and pattern, so you can find every rule that mentions a particular DID by pasting the number in. Typing in the search box or toggling Include inactive resets you to the first page.

Field reference

Testing and common failures

Validation is reveal-on-save: the form does not mark anything red while you type, and shows field errors only after you press Save with an invalid value.
  • “Name is required.” name is trimmed before saving, so a name of only spaces is rejected.
  • “Priority must be a whole number.” Clearing the priority input leaves the controlled number field as NaN, not 0. Retype a value. Values outside 0–10000 are rejected the same way.
  • Invalid URL template. The template is validated after its {{token}} placeholders are substituted, so https://crm.example.com/c?p={{ani}} passes. A template with a scheme other than http or https, or one that is malformed once tokens are removed, fails.
  • The rule never pops. Check, in order: the rule is active; its trigger_event matches the event you expect (a delivered rule will not fire on answer); direction is not narrower than the traffic; and no higher-precedence rule with a catch-all * → * pattern is matching first.
  • The wrong rule pops. Two rules that both match at the same priority. Give them distinct priorities and re-test.
  • The CRM lookup misses. Confirm you are not encoding token values yourself. Substitution is URL-encoded for you.
Save errors from the server are surfaced twice: inline under the form buttons and as a toast.
  • Routing events — the delivered and established events that rules trigger on
  • Telemetry — ANI, DNIS, trunk, and call id as they appear in CDRs