vicigeeksimple guides
Browse
All guides

Automate tasks · API boundaries

VICIdial Agent API vs Non-Agent API: choose the boundary before automating

Use the Agent API for a logged-in agent session and the Non-Agent API for administrative data and reporting work.

Reader setup

Before you start

Run each step in order and move only when the outcome is confirmed.

  1. HTTPS access to a running VICIdial server; complete the install guide first if you do not have one
  2. The official API document matching the installed revision
  3. A dedicated least-privilege API user for authenticated tests
What you will prove
A successful version check on both endpoints and one protected, semantically validated read-only API request.
Safety boundary
Never place `user`, `pass`, lead, phone or call values in a command line, URL, browser history, source file or routine log.

Reader path

How to use this article

  • Use it when: You need a fixed sequence to make a deployment or configuration change now.
  • Expected result: Follow each step and verify the outcome before changing the next layer.
  • Start here: Start at the first section and complete every checkpoint before moving to the next.

01 / 06

Choose the endpoint by the state it owns

Fast answer: use `/agc/api.php` for actions on an already logged-in Agent session and `/vicidial/non_agent_api.php` for system information, leads, lists, campaigns, users, phones, DIDs, reports and recording lookups. Start with each endpoint’s unauthenticated `version` function, then read the exact function section for that installed build.

Both APIs return a plain-text prefix, not just an HTTP status: `SUCCESS:`, `ERROR:`, or occasionally `NOTICE:`. HTTP 200 only means the web server answered — AGENT_API.txt's own worked example shows a `SUCCESS:` line immediately followed by an `ERROR:` line, both delivered as ordinary 200 responses; treat the prefix, not the status code, as the result. The companion article “The VICIdial Agent API with real code: curl, JavaScript and agc/api.php” walks through parsing that response body in full (its Step 2), so this article does not repeat it.

That pairing is not a coincidence: the Agent API's whole contract is session-shaped, so its rejections describe session state, while the Non-Agent API's contract is account-shaped, so its rejections describe account permission. An Agent API success proves nothing about your account's report or user-management permissions, and a Non-Agent API success proves nothing about whether any agent is actually logged in — each API only ever speaks to the state it owns.

This comparison assumes you already know VICIdial's own nouns — campaign, list, lead, the hopper and DID — covered in the companion article “VICIdial terminology for complete beginners: users, phones, campaigns and leads”; the API-specific terms below (`agent_user`, `function`, `source`) are defined at first use here instead.

  • Use HTTPS with normal certificate and hostname verification.
  • Keep a short non-secret `source` label of 20 characters or fewer.
  • Test reads before writes and synthetic objects before production objects.
  • Treat plain-text `ERROR` as failure even when HTTP status is 200.
Real rejection strings, side by side
Agent API (/agc/api.php) rejects on SESSION state:ERROR: agent_user is not logged in - 6666 Non-Agent API (/vicidial/non_agent_api.php) rejects on ACCOUNT permission:ERROR: auth USER DOES NOT HAVE PERMISSION TO USE THIS FUNCTION - 6666|add_lead Agent API, function-specific permission gate (same shape on the Non-Agent side):ERROR: auth USER DOES NOT HAVE PERMISSION TO USE THIS FUNCTION - 6666|webserver|ADMIN
Not executed · worksheet or reference text

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

Before you run it
These are AGENT_API.txt's and NON-AGENT_API.txt's own documented response strings, not a capture from any specific server.
Success looks like
You can tell, from the wording alone, whether a rejection means "no live agent session" (Agent API) or "this account cannot use this function" (Non-Agent API).
Stop if
If a response matches neither shape, read the exact function's RESPONSES block in the matching document before assuming it is a bug.
Trace path · read left to right
01Logged-in agent02Agent API03Administrative API

Visual walkthrough

Follow three real demo screens

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 system administration

Use the Administration map

Sanitized VICIdial Administration menu showing phones, carriers, servers, system settings, and system statuses
Captured September 24, 2026 at 21:34:11 UTC on the authorized isolated demo. This menu is a navigation map only; it does not show that any system-wide setting was changed or verified.
Step 2 · Check permission scope

Review user-group boundaries

Sanitized VICIdial User Groups Listings page showing the fixture user group
Captured September 24, 2026 at 21:53:04 UTC on the authorized isolated demo. This page shows group structure only; it does not prove that an account has a particular permission or that access was changed.
Step 3 · Read global settings

Inspect system-wide security and API context

Sanitized VICIdial Modify System Settings page showing revision, schema, interface, SIP-stack, and API-related controls
Captured August 11, 2026 at 16:22:08 UTC on the authorized isolated demo. This is a read-only view of system-wide settings with no credentials or addresses; it does not prove that a setting was changed or that an API request succeeded.

