In Preview mode, an agent pulls up (or is assigned) a contact record, reviews it on their screen, and then manually clicks Dial to place the call. An optional countdown timer can auto-dial the record after N seconds if the agent doesn't act. Preview is the only Genesys Cloud dialing mode where the agent sees the contact before the call is placed.
Because the agent is reserved before the number is dialed, there is effectively zero chance of call abandonment — the agent is already there waiting. This is why Preview is the go-to mode for high-value, compliance-sensitive, or manual-review campaigns.
| Setting | Notes |
|---|---|
| Script | Required. The agent sees this script during the preview and call. Must contain any custom screen-pop fields the agent needs to review. |
| Queue | Required. Determines which agents are eligible to receive preview records. |
| Contact List | Required. The pool of records that will be assigned to agents. |
| Edge Group | Required. The SIP path used when the call is actually placed. |
| Preview Time Seconds | Optional. 0 = agent must click Dial manually. Any positive number = auto-dials after that many seconds. Common values: 10–30 seconds. |
| Always Running | Optional. When true, the campaign auto-refills records as agents finish them. |
| Agent Owned Columns | Optional. Used with Precise Dialing to route specific records only to specific agents. |
| Call Analysis Response Set | NOT used in Preview. There's no call analysis because the agent places the call themselves and hears the full pre-connect audio (ringing, answer, voicemail) directly. |
| Compliance Abandon Rate | NOT applicable. No abandonment is possible in Preview. |
| No-Answer Timeout | NOT applicable. Preview is the only mode where this setting doesn't exist, because the agent controls the call lifecycle. |
Agentless mode runs an outbound campaign without any agents involved at all. When a contact answers, the call is routed into an outbound Architect flow — essentially an IVR that plays a message, collects digits, offers opt-outs, or does whatever the flow is programmed to do. The agent pool is irrelevant because no humans are waiting on the other end.
Instead of pacing based on agent availability, Agentless mode paces based on the number of outbound lines you allocate to the campaign. If you give it 20 lines, it will place 20 calls in parallel, and as each call finishes, a new one starts. Agentless is the mode you use for automated notifications, appointment reminders, survey invitations, payment reminders, and any broadcast-style outbound.
| Setting | Notes |
|---|---|
| Outbound Flow | Required. An Architect outbound call flow that runs on every answered call. This is where your IVR logic lives: prompts, menus, data collection, opt-outs. If the flow doesn't exist, the campaign cannot start. |
| Call Analysis Response Set | Required. Must include a Transfer to Flow response action. Agentless response sets cannot include Transfer to Agent actions — if you try to assign one, the campaign will reject it. |
| Lines | Required. The number of simultaneous outbound calls the campaign is allowed to place. Effectively the campaign's pacing knob. Shares from the total Edge group line pool. |
| Contact List | Required. The records to dial. |
| Edge Group | Required. Provides the SIP path. Edge group's total line pool is divided across all active campaigns. |
| No-Answer Timeout | Applicable. 15–60 seconds, default 30. How long a ringing call stays active before auto-disconnect. |
| Callable Time Sets | Strongly recommended. Enforces legal-hours calling windows per time zone. |
| DNC Lists | Strongly recommended. Prevents the campaign from dialing opted-out numbers. |
| Queue | Not used. No agents are involved. |
| Script | Not used. No agent is there to see a script. |
| Compliance Abandon Rate | Not applicable. There are no agents, so there's nothing to abandon. |
Predictive mode is Genesys Cloud's most aggressive and efficient automated dialing mode. A patented stage-based pacing algorithm watches what your agents are doing in real time — how long they spend on each call, how long wrap-up takes, how often calls connect — and uses those statistics to predict the exact moment each agent will become available. It then places calls before that moment, so that by the time the customer answers, an agent is just finishing their prior call and is ready to take the new one with minimal idle time.
This is dramatically more efficient than Progressive or Power mode, because agents aren't waiting for calls to be placed — the calls are already in flight. However, it also means the dialer sometimes places calls before an agent is actually available, and if no agent opens up by the time the customer answers, that call is abandoned. Predictive mode trades a small amount of abandon rate for a large increase in agent productivity.
| Setting | Notes |
|---|---|
| Script | Required. Must contain at least one Set Stage action. The stage-based pacing algorithm depends on these stage markers to measure how long agents spend in each phase of a call. No stages = no predictive pacing. This is the #1 setup mistake. |
| Queue | Required. The pool of agents who will receive connected calls. |
| Contact List | Required. The records to dial. |
| Call Analysis Response Set | Required. Must route live answers to an agent via Transfer to Agent. Typically also handles answering machines, busy signals, and SIT tones. |
| Edge Group | Required. Provides outbound lines. |
| Compliance Abandon Rate | Default 5.0%. Maximum percentage of calls that can be abandoned before the dialer self-throttles. Regulatory ceilings are typically 3% (UK Ofcom) or 5% (US TCPA interpretations) — set yours based on your jurisdiction. |
| Max Calls Per Agent | Default 15. How many parallel calls the dialer is allowed to have in flight per idle agent. Higher values = more aggressive pacing = higher productivity but higher abandon risk. |
| No-Answer Timeout | 15–60 seconds, default 30. How long a ringing call stays active before auto-disconnect. |
| Priority | When multiple campaigns share an Edge group's line pool, higher-priority campaigns get first allocation. |
| Outbound Line Count / Weight | How many lines this campaign gets from the Edge group's total pool. Can be fixed or weight-based. |
math. prefix that must be dropped), check against the built-in function reference, and report any problems. It will not execute the expression — this is a static analyzer.| Check | What it catches |
|---|---|
Balanced ( and ) | Missing or extra parentheses — the #1 cause of "expression invalid" errors. |
Balanced {{ and }} | Single curly braces, missing closing braces, or mismatched variable wrappers. |
| Balanced quotes | Unterminated string literals. |
| Known function names | Flags typos and unrecognized functions. Compares against the full built-in list. |
math. prefix | Flags math examples copied without dropping the math. prefix — a common mistake. |
| Boolean keywords | Warns when using && / || / ! where AND / OR / NOT are the documented keywords. |
| Variable syntax | Flags bare {Variable} with single braces instead of {{Variable}}. |
| Empty arguments | Detects empty function arguments like concat( , ). |
| Name | Role | Completed | Revealed | Total XP | Last login | |
|---|---|---|---|---|---|---|
| Loading roster… | ||||||
| Type | Description | Supports expressions? |
|---|---|---|
| Dynamic String ⚡ | Computed text value. Expression must return a string. Recalculates automatically when referenced variables change. | Yes — full expression body |
| Dynamic Number ⚡ | Computed numeric value. Expression must return a number. | Yes — full expression body |
| Dynamic Boolean ⚡ | Computed true/false. Expression must return a boolean. | Yes — full expression body |
| Basic Variable | String, Number, or True/False. Assigned via the Set Variable action — not computed continuously. | Partial — via Set Variable action only |
| List Variable | Stores multiple comma-separated values in one field. Cannot be dynamic. | No — use getIndexValue() or indexOf() inside a Dynamic var |
| Syntax / Variable | Description |
|---|---|
| {{VarName}} | Inserts the runtime value of any script variable. Always double curly braces. Never add spaces inside the braces. |
| {{Scripter.Agent Name}} | Logged-in agent's display name — read-only |
| {{Scripter.Agent Email}} | Agent's email address |
| {{Scripter.Agent ID}} | Agent's unique system identifier |
| {{Scripter.Interaction Id}} | Unique conversation ID — identical to conversationId in the REST API |
| {{Scripter.Customer Formatted Number}} | Customer's formatted phone number |
| {{Scripter.Interaction Type}} | Channel type: call, chat, email, callback, etc. |
| {{Scripter.Interaction State}} | Current state: alerting, connected, disconnected |
| {{Scripter.Customer Call Duration}} | How long the customer has been connected (raw duration string) |
| {{Scripter.Raw Customer Call Start Time}} | Raw call start time as a number in milliseconds — pass directly to formatDate(), no dateToMilliseconds() wrapper needed |
| {{Scripter.Raw Agent Call Start Time}} | Raw agent start time as a number in milliseconds — pass directly to formatDate() |
| {{Scripter.Queue Name}} | Name of the queue this interaction is in |
| {{Scripter.Queue ID}} | ID of the queue — useful for callback actions |
| {{Scripter.Script ID}} | ID of the current script |
| {{Scripter.Is Coaching}} | true if the agent is being coached on this interaction |
| {{Scripter.Is Barging}} | true if a supervisor is barging in on this interaction |
| {{Outbound.FirstName}} | Contact list first name (outbound campaigns) |
| {{Outbound.LastName}} | Contact list last name (outbound campaigns) |
| {{Outbound.Salutation}} | Contact list salutation — e.g. Mr., Ms., Dr. |
| Function | Example & Notes |
|---|---|
| concat(a,b,...) | concat({{FirstName}}, " ", {{LastName}}) — joins unlimited arguments left to right into one string |
| upper(s) | upper({{Status}}) — converts every letter to UPPERCASE |
| lower(s) | lower({{Input}}) — converts every letter to lowercase |
| trim(s) | trim({{CustomerInput}}) — removes leading and trailing whitespace only; middle spaces untouched |
| replace(s,find,rep) | replace({{PhoneNumber}},"-","") — replaces every occurrence; leave rep empty to delete |
| substring(s,start,end) | substring({{Phone}},0,3) — extracts by position; end position not included |
| slice(s,start,end) | slice({{Phone}},-4) — like substring but supports negative positions from the right end |
| substr(s,start,len) | substr({{Account}},0,4) — extracts by start position and character count (not end position) |
| indexOf(s,search) | indexOf({{FullName}},"Smith") — returns 0-based position; -1 if not found |
| length(s) | length({{Notes}}) — returns the character count as a number |
| Function / Operator | Example & Notes |
|---|---|
| ifElse(cond,t,f) | ifElse(equal({{Tier}},"Gold"),"VIP","Standard") — ternary branching function |
| equal(a,b) | equal({{Status}},"active") — strict type + value check; more reliable than == |
| ==, != | {{Status}} == "active" — value-only equality; can produce unexpected results with mixed types |
| <, >, <=, >= | {{Score}} >= 90 — numeric comparison operators |
| ? : | {{Score}} > 80 ? "Pass" : "Fail" — compact JavaScript-style ternary; alternative to ifElse() |
| AND | equal({{IsVIP}},true) AND {{Score}} >= 90 — both conditions must be true |
| OR | {{Type}} == "call" OR {{Type}} == "callback" — at least one condition must be true |
| NOT | NOT equal({{Status}},"closed") — inverts the result of a condition |
| Function | Example & Notes |
|---|---|
| match(s,pattern) | match({{ZipCode}},"^\\d{5}$") — in a Dynamic Boolean returns true/false; in a Dynamic String returns matched text |
| match(s,pat,flags) | match({{Name}},"smith","i") — use i flag for case-insensitive matching |
| match(s,pat,flags,group) | match({{Phone}},"^(\\d{3})", "", 1) — capture group: 0 = whole match, 1 = first () group |
| matchAll(s,pat,flags,idx) | matchAll({{Notes}},"\\d+","",1) — finds all matches; returns the one at index 1 (second match) |
| Pattern | What it validates |
|---|---|
| ^\d{5}$ | Exactly 5 digits — US ZIP code |
| ^\d{10}$ | Exactly 10 digits — phone number (no dashes or spaces) |
| ^[^@]+@[^@]+\.[^@]+$ | Basic email address format |
| ^\d+$ | Numbers only — any length |
| ^[a-zA-Z]+$ | Letters only — A–Z, no numbers or symbols |
| ^[a-zA-Z0-9]{8}$ | Exactly 8 letters or digits — common for account IDs |
| ^\d{1,4}$ | Between 1 and 4 digits — short codes or agent IDs |
| ^[A-Z]{2}\d{4}$ | 2 uppercase letters followed by 4 digits |
| ^\(\d{3}\) \d{3}-\d{4}$ | US phone in (555) 867-5309 format |
{{Scripter.Raw Customer Call Start Time}}) are already numbers in milliseconds — pass them directly to formatDate(), formatDateISO(), and formatLocaleDate() with no wrapper. The non-Raw variants (e.g. {{Scripter.Customer Call Start Time}}) are locale-formatted strings — those need dateToMilliseconds() wrapped around them first. Don't mix the two — wrapping a Raw variant in dateToMilliseconds() will fail because that function expects a string, not a number.| Function | Example & Notes |
|---|---|
| formatDate(ms) | formatDate({{Scripter.Raw Customer Call Start Time}}) — readable string in agent's timezone. Default output: 01/01/2000 12:00:00 am (+00:00). Pass the Raw variant directly, no wrapper. |
| formatDate(ms, fmt) | formatDate({{Scripter.Raw Customer Call Start Time}}, "MM/dd/yyyy") — custom format tokens: MM dd yyyy HH mm ss eeee MMMM |
| formatDateISO(ms) | formatDateISO({{Scripter.Raw Customer Call Start Time}}) — ISO 8601 output e.g. 1999-12-31T19:00:00-05:00; ideal for APIs |
| formatLocaleDate(ms) | formatLocaleDate({{Scripter.Raw Customer Call Start Time}}) — uses each agent's own system locale (US vs UK vs EU formats automatically) |
| dateToMilliseconds(s) | Converts a string date variable to ms. Use with the non-Raw variants — e.g. dateToMilliseconds({{Scripter.Customer Call Start Time}}). Don't use this with Raw variants — they're already numbers. |
| Add 5 minutes (Raw) | formatDate({{Scripter.Raw Customer Call Start Time}} + 5 * 60 * 1000) — Raw is a number, so you can do arithmetic on it directly |
| Compare two Raw dates | {{Scripter.Raw Customer Call Start Time}} > {{Scripter.Raw Agent Call Start Time}} — compare numerically, no conversion needed |
| Function | Example & Notes |
|---|---|
| formatDuration(ms) | formatDuration(durationToMilliseconds({{Scripter.Customer Call Duration}})) — readable e.g. 00:04:32 |
| durationToMilliseconds(d) | Converts a raw duration string into milliseconds. Use for comparisons or arithmetic. |
| Countdown timer | formatDuration(5*60*1000 - durationToMilliseconds({{Scripter.Customer Call Duration}})) — time remaining until 5-minute mark |
| Duration > threshold? | durationToMilliseconds({{Scripter.Customer Call Duration}}) > 300000 — true if call exceeds 5 minutes |
round(), floor(), ceil(), abs(), min(), max(), sqrt(), pow(), and mod() are called directly in Genesys Cloud expressions — no prefix needed.| Operator / Function | Example & Notes |
|---|---|
| +, -, *, / | {{CallCount}} + {{TransferCount}} — standard arithmetic operators |
| % (modulo) | {{Total}} % 2 — remainder after division; 0 = even, 1 = odd |
| ^ (power) | {{Base}} ^ 2 — raises to a power; e.g. 2^3 = 8 |
| round(n,places) | round({{Score}}, 2) — rounds to specified decimal places; 0 = whole number |
| abs(n) | abs({{ScoreDelta}}) — absolute value; removes the negative sign |
| min(a,b) | min({{WaitTime}}, 300000) — returns the smaller of the two values |
| max(a,b) | max({{WaitTime}}, 0) — returns the larger of the two values |
| floor(n) | floor({{Score}}) — rounds down to nearest whole number |
| ceil(n) | ceil({{Score}}) — rounds up to nearest whole number |
| length(s) | length({{AccountNumber}}) — number of characters in a string (result is a number) |
| indexOf(s,v) | indexOf({{FullName}},"Smith") — 0-based position; -1 if not found (result is a number) |
| Operation | Example & Notes |
|---|---|
| getIndexValue(list,idx) | getIndexValue({{OptionsList}}, 0) — retrieves item at position; 0 = first item. Error if index out of range. Use in a Dynamic String. |
| indexOf(list,value) | indexOf({{OptionsList}}, "Gold") — finds position of a value; returns -1 if not found. Use in a Dynamic Number. |
| Push (Set Variable) | No expression syntax — use the Set Variable action in the script editor, choose Push to append a value to the end of the list. |
| Rule | Detail |
|---|---|
| Parentheses first | Use parentheses to control evaluation order. e.g. ({{A}} + {{B}}) * {{C}} |
| Last value assigned | In multi-line expressions, the value of the last evaluated line is assigned to the dynamic variable. |
| Type must match | Dynamic String → must return text. Dynamic Number → must return a number. Dynamic Boolean → must return true/false. Mismatches cause runtime errors. |
| equal() vs == | equal() checks both value AND type. == checks value only and can give unexpected results with mixed types. Use equal() for reliable comparisons. |
| Numeric functions | Functions like round(), floor(), ceil(), abs(), min(), max(), sqrt(), pow(), and mod() are called directly with no prefix. |
| Raw date variables | Scripter.Raw ... date variants are already numbers in milliseconds — pass them directly to formatDate(). The non-Raw variants are locale-formatted strings and need dateToMilliseconds() first. Don't mix the two. |
| Semicolons or newlines | Multiple expressions can be separated by semicolons or newlines. The last one evaluated is what gets assigned to the variable. |
| Nested functions | Functions can be chained by nesting — upper(trim({{Var}})). The innermost function always runs first and passes its result to the outer function. |
| Input/Output limits | Dynamic variables cannot be used as Input or Output variables. Use Basic variables for variables that need to be passed in from Architect or written to the conversation object. |