WEB API: Difference between revisions
No edit summary |
(VG-3075: Document getVoipCalls response fields including new lastSIPresponseNum) |
||
| (130 intermediate revisions by 4 users not shown) | |||
| Line 1: | Line 1: | ||
= | = VoIPmonitor Web API = | ||
This | This page documents VoIPmonitor's Web APIs for programmatic access to CDR data, recordings, active calls, and system functions. | ||
== | == Overview == | ||
<kroki lang="mermaid"> | |||
%%{init: {'flowchart': {'nodeSpacing': 15, 'rankSpacing': 30}}}%% | |||
flowchart LR | |||
subgraph Client | |||
A[Application] | |||
end | |||
subgraph API["API Endpoints"] | |||
B["/php/api.php"] | |||
C["/php/model/sql.php"] | |||
end | |||
subgraph Tasks | |||
E[getVoipCalls] | |||
F[getVoiceRecording] | |||
G[getPCAP] | |||
H[listActiveCalls] | |||
I[getShareURL] | |||
end | |||
A -->|user/password| B | |||
A -->|Session cookie| C | |||
B --> E & F & G & H & I | |||
</kroki> | |||
= | {| class="wikitable" | ||
|- | |||
! API !! Endpoint !! Authentication !! Use Case | |||
|- | |||
| '''HTTP API 2''' || <code>/php/api.php</code> || user/password params || CDR queries, recordings, PCAP, active calls | |||
|- | |||
| '''CDR HTTP API''' || <code>/php/model/sql.php</code> || Session cookie || Advanced CDR filtering with GUI filters | |||
|} | |||
{{Warning|1='''Correct path is critical:''' Always use <code>/php/api.php</code> (not <code>/api.php</code>). Missing the <code>/php/</code> directory causes "action parameter missing" errors.}} | |||
== | == HTTP API 2 == | ||
Preferred API for programmatic access. Requests via HTTP POST or GET to <code>/php/api.php</code>. | |||
=== | === Authentication === | ||
Include <code>user</code> and <code>password</code> parameters in every request: | |||
<syntaxhighlight lang="bash"> | |||
curl 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD¶ms=...' | |||
</syntaxhighlight> | |||
= | {{Note|1=API authentication uses local VoIPmonitor database credentials. It does NOT use LDAP or custom_login.php.}} | ||
'''Rate Limiting:''' Enable in GUI > Settings > System Configuration > "API maximal concurrent connections". | |||
=== getVoipCalls === | |||
=== | |||
Retrieve CDR records by search criteria. | |||
'''Parameters:''' | |||
{| class="wikitable" | |||
|- | |||
! Parameter !! Description | |||
|- | |||
| <code>startTime</code> || Calls starting >= this time (required) | |||
|- | |||
| <code>startTimeTo</code> || Calls starting <= this time | |||
|- | |||
| <code>callEnd</code> || Calls ending <= this time | |||
|- | |||
| <code>caller</code> / <code>called</code> || Caller/called number | |||
|- | |||
| <code>callId</code> || SIP Call-ID | |||
|- | |||
| <code>cdrId</code> || Database ID | |||
|- | |||
| <code>id_sensor</code> || Sensor number | |||
|- | |||
| <code>msisdn</code> || Match caller OR called (instead of AND) | |||
|- | |||
| <code>onlyConnected</code> || <code>1</code> = only answered calls | |||
|- | |||
| <code>customHeaders</code> || Comma-separated custom header names to return | |||
|} | |||
'''Examples:''' | |||
=== | <syntaxhighlight lang="bash"> | ||
# HTTP GET - by time range and caller | |||
curl 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD¶ms={"startTime":"2024-01-01","startTimeTo":"2024-01-31","caller":"123456"}' | |||
# HTTP POST - by Call-ID | |||
echo '{"task":"getVoipCalls","user":"USER","password":"PASSWORD","params":{"startTime":"2024-01-01","callId":"abc123"}}' | curl -X POST -d @- http://server/php/api.php | |||
# With custom headers | |||
=== | curl -G 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' \ | ||
--data-urlencode 'params={"startTime":"2024-01-01","caller":"123","customHeaders":"X-Custom-Header"}' | |||
</syntaxhighlight> | |||
'''Response fields:''' | |||
{| class="wikitable" | |||
|- | |||
! Field !! Description | |||
|- | |||
| <code>cdrId</code> || Database CDR ID | |||
|- | |||
| <code>id_sensor</code> || Sensor ID | |||
|- | |||
| <code>calldate</code> / <code>callend</code> || Call start/end time | |||
|- | |||
| <code>duration</code> / <code>connect_duration</code> || Total / connected duration | |||
|- | |||
| <code>caller</code> / <code>called</code> || Caller/called numbers | |||
|- | |||
| <code>sipcallerip</code> / <code>sipcalledip</code> || SIP endpoint IPs | |||
|- | |||
| <code>codec_a</code> / <code>codec_b</code> || Audio codecs | |||
|- | |||
| <code>lastSIPresponseNum</code> || '''(New in 2026.1)''' Final SIP response code (e.g., 200, 404, 503) | |||
|- | |||
| <code>callId</code> || SIP Call-ID | |||
|} | |||
=== getVoiceRecording === | |||
Download audio recording (WAV format). | |||
=== | '''Parameters:''' | ||
{| class="wikitable" | |||
|- | |||
! Parameter !! Description | |||
|- | |||
| <code>cdrId</code> || Database CDR ID (preferred) | |||
|- | |||
| <code>callId</code> || SIP Call-ID | |||
|- | |||
| <code>calldate</code> || Date hint (default: today) | |||
|- | |||
| <code>zip</code> || <code>true</code> = return ZIP archive | |||
|- | |||
| <code>ogg</code> || <code>true</code> = return OGG format | |||
|- | |||
| <code>saveaudio_afterconnect</code> || <code>"yes"</code> = audio only after call connect | |||
|} | |||
'''Examples:''' | |||
=== | <syntaxhighlight lang="bash"> | ||
# By CDR ID | |||
curl 'http://server/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"cdrId":12345}' > call.wav | |||
=== | # By Call-ID | ||
curl 'http://server/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"callId":"abc123"}' > call.wav | |||
# Multiple recordings (returns ZIP) | |||
echo '{"task":"getVoiceRecording","user":"USER","password":"PASSWORD","params":{"cdrId":[6,7]}}' | php api.php > calls.zip | |||
</syntaxhighlight> | |||
=== getPCAP === | |||
Download PCAP file. Automatically merges multiple legs and returns ZIP if needed. | |||
'''Parameters:''' | |||
{| class="wikitable" | |||
|- | |||
! Parameter !! Description | |||
|- | |||
| <code>cdrId</code> || Database CDR ID | |||
|- | |||
| <code>callId</code> || SIP Call-ID | |||
|- | |||
| <code>cidInterval</code> || Time window (seconds) to search for matching Call-ID | |||
|- | |||
| <code>cidMerge</code> || <code>true</code> = merge multiple legs | |||
|- | |||
| <code>zip</code> || <code>true</code> = force ZIP output | |||
|} | |||
'''Examples:''' | |||
<syntaxhighlight lang="bash"> | |||
# By CDR ID | |||
curl 'http://server/php/api.php?task=getPCAP&user=USER&password=PASSWORD¶ms={"cdrId":"12345"}' > call.pcap | |||
# By Call-ID with merge | |||
curl -G 'http://server/php/api.php?task=getPCAP&user=USER&password=PASSWORD' \ | |||
--data-urlencode 'params={"callId":"abc123","cidInterval":60,"cidMerge":true}' | |||
</syntaxhighlight> | |||
{{Tip|Use <code>curl -G --data-urlencode</code> for complex JSON params to avoid encoding issues.}} | |||
=== | === listActiveCalls === | ||
Get currently active calls from sensor. | |||
'''Parameters:''' <code>sensorId</code> (optional), <code>callId</code> (optional) | |||
<syntaxhighlight lang="bash"> | |||
curl 'http://server/php/api.php?task=listActiveCalls&user=USER&password=PASSWORD¶ms={"sensorId":"1"}' | |||
</syntaxhighlight> | |||
{{Note|1=IP addresses in response are integers. Convert with <code>INET_NTOA()</code> in MySQL or equivalent in your code.}} | |||
=== | === handleActiveCall === | ||
Pause/unpause RTP recording on active call. | |||
'''Parameters:''' | |||
* <code>sensorId</code> - Sensor number | |||
* <code>command</code> - <code>pausecall</code> or <code>unpausecall</code> | |||
* <code>callRef</code> - Call reference from listActiveCalls | |||
= | <syntaxhighlight lang="bash"> | ||
curl 'http://server/php/api.php?task=handleActiveCall&user=USER&password=PASSWORD¶ms={"sensorId":"1","command":"pausecall","callRef":"0x7f0e4c3c2680"}' | |||
</syntaxhighlight> | |||
=== getShareURL === | |||
Generate public shareable link for a CDR. | |||
== | '''Parameters:''' | ||
{| class="wikitable" | |||
|- | |||
! Parameter !! Description | |||
|- | |||
| <code>callId</code> or <code>cdrId</code> || Call identifier | |||
|- | |||
| <code>cidInterval</code> || Time window for Call-ID search | |||
|- | |||
| <code>rtp</code> || <code>true</code> = include RTP data | |||
|- | |||
| <code>sip_history</code> || <code>true</code> = SIP history only (no RTP) | |||
|- | |||
| <code>anonIps</code> || <code>true</code> = anonymize IPs | |||
|- | |||
| <code>validDays</code> || Link validity in days | |||
|} | |||
<syntaxhighlight lang="bash"> | |||
curl 'http://server/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"abc123","rtp":true,"validDays":15}' | |||
</syntaxhighlight> | |||
=== reportSummary === | |||
Generate pre-configured summary report as image or JSON. | |||
= | {{Warning|1=Reports must be created in '''GUI → Reports → Daily Report''' BEFORE using the API. The <code>report_name</code> parameter must match the report's Description field.}} | ||
'''Parameters:''' | |||
* <code>report_name</code> - Description field from GUI report | |||
* <code>datetime_from</code> / <code>datetime_to</code> - Date range | |||
* <code>json</code> - <code>true</code> = return JSON instead of image | |||
= | |||
<syntaxhighlight lang="bash"> | |||
curl 'http://server/php/api.php?task=reportSummary&user=USER&password=PASSWORD¶ms={"report_name":"Daily Summary","datetime_from":"2024-01-01","datetime_to":"2024-01-31"}' | |||
</syntaxhighlight> | |||
==== | === Other Tasks === | ||
= | {| class="wikitable" | ||
|- | |||
! Task !! Description | |||
|- | |||
| <code>listCdrIds</code> || List CDR IDs with basic info. Params: <code>offset</code>, <code>size</code> | |||
|- | |||
| <code>getAudioGraph</code> || Get spectrogram/waveform image. Params: <code>cdrId</code>, <code>type</code> (S/P/ALL), <code>side</code> (L/R) | |||
|} | |||
=== | == CDR HTTP API == | ||
Session-based API using GUI filter parameters. Requires login first. | |||
=== | === Authentication === | ||
==== | <syntaxhighlight lang="bash"> | ||
# Step 1: Login and get session | |||
curl -X POST 'http://server/php/model/sql.php?module=bypass_login&user=USER&pass=PASSWORD' | |||
# Returns: {"SID":"abc123...","cookie_name":"PHPSESSID","success":true} | |||
# Step 2: Use session cookie for requests | |||
curl -X POST --cookie "PHPSESSID=abc123..." \ | |||
'http://server/php/model/sql.php?task=LISTING&module=CDR&fdatefrom=2024-01-01T00:00:00&fcaller=123' | |||
</syntaxhighlight> | |||
{{Note|1=If GUI is in subdirectory (e.g., <code>/demo</code>), cookie name changes to <code>PHPSESSID-demo</code>.}} | |||
'''Disable authorization:''' GUI > Settings > System Configuration > "Disable authorization for API usage" | |||
=== Filter Parameters === | |||
'''Mandatory:''' <code>task=LISTING</code>, <code>module=CDR</code>, and at least one of <code>fdatefrom</code> or <code>fdateto</code>. | |||
{| class="wikitable" | |||
|- | |||
! Parameter !! Description !! Example | |||
|- | |||
| <code>fdatefrom</code> / <code>fdateto</code> || Date range || <code>2024-01-01T00:00:00</code> | |||
|- | |||
| <code>fcaller</code> / <code>fcalled</code> || Caller/called number || <code>123456</code> | |||
|- | |||
| <code>fcallerd_type</code> || <code>0</code>=OR, <code>1</code>=AND || <code>1</code> | |||
|- | |||
| <code>fcaller_domain</code> / <code>fcalled_domain</code> || SIP domain || <code>sip.example.com</code> | |||
|- | |||
| <code>fsipcallerip</code> / <code>fsipcalledip</code> || SIP IP address || <code>192.168.1.1</code> | |||
|- | |||
| <code>fcallid</code> || SIP Call-ID || <code>abc123</code> | |||
|- | |||
| <code>fsipresponse</code> || SIP response code || <code>503</code> | |||
|- | |||
| <code>fdurationgt</code> / <code>fdurationlt</code> || Duration (seconds) || <code>10</code> | |||
|- | |||
| <code>fsensor_id</code> || Sensor ID || <code>1</code> | |||
|- | |||
| <code>fcodec</code> || Codec numbers (comma-sep) || <code>0,8</code> | |||
|- | |||
| <code>suppress_results</code> || <code>1</code>=count only || <code>1</code> | |||
|} | |||
'''Paging:''' <code>page</code>, <code>start</code>, <code>limit</code> | |||
'''Sorting:''' <code>sort=[{"property":"calldate","direction":"DESC"}]</code> | |||
{{Warning|1=Use <code>=</code> (equals) for parameters, not <code>:</code> (colon). Example: <code>fcallerd_type=1</code> (correct), not <code>fcallerd_type:1</code> (wrong).}} | |||
=== Wildcards === | |||
Use <code>%25</code> (URL-encoded <code>%</code>) for SQL LIKE patterns: | |||
<syntaxhighlight lang="bash"> | |||
# Caller starting with "00" | |||
curl -G 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' \ | |||
--data-urlencode 'params={"startTime":"2024-01-01","caller":"%2500%25"}' | |||
</syntaxhighlight> | |||
=== Codec Values === | |||
{| class="wikitable" | |||
|- | |||
! Value !! Codec !! Value !! Codec | |||
|- | |||
| 0 || PCMU (G.711 μ-law) || 8 || PCMA (G.711 A-law) | |||
|- | |||
| 3 || GSM || 9 || G.722 | |||
|- | |||
| 4 || G.723 || 12 || QCELP | |||
|- | |||
| 18 || G.729 || 97 || iLBC | |||
|- | |||
| 98 || Speex || 301-305 || SILK variants | |||
|- | |||
| 306-308 || iSAC variants || 1000 || T.38 (Fax) | |||
|} | |||
=== RTP Quality Filters === | |||
{| class="wikitable" | |||
|- | |||
! Parameter !! Description | |||
|- | |||
| <code>fmosf1</code>, <code>fmosf2</code>, <code>fmosadapt</code> || MOS score filters | |||
|- | |||
| <code>frtcp_maxjitter</code>, <code>frtcp_avgjitter</code> || RTCP jitter | |||
|- | |||
| <code>frtcp_maxfr</code>, <code>frtcp_avgfr</code> || RTCP frame rate | |||
|- | |||
| <code>floss1</code> - <code>floss10</code> || Packet loss distribution | |||
|- | |||
| <code>f_d50</code>, <code>f_d70</code>, <code>f_d90</code>, ... || Delay distribution (50ms, 70ms, etc.) | |||
|} | |||
== Utility Endpoints == | |||
=== Direct PCAP Download === | |||
<syntaxhighlight lang="bash"> | |||
curl 'http://server/php/pcap.php?id=12345' # Full PCAP | |||
curl 'http://server/php/pcap.php?id=12345&disable_rtp=1' # SIP only | |||
</syntaxhighlight> | |||
=== CDR URL for Browser === | |||
<syntaxhighlight lang="text"> | |||
http://server/admin.php?cdr_filter={fcallid:"abc123"} | |||
</syntaxhighlight> | |||
=== SIP History === | |||
Requires session authentication first. | |||
<syntaxhighlight lang="bash"> | |||
# JSON data | |||
curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=brief_data&id=12345' | |||
# HTML table | |||
curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=brief&id=12345' | |||
# MSC diagram | |||
curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=getMSC&id=12345' | |||
</syntaxhighlight> | |||
=== License Check === | |||
<syntaxhighlight lang="bash"> | |||
# Basic license check | |||
curl 'http://server/php/apilicensecheck.php?task=licenseCheck' | |||
# Concurrent calls limit check | |||
curl 'http://server/php/apilicensecheck.php?task=licenseCallsLimitCheck' | |||
</syntaxhighlight> | |||
== Share CDR Configuration == | |||
=== Share Link Types === | |||
Use <code>/php/model/utilities.php</code> with <code>task=shareCdr</code>: | |||
{| class="wikitable" | |||
|- | |||
! Type !! subType !! Description | |||
|- | |||
| Local Public || <code>self_protected_link</code> || Password-protected local link | |||
|- | |||
| Local Private || <code>self_login_link</code> || Requires GUI login | |||
|- | |||
| voipmonitor.org || <code>share_link</code> || Public via share.voipmonitor.org | |||
|} | |||
=== Custom Branding === | |||
'''Product Name:''' Edit <code>config/system_configuration.php</code>: | |||
<syntaxhighlight lang="php"> | |||
define('BRAND_NAME', 'YourCompany'); | |||
</syntaxhighlight> | |||
'''Share Domain:''' Edit <code>brand.php</code> to use your domain instead of share.voipmonitor.org: | |||
<syntaxhighlight lang="php"> | |||
define('BRAND_SHARESITE', 'share.yourdomain.com'); | |||
define('BRAND_DOMAIN', 'yourdomain.com'); | |||
</syntaxhighlight> | |||
== Custom Login (LDAP/SSO) == | |||
Custom authentication via <code>scripts/custom_login.php</code>. This applies to GUI login only, NOT to API authentication. | |||
=== Basic Structure === | |||
<syntaxhighlight lang="php"> | |||
<?php | |||
function custom_login($user, $password) { | |||
// Authenticate against external system (LDAP, etc.) | |||
// ... | |||
return array( | |||
'username' => $user, | |||
'id' => $uniqueNumericId, // REQUIRED: Must be unique per user! | |||
'is_admin' => false, | |||
'id_group' => 1, // Optional: GUI group ID | |||
'enable_sensors' => array(1,2,3) // Optional: restrict to sensors | |||
); | |||
} | |||
?> | |||
</syntaxhighlight> | |||
{{Warning|1='''The <code>id</code> field MUST be unique per user.''' If multiple users return the same ID, they share ALL settings (timezone, dashboard, etc.). Use LDAP <code>uidnumber</code> or <code>crc32($email)</code> for uniqueness.}} | |||
=== LDAP Example === | |||
See <code>scripts/ldap_custom_login_example.php</code> in GUI directory. | |||
'''Requirements:''' <code>php-ldap</code> package installed. | |||
'''Debug from CLI:''' | |||
<syntaxhighlight lang="bash"> | |||
cd /var/www/html/scripts/ | |||
php custom_login.php | |||
</syntaxhighlight> | |||
Enable debug by uncommenting the debug block at top of script. | |||
=== Troubleshooting === | |||
'''Users share settings:''' Return unique <code>id</code> per user (see warning above). | |||
'''LDAP users can't view CDRs:''' Ensure <code>is_admin => false</code> and correct <code>id_group</code> is returned. | |||
'''Script being deleted:''' GUI antivirus deletes scripts with <code>shell_exec()</code>, <code>exec()</code>, etc. | |||
'''Solutions:''' | |||
# Disable antivirus in <code>config/system_configuration.php</code>: | |||
<syntaxhighlight lang="php"> | |||
define('DISABLE_ANTIVIRUS', true); | |||
</syntaxhighlight> | |||
# Or move shell commands to external file outside web directory and <code>require_once()</code> it. | |||
=== Azure AD / Microsoft SSO === | |||
For Microsoft Entra ID integration, see [[Microsoft_Sign_in_usage]]. For Google, see [[Google_Sign_in_usage]]. | |||
=== Return Array Parameters === | |||
Full list of available return parameters for custom_login: | |||
<div class="mw-collapsible mw-collapsed"> | |||
<syntaxhighlight lang="text"> | |||
username, name, id, id_group, group_name, is_admin, email | |||
enable_sensors - array of sensor IDs user can access | |||
can_cdr, can_write_cdr, can_play_audio, can_download_audio | |||
can_listen_active_call, can_pcap, can_upload_pcap | |||
can_messages, can_view_content_message, can_graphs | |||
can_activecalls, can_register, can_sip_msg, can_livesniffer | |||
can_capture_rules, can_audit, can_alerts_edit, can_reports_edit | |||
can_dashboard, can_ipacc, can_mtr, can_sensors_operations | |||
can_network, can_edit_codebooks, hide_license_information | |||
ip, number, domain, vlan (user restrictions) | |||
custom_headers_cdr, custom_headers_message | |||
blocked, blocked_reason, req_2fa | |||
</syntaxhighlight> | |||
</div> | |||
== See Also == | |||
* [[Call_Detail_Record_-_CDR#Filter_Form_button|CDR Filter Form]] - GUI filter options | |||
* [[Active_calls|Active Calls]] - Active calls monitoring | |||
* [[User_Management|User Management]] - User permissions | |||
* [[Google_Sign_in_usage|Google Sign-In]] - Google OAuth setup | |||
* [[Microsoft_Sign_in_usage|Microsoft Sign-In]] - Azure AD setup | |||
== AI Summary for RAG == | |||
'''Summary:''' VoIPmonitor Web API reference with two main APIs: (1) HTTP API 2 at <code>/php/api.php</code> using user/password authentication for tasks like getVoipCalls, getVoiceRecording, getPCAP, listActiveCalls, getShareURL, handleActiveCall, reportSummary; (2) CDR HTTP API at <code>/php/model/sql.php</code> using session cookies with full GUI filter support. Critical: correct endpoint path is <code>/php/api.php</code> (not <code>/api.php</code>). reportSummary requires pre-configured reports in GUI. Custom login via <code>scripts/custom_login.php</code> enables LDAP/SSO - requires unique numeric ID per user to avoid shared settings. Antivirus may delete scripts with shell_exec - disable with DISABLE_ANTIVIRUS or move to external file. Branding: BRAND_NAME for product name, BRAND_SHARESITE/BRAND_DOMAIN in brand.php for custom share domain. | |||
'''Keywords:''' web api, http api, api.php, sql.php, getVoipCalls, getVoiceRecording, getPCAP, getShareURL, listActiveCalls, reportSummary, handleActiveCall, CDR filter, custom login, LDAP, authentication, session, curl, JSON, branding, BRAND_NAME, BRAND_SHARESITE, antivirus, DISABLE_ANTIVIRUS, unique user id, uidnumber | |||
'''Key Questions:''' | |||
* What is the correct VoIPmonitor API endpoint path? | |||
* How do I retrieve CDRs via the VoIPmonitor API? | |||
* How to download PCAP or voice recordings via API? | |||
* How to list active calls via API? | |||
* How to generate reports via API? | |||
* How to configure LDAP authentication for VoIPmonitor? | |||
* Why do LDAP users share settings? (need unique ID) | |||
* Why is custom_login.php being deleted? (antivirus) | |||
* How to customize VoIPmonitor branding? | |||
* What's the difference between api.php and sql.php? | |||
* How to use wildcards in API filter parameters? | |||
Latest revision as of 12:16, 19 January 2026
VoIPmonitor Web API
This page documents VoIPmonitor's Web APIs for programmatic access to CDR data, recordings, active calls, and system functions.
Overview
| API | Endpoint | Authentication | Use Case |
|---|---|---|---|
| HTTP API 2 | /php/api.php |
user/password params | CDR queries, recordings, PCAP, active calls |
| CDR HTTP API | /php/model/sql.php |
Session cookie | Advanced CDR filtering with GUI filters |
⚠️ Warning: Correct path is critical: Always use /php/api.php (not /api.php). Missing the /php/ directory causes "action parameter missing" errors.
HTTP API 2
Preferred API for programmatic access. Requests via HTTP POST or GET to /php/api.php.
Authentication
Include user and password parameters in every request:
curl 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD¶ms=...'
ℹ️ Note: API authentication uses local VoIPmonitor database credentials. It does NOT use LDAP or custom_login.php.
Rate Limiting: Enable in GUI > Settings > System Configuration > "API maximal concurrent connections".
getVoipCalls
Retrieve CDR records by search criteria.
Parameters:
| Parameter | Description |
|---|---|
startTime |
Calls starting >= this time (required) |
startTimeTo |
Calls starting <= this time |
callEnd |
Calls ending <= this time |
caller / called |
Caller/called number |
callId |
SIP Call-ID |
cdrId |
Database ID |
id_sensor |
Sensor number |
msisdn |
Match caller OR called (instead of AND) |
onlyConnected |
1 = only answered calls
|
customHeaders |
Comma-separated custom header names to return |
Examples:
# HTTP GET - by time range and caller
curl 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD¶ms={"startTime":"2024-01-01","startTimeTo":"2024-01-31","caller":"123456"}'
# HTTP POST - by Call-ID
echo '{"task":"getVoipCalls","user":"USER","password":"PASSWORD","params":{"startTime":"2024-01-01","callId":"abc123"}}' | curl -X POST -d @- http://server/php/api.php
# With custom headers
curl -G 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' \
--data-urlencode 'params={"startTime":"2024-01-01","caller":"123","customHeaders":"X-Custom-Header"}'
Response fields:
| Field | Description |
|---|---|
cdrId |
Database CDR ID |
id_sensor |
Sensor ID |
calldate / callend |
Call start/end time |
duration / connect_duration |
Total / connected duration |
caller / called |
Caller/called numbers |
sipcallerip / sipcalledip |
SIP endpoint IPs |
codec_a / codec_b |
Audio codecs |
lastSIPresponseNum |
(New in 2026.1) Final SIP response code (e.g., 200, 404, 503) |
callId |
SIP Call-ID |
getVoiceRecording
Download audio recording (WAV format).
Parameters:
| Parameter | Description |
|---|---|
cdrId |
Database CDR ID (preferred) |
callId |
SIP Call-ID |
calldate |
Date hint (default: today) |
zip |
true = return ZIP archive
|
ogg |
true = return OGG format
|
saveaudio_afterconnect |
"yes" = audio only after call connect
|
Examples:
# By CDR ID
curl 'http://server/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"cdrId":12345}' > call.wav
# By Call-ID
curl 'http://server/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"callId":"abc123"}' > call.wav
# Multiple recordings (returns ZIP)
echo '{"task":"getVoiceRecording","user":"USER","password":"PASSWORD","params":{"cdrId":[6,7]}}' | php api.php > calls.zip
getPCAP
Download PCAP file. Automatically merges multiple legs and returns ZIP if needed.
Parameters:
| Parameter | Description |
|---|---|
cdrId |
Database CDR ID |
callId |
SIP Call-ID |
cidInterval |
Time window (seconds) to search for matching Call-ID |
cidMerge |
true = merge multiple legs
|
zip |
true = force ZIP output
|
Examples:
# By CDR ID
curl 'http://server/php/api.php?task=getPCAP&user=USER&password=PASSWORD¶ms={"cdrId":"12345"}' > call.pcap
# By Call-ID with merge
curl -G 'http://server/php/api.php?task=getPCAP&user=USER&password=PASSWORD' \
--data-urlencode 'params={"callId":"abc123","cidInterval":60,"cidMerge":true}'
💡 Tip: Use curl -G --data-urlencode for complex JSON params to avoid encoding issues.
listActiveCalls
Get currently active calls from sensor.
Parameters: sensorId (optional), callId (optional)
curl 'http://server/php/api.php?task=listActiveCalls&user=USER&password=PASSWORD¶ms={"sensorId":"1"}'
ℹ️ Note: IP addresses in response are integers. Convert with INET_NTOA() in MySQL or equivalent in your code.
handleActiveCall
Pause/unpause RTP recording on active call.
Parameters:
sensorId- Sensor numbercommand-pausecallorunpausecallcallRef- Call reference from listActiveCalls
curl 'http://server/php/api.php?task=handleActiveCall&user=USER&password=PASSWORD¶ms={"sensorId":"1","command":"pausecall","callRef":"0x7f0e4c3c2680"}'
Generate public shareable link for a CDR.
Parameters:
| Parameter | Description |
|---|---|
callId or cdrId |
Call identifier |
cidInterval |
Time window for Call-ID search |
rtp |
true = include RTP data
|
sip_history |
true = SIP history only (no RTP)
|
anonIps |
true = anonymize IPs
|
validDays |
Link validity in days |
curl 'http://server/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"abc123","rtp":true,"validDays":15}'
reportSummary
Generate pre-configured summary report as image or JSON.
⚠️ Warning: Reports must be created in GUI → Reports → Daily Report BEFORE using the API. The report_name parameter must match the report's Description field.
Parameters:
report_name- Description field from GUI reportdatetime_from/datetime_to- Date rangejson-true= return JSON instead of image
curl 'http://server/php/api.php?task=reportSummary&user=USER&password=PASSWORD¶ms={"report_name":"Daily Summary","datetime_from":"2024-01-01","datetime_to":"2024-01-31"}'
Other Tasks
| Task | Description |
|---|---|
listCdrIds |
List CDR IDs with basic info. Params: offset, size
|
getAudioGraph |
Get spectrogram/waveform image. Params: cdrId, type (S/P/ALL), side (L/R)
|
CDR HTTP API
Session-based API using GUI filter parameters. Requires login first.
Authentication
# Step 1: Login and get session
curl -X POST 'http://server/php/model/sql.php?module=bypass_login&user=USER&pass=PASSWORD'
# Returns: {"SID":"abc123...","cookie_name":"PHPSESSID","success":true}
# Step 2: Use session cookie for requests
curl -X POST --cookie "PHPSESSID=abc123..." \
'http://server/php/model/sql.php?task=LISTING&module=CDR&fdatefrom=2024-01-01T00:00:00&fcaller=123'
ℹ️ Note: If GUI is in subdirectory (e.g., /demo), cookie name changes to PHPSESSID-demo.
Disable authorization: GUI > Settings > System Configuration > "Disable authorization for API usage"
Filter Parameters
Mandatory: task=LISTING, module=CDR, and at least one of fdatefrom or fdateto.
| Parameter | Description | Example |
|---|---|---|
fdatefrom / fdateto |
Date range | 2024-01-01T00:00:00
|
fcaller / fcalled |
Caller/called number | 123456
|
fcallerd_type |
0=OR, 1=AND |
1
|
fcaller_domain / fcalled_domain |
SIP domain | sip.example.com
|
fsipcallerip / fsipcalledip |
SIP IP address | 192.168.1.1
|
fcallid |
SIP Call-ID | abc123
|
fsipresponse |
SIP response code | 503
|
fdurationgt / fdurationlt |
Duration (seconds) | 10
|
fsensor_id |
Sensor ID | 1
|
fcodec |
Codec numbers (comma-sep) | 0,8
|
suppress_results |
1=count only |
1
|
Paging: page, start, limit
Sorting: sort=[{"property":"calldate","direction":"DESC"}]
⚠️ Warning: Use = (equals) for parameters, not : (colon). Example: fcallerd_type=1 (correct), not fcallerd_type:1 (wrong).
Wildcards
Use %25 (URL-encoded %) for SQL LIKE patterns:
# Caller starting with "00"
curl -G 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' \
--data-urlencode 'params={"startTime":"2024-01-01","caller":"%2500%25"}'
Codec Values
| Value | Codec | Value | Codec |
|---|---|---|---|
| 0 | PCMU (G.711 μ-law) | 8 | PCMA (G.711 A-law) |
| 3 | GSM | 9 | G.722 |
| 4 | G.723 | 12 | QCELP |
| 18 | G.729 | 97 | iLBC |
| 98 | Speex | 301-305 | SILK variants |
| 306-308 | iSAC variants | 1000 | T.38 (Fax) |
RTP Quality Filters
| Parameter | Description |
|---|---|
fmosf1, fmosf2, fmosadapt |
MOS score filters |
frtcp_maxjitter, frtcp_avgjitter |
RTCP jitter |
frtcp_maxfr, frtcp_avgfr |
RTCP frame rate |
floss1 - floss10 |
Packet loss distribution |
f_d50, f_d70, f_d90, ... |
Delay distribution (50ms, 70ms, etc.) |
Utility Endpoints
Direct PCAP Download
curl 'http://server/php/pcap.php?id=12345' # Full PCAP
curl 'http://server/php/pcap.php?id=12345&disable_rtp=1' # SIP only
CDR URL for Browser
http://server/admin.php?cdr_filter={fcallid:"abc123"}
SIP History
Requires session authentication first.
# JSON data
curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=brief_data&id=12345'
# HTML table
curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=brief&id=12345'
# MSC diagram
curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=getMSC&id=12345'
License Check
# Basic license check
curl 'http://server/php/apilicensecheck.php?task=licenseCheck'
# Concurrent calls limit check
curl 'http://server/php/apilicensecheck.php?task=licenseCallsLimitCheck'
Use /php/model/utilities.php with task=shareCdr:
| Type | subType | Description |
|---|---|---|
| Local Public | self_protected_link |
Password-protected local link |
| Local Private | self_login_link |
Requires GUI login |
| voipmonitor.org | share_link |
Public via share.voipmonitor.org |
Custom Branding
Product Name: Edit config/system_configuration.php:
define('BRAND_NAME', 'YourCompany');
Share Domain: Edit brand.php to use your domain instead of share.voipmonitor.org:
define('BRAND_SHARESITE', 'share.yourdomain.com');
define('BRAND_DOMAIN', 'yourdomain.com');
Custom Login (LDAP/SSO)
Custom authentication via scripts/custom_login.php. This applies to GUI login only, NOT to API authentication.
Basic Structure
<?php
function custom_login($user, $password) {
// Authenticate against external system (LDAP, etc.)
// ...
return array(
'username' => $user,
'id' => $uniqueNumericId, // REQUIRED: Must be unique per user!
'is_admin' => false,
'id_group' => 1, // Optional: GUI group ID
'enable_sensors' => array(1,2,3) // Optional: restrict to sensors
);
}
?>
⚠️ Warning: The id field MUST be unique per user. If multiple users return the same ID, they share ALL settings (timezone, dashboard, etc.). Use LDAP uidnumber or crc32($email) for uniqueness.
LDAP Example
See scripts/ldap_custom_login_example.php in GUI directory.
Requirements: php-ldap package installed.
Debug from CLI:
cd /var/www/html/scripts/
php custom_login.php
Enable debug by uncommenting the debug block at top of script.
Troubleshooting
Users share settings: Return unique id per user (see warning above).
LDAP users can't view CDRs: Ensure is_admin => false and correct id_group is returned.
Script being deleted: GUI antivirus deletes scripts with shell_exec(), exec(), etc.
Solutions:
- Disable antivirus in
config/system_configuration.php:
define('DISABLE_ANTIVIRUS', true);
- Or move shell commands to external file outside web directory and
require_once()it.
Azure AD / Microsoft SSO
For Microsoft Entra ID integration, see Microsoft_Sign_in_usage. For Google, see Google_Sign_in_usage.
Return Array Parameters
Full list of available return parameters for custom_login:
username, name, id, id_group, group_name, is_admin, email
enable_sensors - array of sensor IDs user can access
can_cdr, can_write_cdr, can_play_audio, can_download_audio
can_listen_active_call, can_pcap, can_upload_pcap
can_messages, can_view_content_message, can_graphs
can_activecalls, can_register, can_sip_msg, can_livesniffer
can_capture_rules, can_audit, can_alerts_edit, can_reports_edit
can_dashboard, can_ipacc, can_mtr, can_sensors_operations
can_network, can_edit_codebooks, hide_license_information
ip, number, domain, vlan (user restrictions)
custom_headers_cdr, custom_headers_message
blocked, blocked_reason, req_2fa
See Also
- CDR Filter Form - GUI filter options
- Active Calls - Active calls monitoring
- User Management - User permissions
- Google Sign-In - Google OAuth setup
- Microsoft Sign-In - Azure AD setup
AI Summary for RAG
Summary: VoIPmonitor Web API reference with two main APIs: (1) HTTP API 2 at /php/api.php using user/password authentication for tasks like getVoipCalls, getVoiceRecording, getPCAP, listActiveCalls, getShareURL, handleActiveCall, reportSummary; (2) CDR HTTP API at /php/model/sql.php using session cookies with full GUI filter support. Critical: correct endpoint path is /php/api.php (not /api.php). reportSummary requires pre-configured reports in GUI. Custom login via scripts/custom_login.php enables LDAP/SSO - requires unique numeric ID per user to avoid shared settings. Antivirus may delete scripts with shell_exec - disable with DISABLE_ANTIVIRUS or move to external file. Branding: BRAND_NAME for product name, BRAND_SHARESITE/BRAND_DOMAIN in brand.php for custom share domain.
Keywords: web api, http api, api.php, sql.php, getVoipCalls, getVoiceRecording, getPCAP, getShareURL, listActiveCalls, reportSummary, handleActiveCall, CDR filter, custom login, LDAP, authentication, session, curl, JSON, branding, BRAND_NAME, BRAND_SHARESITE, antivirus, DISABLE_ANTIVIRUS, unique user id, uidnumber
Key Questions:
- What is the correct VoIPmonitor API endpoint path?
- How do I retrieve CDRs via the VoIPmonitor API?
- How to download PCAP or voice recordings via API?
- How to list active calls via API?
- How to generate reports via API?
- How to configure LDAP authentication for VoIPmonitor?
- Why do LDAP users share settings? (need unique ID)
- Why is custom_login.php being deleted? (antivirus)
- How to customize VoIPmonitor branding?
- What's the difference between api.php and sql.php?
- How to use wildcards in API filter parameters?