02 / 06

Step 1 — Identify both installed API builds

The official Agent API documents `version` without credentials, and the Non-Agent API exposes the same discovery function; AGENT_API.txt (Updated: 2025-08-30) and NON-AGENT_API.txt (Updated: 2025-07-18) both document it with zero required fields. POSTing form data keeps the request shape compatible with later protected calls while avoiding credentials in a URL.

Replace only the reserved hostname with the approved VICIdial DNS name. Keep strict TLS validation enabled; do not add `-k` or an insecure certificate bypass. Save the returned version/build in the private integration change record. Each response also carries a `DATE` and `EPOCH` field; record the `DATE` next to your own change log so you can tell, months later, which installed build a given integration was last tested against.

Call both read-only version endpoints
curl --fail-with-body --silent --show-error --max-time 15 \  --request POST \  --data-urlencode 'function=version' \  "https://<VICIDIAL_HOST>/agc/api.php" curl --fail-with-body --silent --show-error --max-time 15 \  --request POST \  --data-urlencode 'function=version' \  "https://<VICIDIAL_HOST>/vicidial/non_agent_api.php"
Evidence · ViciBox 12 demo capture · demo values substituted

Captured demo response · 2026-09-23 21:35 UTC. The displayed command is the command that ran; a safe subset label means it was filtered, redacted, or fixture-scoped. Replays only after you select Replay transcript.

Command output line: curl --fail-with-body --silent --show-error --max-time 15 \ --request POST \ --data-urlencode 'function=version' \ "https://[demo-host]/agc/api.php" curl --fail-with-body --silent --show-error --max-time 15 \ --request POST \ --data-urlencode 'function=version' \ "https://[demo-host]/vicidial/non_agent_api.php"
VERSION: 2.14-83|BUILD: 250830-2102|DATE: 2026-09-23 17:35:34|EPOCH: [number]
VERSION: 2.14-202|BUILD: 250720-1841|DATE: 2026-09-23 17:35:34|EPOCH: [number]|DST: 1|TZ: -5.00|TZNOW: -4|
Before you run it
Replace `<VICIDIAL_HOST>` with the certificate-matching VICIdial hostname, keeping the quotes. These two discovery calls contain no credentials or customer data.
Success looks like
Each endpoint returns a `VERSION:` response whose build can be matched to the installed source and official reference.
Stop if
Stop on TLS, timeout, HTTP or `ERROR` output; do not bypass certificate checks or guess function support.

03 / 06

Step 2 — Select one documented read-only function

Agent API functions normally require `user`, `pass`, `source` and `agent_user` together, because nearly every function acts on one logged-in Agent's live session. AGENT_API.txt's own required-variables note lists `agent_user` for every call, but the example URLs for five functions never include it: the credential-free `version`; `webserver`, which still needs `user`/`pass`/`source` plus its own permission; and `st_login_log`, `st_get_agent_active_lead` and `send_notification`, which identify their target through `value`/`vendor_id` or `recipient`/`recipient_type` instead of a logged-in session. Confirm your API user carries Agent API access — the `vdc_agent_api_access` column on `vicidial_users` — before assuming a rejection means the agent, not the account, is the problem.

The Non-Agent API is the correct starting point for bounded inventory and status reads instead: it has no Agent-session concept at all, so its functions are gated purely by the calling account's `user_level` and function-specific permissions. NON-AGENT_API.txt states specific requirements per function — `sounds_list`, for example, documents that its caller needs `user_level` 7 or higher — so “my account is a high-level admin” does not guarantee every function is allowed; check the function's own permission note before assuming access. Read the complete function section for the discovered build, including output stages and permissions; request only the output formats (stage values such as csv, tab or pipe) that the function's own section lists, and do not assume any other format exists.

API selection worksheet
goal: one exact read-only questionendpoint: Agent API | Non-Agent APIinstalled build: value from versionfunction: exact documented namerequired permission: exact documented permissionresource filter: one synthetic agent/list/campaignexpected prefix/format: documented value
Not executed · worksheet or reference text

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

Before you run it
Complete from the matching official API document before creating an authenticated request.
Success looks like
Every row is explicit and the selected function is read-only for one bounded synthetic resource.
Stop if
Stop if the build, function, permission, filter or output contract is unknown.

04 / 06

Step 3 — Put authentication in a protected curl config

Create a mode-0600 curl configuration as root — `umask 077` then `install -m 600 /dev/null /etc/vicidial-api/readonly.cfg` for a Non-Agent read, or `/etc/vicidial-api/agent.cfg` for an Agent API call — and edit only that file. The template below holds only the endpoint, credentials and connection limits, so the same file serves any Non-Agent read; the function itself is supplied per call with `--data-urlencode` on the command line in Step 4. The Agent API file has the same shape but targets `/agc/api.php` and adds `agent_user`.

