Reader setup
Before you start
- A VICIdial test campaign and synthetic lead, plus a CRM sandbox or dedicated test tenant
- A least-privilege integration account approved by both system owners
- A private mapping of fictional VICIdial lead ID to an existing synthetic Salesforce Contact ID, expected fictional names and sandbox owner
- Expected result
- Map a synthetic VICIdial lead to an existing Salesforce sandbox Contact, perform one authorized read and compare the returned record to the mapping; evaluate native hooks separately before any integration.
- Before making changes
- Never test against a production CRM with real leads. Do not place VICIdial, Salesforce or Vtiger credentials in JavaScript, query strings, browser bookmarks or shared screenshots.
01 / 07
VICIdial's own CRM hooks, before any custom integration
Begin with one fictional CRM contact and one test lead. Record the two IDs and expected name in a private mapping. The worked sandbox request below checks the CRM record only; test any native hook separately before claiming delivery.
Before building anything, check what VICIdial already does for you. CRM Popup Login/Address opens a new window on agent login to a campaign, populated the same way as a web form: begin the address with the literal three letters VAR, then use --A--user_custom_one--B-- (and the four other user_custom fields) to carry your own correlation values straight into the CRM's URL. The field lives on the campaign's own detail screen, under the top-level Campaigns menu — not under Admin.
Web Form, Start Call URL and Dispo Call URL trigger at different points; the documented substitutions are feature-specific. The upstream CALL_URL_FEATURES reference explicitly warns that not all variables are available for every feature. Confirm each field on the installed revision with synthetic values. The generic Call URL mechanism is separate from a Vtiger-specific connector or API integration.
These native fields need no server-side integration service and no VICIdial credentials outside VICIdial itself: VICIdial substitutes the variables and delivers the finished address on its own, whether that means the webserver calling it directly or the agent's browser opening it as a window. That is why they come first, not the small integration service in the rest of this article.
Two more shipped details matter once you go beyond the basic address. CALL_URL_FEATURES.txt documents &CF_uses_custom_fields=Y for the Web Form address specifically: append it to the query string or a custom list field never resolves; CRM Popup Address is "populated just like the web form address," so the same parameter is worth trying there too, but confirm it on your build before relying on it. The same documentation describes LOCALFQDN for the web form URL when agents reach the agent screen through more than one network path: it lets VICIdial rewrite the address per agent to whichever hostname that agent actually used to log in, instead of a fixed one baked into the field, so one saved URL keeps working across every segment.
If a field the CRM expects is sometimes blank on the VICIdial side, a DISPO_FILTER Settings Container can substitute a replacement value before the Dispo Call URL fires — CALL_URL_FEATURES.txt gives replacing a blank state field with a fixed placeholder as its own worked example. That is a VICIdial-side data-hygiene option worth knowing before your field map assumes the CRM has to absorb every blank field itself.
- Before you use it
- Set this on the campaign's CRM Popup Address field only after CRM Popup Login is Y, and confirm the field is reachable on your build's campaign detail screen — exact labels can drift by revision.
VARhttps://<CRM_HOST>/login?user=--A--user_custom_one--B--&campaign=--A--campaign--B--This sample is a template or reading aid, not a terminal command. There is no output to show.
- Success looks like
- On the agent's next login to this campaign, VICIdial opens this address in a new window with --A--user_custom_one--B-- and --A--campaign--B-- already substituted for that agent's real values.
- Stop if
- If the window is blank, check the actual URL and substituted test values, the receiving CRM page, browser popup settings and network access before changing the VICIdial field.
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.Open the script workspace
Open to enlargeCapture details
No scripts are defined for the fixture account, so the listing is empty. It does not show a script execution, CRM exchange, or call result.Check list-level form and URL fields
Open to enlargeCapture details
This is list configuration rather than a lead record; it contains no customer row and does not prove a dialing or import result.Recognize where the agent sees the workflow
Open to enlargeCapture details
This 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.02 / 07
Choose one direction and one owner for every field
Start with one narrow flow: CRM sandbox contact → VICIdial test lead, or completed VICIdial test disposition → CRM sandbox activity. Avoid bidirectional sync until a single direction is reliable, because two systems writing the same phone number or status creates silent overwrite and duplicate problems.
Write a field map: internal correlation ID, source record ID, display name, approved test phone field, disposition and last-update timestamp. Define the owner for each field. A CRM is not automatically the source of truth just because an agent sees it first. VICIdial's own vendor_lead_code field — part of the same available-fields list the Call URLs draw from — is usually the safer join key than a phone number, since it exists specifically to hold an external system's identifier.
The native fields above already answer part of this decision: a Dispo Call URL is VICIdial-to-CRM only, so if that direction and that trigger point covers your need, you may not need the rest of this article's integration service at all. Reach for a custom service only for what native fields cannot cover — reading CRM data into VICIdial, running on a schedule, or reacting to something other than login, call-start or disposition.
03 / 07
Use the VICIdial API boundary, not direct browser automation
Native Call URL fields are one-directional and event-triggered: VICIdial calls out when something happens and stops there. They cannot pull a CRM record into VICIdial, run on a schedule, or perform an arbitrary read or write beyond what a single event fires. That gap — not a shortcoming of the native fields, just the edge of what a fire-and-forget URL can do — is what the rest of this article's integration service is for.
VICIdial documents an Agent API for controlling an already logged-in agent session and a Non-Agent API for work outside the interactive agent screen. Read the API file from the exact VICIdial version installed in your lab; available functions and authorization settings are version-dependent.
Put API calls in a server-side integration service. It should authenticate to VICIdial and the CRM with dedicated least-privilege accounts, redact logs, rate-limit retries and keep an audit record. Do not embed secrets into an agent web form or have a browser call a privileged API directly.
04 / 07
Guided example: make a harmless outbound test payload
This object is deliberately generic. It is a local contract between your integration service and a CRM sandbox; it is not a direct call to either vendor and uses no real contact data.
- Before you use it
- Use only synthetic IDs and a CRM sandbox record created for this guide.
const event = { eventId: 'lab-vici-001', source: 'vicidial-lab', action: 'disposition_review', vicidialLeadId: 'TEST-001', crmRecordId: 'SANDBOX-001', disposition: 'TEST_ONLY', occurredAt: new Date().toISOString()};This sample is a template or reading aid, not a terminal command. There is no output to show.
- Success looks like
- The event has a stable test ID. Replay is safe only after the receiver checks that ID and prevents duplicate actions.
- Stop if
- Stop if an event contains a real phone number, customer name, recording link or production record ID.
05 / 07
Read one correlated synthetic Salesforce sandbox record
A sandbox administrator supplies an authorized OAuth token, sandbox instance URL, API version and an existing synthetic Contact ID. Record the mapping from the fictional VICIdial lead ID to that Contact ID in the test worksheet. This example only reads; it does not create or update a record.
Use a server-side environment with least-privilege access and a secret store. Confirm the instance is the intended sandbox before issuing a request. Do not put tokens or personal data in screenshots or logs.
- Have the sandbox owner create or identify one synthetic Contact and provide its ID. Record the corresponding fictional VICIdial lead ID and expected fictional name.
- Run the read-only request, compare returned Id and names with the worksheet, and record pass or failure without saving secrets.
- Ask the owner to retire the synthetic Contact according to sandbox policy. No write or deletion is performed by this request.
- Before you use it
- Use only an authorized sandbox token and an existing fictional Contact; keep the response and token private.
# Set these in the authorized test environment: sandbox instance, API version, token and synthetic Contact ID.# Confirm the instance hostname and Contact ID against the sandbox worksheet first.curl --fail-with-body --silent --show-error \ "$SALESFORCE_SANDBOX_INSTANCE/services/data/$SALESFORCE_API_VERSION/sobjects/Contact/$SYNTHETIC_CONTACT_ID?fields=Id,FirstName,LastName" \ -H "Authorization: Bearer $SALESFORCE_ACCESS_TOKEN" \ -H "Accept: application/json"This example has no recorded result here. Follow its preparation, expected result and stop conditions before using it.
- Success looks like
- HTTP success returns the mapped synthetic Contact ID and expected fictional names. Compare them with the lead-to-contact worksheet; a match establishes this one read, not an end-to-end integration.
- Stop if
- Stop on 401/403, 404, an unexpected ID or non-sandbox hostname. Check permissions, API version and mapping with the sandbox owner; do not widen access blindly.
06 / 07
Apply the same boundary to Vtiger
Use Vtiger’s documented REST API and its supported authentication method for the deployed edition. Create a sandbox test record, read it, then create one clearly labeled test note or activity. Confirm API names, editions and permissions in the administrator’s current Vtiger documentation; do not rely on an old forum snippet as a schema contract.
If you use webhooks or polling, make delivery idempotent: retain the source event ID and refuse to create the same CRM activity twice. A network timeout does not prove the CRM did not receive the first request.
The same one-directional-versus-full-API distinction applies here: Vtiger's REST API can be polled or pushed to from your integration service, but VICIdial has no native Vtiger-specific hook. Every Vtiger touchpoint in this guide goes through the API boundary above, not a Call URL field.
07 / 07
Verify IDs, permissions and deletion before expanding
For the read-only example, record the fictional VICIdial lead ID, sandbox Contact ID, request time, HTTP status and whether the returned ID and names match the private mapping. This confirms one CRM read, not event delivery, duplicate handling or unrelated-record access controls. Test those separately if the approved integration needs them.
The worked read does not change the Contact or campaign. If a separate authorized hook test changed campaign fields, restore the exact before-values and reopen the campaign; have the sandbox owner retire synthetic records and test accounts under the agreed procedure.
Before testing, record the existing CRM Popup and Call URL values privately. To roll back, restore those exact values and reopen the campaign to check them; then remove the test record and account through the sandbox cleanup process.
Log the CRM's own rate-limit or API-usage response alongside your test record. Both Salesforce and Vtiger meter API calls per organization or per license; a test loop that ignores that limit can degrade a shared sandbox for other teams, which is exactly the kind of blast radius a lab exercise is supposed to avoid.
- The field map identifies one source system and one update direction for each field.
- Test credentials stay in server-side storage, and the test account cannot access unrelated CRM records.
- Find the test record and its matching integration log by test ID; confirm the documented deletion process covers both.
- If you roll back, restore the previously recorded CRM Popup and Call URL settings, then reopen the campaign to check them.
Checks and sources
What was checked
- CALL_URL_FEATURES.txt documents CRM Popup Login/Address, Web Form, Start Call URL and Dispo Call URL as VICIdial's own event-triggered hand-off to a CRM, all using the same --A--field--B-- substitution and the user_custom_one..five fields as the rest of the Call URL family.
- CALL_URL_FEATURES.txt states explicitly that the Start Call URL does not fire for manual-dial calls — a documented limit to design the test around, not a bug to chase.
- VICIdial’s documentation distinguishes the Agent API from the Non-Agent API; administrators must confirm functions in the documentation shipped with their installed version.
- Salesforce documents OAuth authorization for API access and a limits endpoint suitable for a low-impact connectivity check.
- Vtiger edition, authentication and object names vary; this article intentionally directs readers to the current official Vtiger documentation rather than asserting a universal endpoint.
Primary references
Sources
- VICIdial Call URL featuresVICIdial · accessed September 23, 2026
- VICIdial Agent APIVICIdial · accessed September 23, 2026
- VICIdial Non-Agent APIVICIdial · accessed September 23, 2026
- Salesforce OAuth and Connect REST APISalesforce · accessed September 23, 2026
- Vtiger developer documentationVtiger · accessed September 23, 2026
- Get Records Using sObject RowsSalesforce Developers · accessed 2026-11-07


