vicigeeksimple guides
Browse
All guides

Automate tasks · Integration boundaries

VICIdial webhooks and events: Call URLs, Agent Events Push, CORS, WebSockets and SSE boundaries

Build idempotent integrations around documented VICIdial extension points without calling browser events a transactional webhook stream.

Reader setup

Before you evaluate

  1. A running VICIdial deployment plus an allowlisted HTTPS receiver you control
  2. Synthetic event data
  3. Permission to disable the test URL or restore the prior integration configuration
Expected result
A bounded, idempotent integration design.
Before making changes
Do not expose secrets in URLs or use a wildcard CORS origin.

Use the right extension point and design for imperfect delivery

Choose one event and one destination for a test. Send a synthetic event twice and record whether the receiver stores one result, then stop the receiver and observe what the agent sees.

Fast answer: Call URLs are call-triggered URL integrations, Agent Events Push is browser-side event delivery that often needs a reviewed relay, Cross-Origin Resource Sharing (CORS) is a browser permission boundary, and custom WebSocket hooks are in-app code extension points—not a managed durable message bus. Server-sent events (SSE) are not documented here as a native VICIdial event transport.

Assume events can be duplicated, delayed, reordered or missing, especially around browser close. This article assumes an allowlisted HTTPS receiver and synthetic test data; it does not promise exactly-once delivery, endorse a relay product or claim a deployed integration.

This article assumes the reader already knows “agent” as VICIdial uses it; the companion article “VICIdial terminology for complete beginners: users, phones, campaigns and leads” covers that and the rest of the platform's vocabulary.

  • Before starting, prepare an HTTPS receiver you control, a fictional test record and the steps for disabling the integration.
  • Non-goal: do not treat browser events as a complete audit trail or native SSE stream.
  • Define a reconciliation path for missed terminal events.
Trace path · read left to right
01Agent browser02Reviewed relay03Idempotent integration
Reference screenshots 3 images

Reference capture

Reference screens from the demo

Captured on an isolated VICIdial demo: Administration screens on September 24, 2026, and the idle Agent screen on August 11, 2026. Each caption states its own capture time, and every sanitized image helps you recognize a related screen; none proves that this article's call, command, or result occurred.
Step 1 · Find Scripts

Open the script workspace

Open to enlarge
Sanitized VICIdial Scripts Listings page showing where agent-visible scripts are managed
Captured September 24, 2026 at 21:53:14 UTC on the authorized isolated demo.
Capture detailsNo scripts are defined for the fixture account, so the listing is empty. It does not show a script execution, CRM exchange, or call result.
Step 2 · Locate URL overrides

Check list-level form and URL fields

Open to enlarge
Sanitized VICIdial list detail page showing list state, reset, time, script, and URL override settings
Captured August 11, 2026 at 16:21:03 UTC on the authorized isolated demo.
Capture detailsThis is list configuration rather than a lead record; it contains no customer row and does not prove a dialing or import result.
Step 3 · See the Agent-side surface

Recognize where the agent sees the workflow

Open to enlarge
Sanitized logged-in VICIdial Agent screen in an idle no-live-call state with blank customer fields
Captured August 11, 2026 at 16:25:04 UTC on the authorized isolated demo.
Capture detailsThis is a real logged-in idle Agent screen with session and system identifiers redacted. Customer fields are blank, and it does not prove a placed, answered, recorded, transferred, or completed call.

Call URLs: explicit destination, encoding and data minimization

VICIdial's Call URL features are covered in full in the companion article “VICIdial Call URLs: trigger an external system on call events,” including the `VAR` prefix and the `--A--field--B--` substitution syntax; this section only places Call URLs among the other extension points below. Confirm which trigger applies to inbound, outbound or manual calls, and whether the request is browser- or server-originated, before relying on it.

Allowlist the HTTPS receiver, encode every inserted value, avoid reusable secrets in a URL, and authenticate using a reviewed scheme. The receiver should validate schema and deduplicate repeats; handle distinct events that arrive out of order separately.

  • Send a fictional record with no customer information and inspect the receiver’s response.
  • Do not place customer data in URL logs.
  • Document timeout and receiver-failure behavior.

