How to Call the VICIdial API From Your App (PHP, Python, Node)
The VICIdial Non-Agent and Agent APIs are plain HTTP GET requests — here is how to call them correctly from PHP, Python, and Node.js with real examples.
The VICIdial API — both the Non-Agent API for data operations Non-agent API and the Agent API for controlling live sessions Agent API — is a plain HTTP GET interface. There is no SDK, no client library to install. Your application builds a URL with parameters in the query string and reads a plain-text response. Any language that can make an HTTP request can talk to it. The differences between PHP, Python, and Node come down to which HTTP library you use and how each language handles URL encoding.
Auth and the source parameter
Every call passes user and pass in the query string. For the Non-Agent API API (application programming interface), the account needs modify_leads set to 1 and user level 8 or higher. For the Agent API, a standard agent account (level 1) works for functions targeting that agent's own session. Always pass a source parameter — a short label for your app (up to 20 chars). It appears in VICIdial's API log and is the fastest way to find your calls when debugging.
Request and response flow
sequenceDiagram
participant App as Your App
participant API as non_agent_api.php
participant DB as VICIdial DB
App->>API: GET with user pass function and params
API->>API: validate user permissions
API->>DB: execute operation
DB-->>API: result
API-->>App: plain text SUCCESS or ERROR line
App->>App: check first word of responsePHP
PHP's file_get_contents works for a quick call, but curl via the curl_* functions gives you proper error handling and timeout control. Use http_build_query() to build the query string — it handles URL encoding correctly and avoids the broken-URL bugs that come from manual string concatenation with names that contain spaces or special characters.
<?php
$params = http_build_query([
'source' => 'my-crm',
'user' => '6666',
'pass' => '1234',
'function' => 'add_lead',
'phone_number' => '7275551212',
'phone_code' => '1',
'list_id' => '101',
'first_name' => 'Maria',
'last_name' => 'Santos',
'vendor_lead_code' => 'CRM-98765',
]);
$url = 'https://your-server/vicidial/non_agent_api.php?' . $params;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if ($err) { error_log('VICIdial API error: ' . $err); }
elseif (strpos($response, 'SUCCESS') !== 0) { error_log('VICIdial: ' . $response); }
?>Python
Use the requests library. Pass a dictionary to the params keyword argument and requests handles URL encoding automatically. VICIdial returns plain text, not JSON, so read response.text and check whether it starts with SUCCESS or ERROR.
import requests
params = {
'source': 'my-crm',
'user': '6666',
'pass': '1234',
'function': 'add_lead',
'phone_number': '7275551212',
'phone_code': '1',
'list_id': '101',
'first_name': 'Maria',
'last_name': 'Santos',
'vendor_lead_code': 'CRM-98765',
}
try:
r = requests.get(
'https://your-server/vicidial/non_agent_api.php',
params=params,
timeout=10,
)
r.raise_for_status()
if not r.text.startswith('SUCCESS'):
print(f'VICIdial error: {r.text}')
except requests.RequestException as e:
print(f'HTTP error: {e}')Node.js
Node's built-in https module works, but the node-fetch or native fetch (Node 18+) is cleaner. Use URLSearchParams for the query string — it handles encoding the same way PHP's http_build_query does.
const params = new URLSearchParams({
source: 'my-crm',
user: '6666',
pass: '1234',
function: 'add_lead',
phone_number: '7275551212',
phone_code: '1',
list_id: '101',
first_name: 'Maria',
last_name: 'Santos',
vendor_lead_code: 'CRM-98765',
});
const url = `https://your-server/vicidial/non_agent_api.php?${params}`;
const res = await fetch(url, { signal: AbortSignal.timeout(10_000) });
const text = await res.text();
if (!text.startsWith('SUCCESS')) {
console.error('VICIdial error:', text);
}Once your language wrapper works, use it to call both the Non-Agent API for data operations (adding leads Lead, reading lead info, checking DNC status DNC (do not call)) and the Agent API for session control (external dial, pause, hangup). The same request shape applies to both endpoints — only the hostname path changes from non_agent_api.php to agent_api.php.
Error handling deserves its own paragraph. VICIdial's API returns plain text — there is no HTTP 4xx or 5xx status code for application-level errors. A permission failure, a missing parameter, and a database error all come back as HTTP 200 with an error string in the body. Your code must check the first word of the response body and branch accordingly. A response starting with SUCCESS means the operation worked. Anything starting with ERROR contains a human-readable message that tells you what went wrong — log the full string, not just that an error occurred.
Response parsing is simple because VICIdial uses a consistent format. The add_lead success line looks like: SUCCESS: add_lead LEAD HAS BEEN ADDED - 7275551212|6666|101|193715|-4. Split on the dash to get the data block, then split on pipes: field 1 is the phone number, field 2 is the API user, field 3 is the list ID, field 4 is the new lead_id, and field 5 is the GMT timezone offset the system assigned. Store that lead_id in your database — you will need it to pull disposition status later with lead_all_info.
Set a connection timeout on every request — 10 seconds is a reasonable upper bound for a local or same-datacenter call. VICIdial's API scripts are synchronous and will block until the database operation completes. If your box is under heavy load, some calls will be slow. A missing timeout in your HTTP client can cause your app's worker thread to hang indefinitely, especially when inserting leads Lead with DNC checks DNC (do not call) that run extra queries. Build retry logic with exponential backoff for transient failures — a 500ms delay before the second attempt is enough to ride out brief database lock contention.
For a guide on securing the API endpoint so it is not open to the internet, read how to secure the VICIdial API. For the full function reference and how the two APIs compare, see the VICIdial API and AGI overview.
If you want a VICIdial server with HTTPS already configured so your API calls work without certificate warnings on day one, every VICIfast plan ships a production-ready box in under 40 seconds.
About VICIfast LLC
VICIfast LLC operates a managed VICIdial hosting + BYOI service for outbound and inbound call centers. We run the dialers, the carriers, the recordings pipeline, and the compliance plumbing so operators don’t have to.
Citing this article
VICIfast Engineering. “How to Call the VICIdial API From Your App (PHP, Python, Node)”. VICIfast LLC, June 28, 2026. Retrieved from https://vicifast.com/blog/api-call-from-your-app-language
Have questions?
Related posts
You might be interested in
VICIfast newsletter
Liked this? Get the next one in your inbox.
We ship the kind of stuff you just read — concrete, numbers-first, no drip. One email when a new post goes live. Unsubscribe in one click.
Comments
No comments yet — be the first.