The placeholder credentials are deliberately invalid. Never commit the filled file, pass it to another user, store it under a web root, or leave a copy in a shared temporary directory.

Non-Agent API read-only curl configuration (/etc/vicidial-api/readonly.cfg)
url = "https://<VICIDIAL_HOST>/vicidial/non_agent_api.php"request = "POST"connect-timeout = 5max-time = 15fail-with-bodysilentshow-errordata-urlencode = "source=guide-check"data-urlencode = "user=<API_USER>"data-urlencode = "pass=<API_PASS>"
Not executed · worksheet or reference text

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

Before you run it
Replace the hostname and credential placeholders only inside the protected mode-0600 file at `/etc/vicidial-api/readonly.cfg`. Keep `source` short and non-secret; the function is added on the command line, not in this file.
Success looks like
The file contains one HTTPS endpoint, bounded timeouts and credentials only; no secret appears in shell history or a URL, and no function is hardcoded into it.
Stop if
Stop if permissions are broader than 0600, TLS would be bypassed, or the function could write state.

05 / 06

Step 4 — Run the protected request and parse its semantic prefix

Run curl with `--config` against the file Step 3 created, and capture the small response in memory. `curl`'s own exit status only reports transport/HTTP failure; your code must separately reject a legacy application-level `ERROR:` body, since VICIdial returns that on an ordinary HTTP 200. AGENT_API.txt also documents a third prefix, `NOTICE:`, for cases such as `external_dial` targeting an in-group that does not exist — treat an unrecognized prefix the same defensive way, by logging it and stopping, rather than assuming success.

Do not print full data responses in automation logs. Record a sanitized function name, timestamp, response class and correlation value generated by your own integration—not lead, phone, Agent, call or recording identifiers.

Run the protected request and classify its response
response="$(curl --fail-with-body --silent --show-error --config /etc/vicidial-api/readonly.cfg --data-urlencode 'function=version')"case "$response" in  VERSION:*|SUCCESS:*) printf '%s\n' 'API response accepted' ;;  ERROR:*) printf '%s\n' 'VICIdial returned ERROR' >&2; exit 1 ;;  *) printf '%s\n' 'Unexpected API response' >&2; exit 1 ;;esac
Evidence · ViciBox 12 demo capture

Captured demo response · 2026-09-23 21:35 UTC. The displayed command is the command that ran; a safe subset label means it was filtered, redacted, or fixture-scoped. Replays only after you select Replay transcript.

Command output line: response="$(curl --fail-with-body --silent --show-error --config /etc/vicidial-api/readonly.cfg --data-urlencode 'function=version')" case "$response" in VERSION:*|SUCCESS:*) printf '%s\n' 'API response accepted' ;; ERROR:*) printf '%s\n' 'VICIdial returned ERROR' >&2; exit 1 ;; *) printf '%s\n' 'Unexpected API response' >&2; exit 1 ;; esac
API response accepted
Before you run it
Complete Step 3's protected file first. This command only reads the version endpoint; it changes no VICIdial state.
Success looks like
The script prints `API response accepted` without exposing the response body or credentials.
Stop if
Stop on `ERROR`, unexpected output, timeout or transport failure; do not point this read-only example at a state-changing function.

06 / 06

Step 5 — Verify independently before adding a write

For a read, compare the result with the authorized VICIdial screen or a separate bounded read path. For any future write, define the existing state, exact intended effect, idempotency behavior, rollback and independent post-condition before changing the protected config.

Never chain Agent state transitions optimistically. Pause, hangup, disposition and logout must each receive and satisfy their documented state/result contract. For Non-Agent writes, set duplicate, hopper, callback, custom-field and reset options explicitly and test on an inactive synthetic object first. Before calling any write function more than once, read the companion article “VICIdial API automation that does not hide failures” — a retried request is not automatically safe just because the first attempt returned `ERROR`.

  • Rotate or remove the local test credential after acceptance.
  • Apply response-size and timeout limits to every function.
  • Log only response class and non-sensitive timing.
  • Repeat version and permission checks after every VICIdial upgrade.

Evidence ledger

Verification basis

  • Source present: AGENT_API.txt (Updated: 2025-08-30) and NON-AGENT_API.txt (Updated: 2025-07-18) define both endpoints' functions, parameters and response prefixes.
  • Configured/enabled/functionally verified: this article makes no claim that an API user or function is enabled on any target.
  • The target revision and permissions must be checked with its supported version/read paths before use.

Primary references

Sources

  1. VICIdial Agent APIVICIdial · accessed August 4, 2026
  2. VICIdial Non-Agent APIVICIdial · accessed August 4, 2026
  3. OWASP API Security Top 10OWASP · accessed September 23, 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.