Agent Events Push: browser-originated, not an audit log

Two System Settings control this feature: Agent Push Events enables it system-wide and defaults to 0 (disabled), and Agent Push URL is where enabled events are sent, built from `--A--user--B--`, `--A--event--B--`, `--A--message--B--`, `--A--lead_id--B--` and `--A--counter--B--`. Because the request fires from the Agent screen's own browser-side AJAX, the target must be local to the web server — reach an external receiver through the shipped `get2post.php` relay, never by pointing Agent Push URL at another host directly. Browser shutdown can also prevent a final logout event, so consumer state must be reconciled against an authoritative read path rather than inferred from event order.

Use stable event/call/agent correlation fields where available, timestamp receipt and source separately, deduplicate within a bounded window, and queue retries without turning a transient receiver outage into a browser reconnect storm.

For a browser-event relay, choose an identity before enabling writes. One reviewed design is (source,agent,session_generation,event,counter), with a canonical payload digest stored beside the receipt. session_generation must come from an authenticated association with the actual current session; it is not one of the five native URL variables. A receiver cannot safely invent it from lead_id or receipt time.

If the adapter cannot establish a stable session generation, do not automate a business write from this stream. Keep it observational and use a separately identified server event or an authoritative read. Counters can repeat after a new session; a lead can also have several distinct events.

Reconciliation uses the installation’s approved read-only agent_status/session source. Compare its current session/state at the workflow’s documented freshness interval and after reconnect or missing logout. Keep received event history; do not overwrite the authoritative current state with a late event from an old session.

Before you use it
This mirrors AGENT_EVENTS_PUSH.txt's own System Settings names and variable list; it is not a live configuration.
Agent Push Events and URL settings
Agent Push Events = 0   # System Settings; 0 disabled (default), 1 enabledAgent Push URL = <AGC_SCRIPT>?user=--A--user--B--&event=--A--event--B--&message=--A--message--B--&lead_id=--A--lead_id--B--&counter=--A--counter--B-- Event names actually documented (partial list):logged_instate_readycall_deaddispo_setlogged_out_complete   # may not trigger reliably; agent can close the browser first
Not executed · worksheet or reference text

This sample is a template or reading aid, not a terminal command. There is no output to show.

Success looks like
You can name both settings, list the five URL variables, and can point to at least one event your integration must reconcile rather than trust blindly (`logged_out_complete`).
Stop if
If your build's System Settings uses different labels, confirm the installed version's Agent Events Push documentation before wiring a receiver.
Fictional receipt decisions after trusted session associationScroll sideways to compare columns
InputIdentity relationReceiver action
sessionS1/eventdispo_set/counter21 with payloadPNew identityCommit receipt, then acknowledge; schedule separately idempotent work.
Same S1/dispo_set/21 and sameP againExact replayReturn duplicate; do not run a second business write.
Same S1/dispo_set/21 but changedPIdentity conflictQuarantine/review correction policy; do not overwrite silently.
S1/dispo_set/counter22Different event identityRetain separately even when lead_id is unchanged.
Late S1 logged_out after snapshot says currentS2 PAUSEDOld-session eventRetain history; current-state read wins.
Counter21 with unknown session generationIdentity unprovenObservation only; no automated write.

Reproduce durable receipt/replay/conflict handling locally

Prepare a protected read-only API check

CORS is a narrow browser allowlist

CORS support adds seven configurable variables to `agc/options.php` for Agent scripts, and the same seven to `vicidial/options.php` for four Admin scripts only — `non_agent_api.php`, `vdremote.php`, `AST_timeonVDADall.php` and `nanpa_type.php`: `$CORS_allowed_origin`, `$CORS_allowed_methods`, `$CORS_affected_scripts`, `$CORS_allowed_headers`, `$CORS_allowed_credentials`, `$Xframe_options` and `$CORS_debug`.

CORS_SUPPORT.txt itself warns against setting `$CORS_allowed_origin` to a wildcard, because that lets any website use your webserver's resources from any browser window, iframe or hidden span. Permit explicit HTTPS origins and the minimal methods and headers your integration actually needs, and enable `$CORS_allowed_credentials` only when strictly required.

Test preflight, authenticated and same-origin requests after changing any CORS option, and turn `$CORS_debug` back off once satisfied — CORS_SUPPORT.txt notes it can generate a large `CORSdebug_log.txt`.

Before you use it
Run as root; this only lists filenames and permissions under the agent web directory.
Check whether Agent CORS/WebSocket config files exist yet
ls -l /srv/www/htdocs/agc/options*.php
Evidence · ViciBox 12 demo capture

Captured demo response · 2026-09-23 21:35 UTC. Any filtering, hidden values or test-only data are identified in the capture label. Select Replay transcript to read the recorded output.

Command output line: ls -l /srv/www/htdocs/agc/options*.php
-rwxr-xr-x 1 root root 10471 Feb 10 2026 /srv/www/htdocs/agc/options-example.php
Success looks like
The listing shows which matching files exist and their permissions. It does not prove whether CORS or hooks are active; inspect the relevant configuration and test the behavior separately.
Stop if
If neither file exists, this build's `agc` directory differs from a stock install — locate the actual options file before changing CORS or WebSocket settings.
  • List exact origins; do not use *.
  • From an allowed origin and a denied origin, test the same credentialed request; record whether each receives protected content.
  • After an update or proxy change, repeat the allowed-origin, denied-origin and receiver-unavailable tests.

Keep WebSocket hooks and SSE in their proper boundary

WEBSOCKETS_SUPPORT.txt documents five insertion points in the same `agc/options.php` file: `$INSERT_head_script` (loaded just above the agent screen's main script tag), `$INSERT_head_js` (after the first JavaScript function), `$INSERT_first_onload` and `$INSERT_window_onload` (the start and end of the page's onload handler), and `$INSERT_agent_events` (inside the function that also drives Agent Events Push). Review whatever you insert there as application code: content security, dependency pinning, authentication, reconnect backoff, browser compatibility and failure isolation all belong in the release plan.

The doc's own worked example passes a WebSocket application's connection details to the agent screen through a custom login-URL variable — a pattern that, in that same example, sits next to the agent's login password in the query string. Treat that as a cautionary illustration, not a template: never place a phone-login password, an agent password, or any other secret in a URL, a browser history entry, or a bookmark, no matter which VICIdial screen it targets.

SSE may be a useful downstream delivery choice for your own relay-to-dashboard path, but it is not evidence of a native VICIdial SSE event feed. Keep it behind a service that authenticates subscribers, redacts sensitive fields and can replay from an owned durable store.

Before you use it
Run as root; `options-example.php` is the shipped template, never the active config, so this is read-only regardless of whether CORS or WebSockets are enabled on this build.
Read the shipped options template for CORS and WebSocket hooks
grep -n 'CORS_\|INSERT_' /srv/www/htdocs/agc/options-example.php
Evidence · ViciBox 12 demo capture

Captured demo response · 2026-09-23 21:35 UTC. Any filtering, hidden values or test-only data are identified in the capture label. Select Replay transcript to read the recorded output.

Command output line: grep -n 'CORS_\|INSERT_' /srv/www/htdocs/agc/options-example.php
16:# 180223-1657 - Added $INSERT_ variables
17:# 180425-2035 - Added #INSERT_first_onload variable
26:# 220916-0901 - Added INSERT_before_body_close option, Issue #1375
111:$INSERT_head_script = ''; # inserted right above the <script language="Javascript"> line after logging in
112:$INSERT_head_js = ''; # inserted after first javascript function
113:$INSERT_first_onload = ''; # inserted at the beginning of the first section of the onload function
114:$INSERT_window_onload = ''; # inserted at the end of the onload function
115:$INSERT_agent_events = ''; # inserted within the agent_events function
116:$INSERT_before_body_close = ''; # inserted before each BODY close tag
129:$CORS_allowed_origin = ''; # if multiple origins allowed, separate them by a pipe (also allows PHP preg syntax)
131:$CORS_allowed_methods = ''; # if multiple methods allowed, separate them by a comma
133:$CORS_affected_scripts = ''; # use '--ALL--' for all agc scripts. If multiple(but less than all) scripts affected, separate them by a space
135:$CORS_allowed_headers = ''; # passed in Access-Control-Allow-Headers http response header,
137:$CORS_allowed_credentials = 'N'; # 'Y' or 'N', whether to send credentials to browser or not
140:$CORS_debug = 0; # 0 = no, 1 = yes (default is no) This will generate a lot of log entries in a CORSdebug_log.txt file
Success looks like
You see every `$CORS_*` and `$INSERT_*` variable name at its default, commented-out value — the same list this article names above.
Stop if
If the file is missing, this build's `agc` directory differs from a stock install; locate the actual shipped template before copying it to `options.php`.
  • Do not expose agent credentials to custom JavaScript.
  • Cap reconnects and persistent-connection resource use.
  • Revalidate insertions after every VICIdial update.

Release with negative tests and reconciliation

Test receiver timeout, duplicate event, reordered event, missing logout, unauthorized origin, expired certificate and relay restart. Verify the agent screen remains usable when the integration is down; an integration must not block call handling unless that is a consciously designed and tested policy.

Stop deployment if the destination is not allowlisted, secrets appear in URLs/logs, CORS is broad, replay/deduplication is absent, or a browser outage causes uncontrolled retries. Roll back the scoped URL/insert/CORS configuration through normal change control, then independently verify normal Agent behavior. Complete the CORS review below before any of those variables go live.

Before you use it
Replace only the example.test placeholder with an approved HTTPS origin, in a private review record, before a reviewer applies these as `$CORS_*` variables in `options.php`.
CORS review worksheet
CORS_allowed_origin = https://portal.example.testCORS_allowed_methods = [minimum required]CORS_affected_scripts = [minimum required, or --ALL-- for Agent scripts only]CORS_allowed_headers = [minimum required]CORS_allowed_credentials = NXframe_options = [N | SAMEORIGIN | DENY]CORS_debug = 0preflight_test = [pass or fail]
Not executed · worksheet or reference text

This sample is a template or reading aid, not a terminal command. There is no output to show.

Success looks like
One explicit origin and minimum access rules are independently tested, `CORS_debug` is off, and `CORS_allowed_credentials` is `N` unless a specific integration requires `Y`.
Stop if
Stop if the origin is wildcarded, untrusted, or preflight/authentication fails.
  • Keep an integration kill switch.
  • Monitor receiver latency, failures and queue depth with no PII payloads.
  • Reconcile aggregate event counts with an authorized source of truth.
  • Write the exact identity fields, canonical payload rule and duplicate-retention window; test a same-key/same-payload replay and same-key/different-payload conflict.
  • Demonstrate a new session reusing a counter and a late old-session logout; neither may erase the current authoritative snapshot.
  • If stable identity or the independent read is unavailable, keep business writes disabled and hand off the exact missing capability.

Checks and sources

What was checked

  • Source present: CALL_URL_FEATURES.txt, AGENT_EVENTS_PUSH.txt, CORS_SUPPORT.txt and WEBSOCKETS_SUPPORT.txt — VICIdial's own shipped documentation — define these extension points' settings, variables and events.
  • Configured/enabled/functionally verified: no external receiver, CORS origin or persistent connection is asserted as deployed or tested here.
  • AGENT_EVENTS_PUSH.txt states plainly that Agent Events Push is browser-driven and that consumers must tolerate loss, duplication and reordering; this article treats that as a design constraint, not a defect to route around.

Primary references

Sources

  1. VICIdial Call URL featuresVICIdial · accessed August 4, 2026
  2. VICIdial Agent Events PushVICIdial · accessed August 4, 2026
  3. VICIdial CORS supportVICIdial · accessed August 4, 2026
  4. VICIdial WebSockets supportVICIdial · accessed August 4, 2026
  5. Agent Events Push variables and browser boundaryVICIdial Group · accessed November 7, 2026

Follow without guesswork

Get the next article

RSS is live now. Email delivery below is an explicit local preview and sends nothing.Open the RSS feed
Email preview only. The address stays in this browser and is never transmitted.