WEB API: Difference between revisions

From VoIPmonitor.org
(Add information about resolving license lockout: CDR deletion, license upgrade, and contact support)
(Add curl --data-urlencode examples for getPCAP API to fix success:false errors)
Line 658: Line 658:
Parameters like getVoiceRecording. Returns PCAP (merged legs if multiple in interval). Zip auto if multiple.
Parameters like getVoiceRecording. Returns PCAP (merged legs if multiple in interval). Zip auto if multiple.


==== Examples ====
==== curl with data-urlencode ===


===== HTTP GET (with RTP) =====
Use <code>-G</code> and <code>--data-urlencode</code> to properly encode the params string, especially when it contains special characters or complex bracket structures. This prevents <code>success:false</code> responses due to malformed parameters.
 
===== HTTP GET (with cURL recommended) =====
 
curl -G -X GET 'http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD' --data-urlencode 'params={"callId":"1502262225","cidInterval":60,"cidMerge":true}'
 
===== HTTP POST (with cURL recommended for complex params) =====
 
curl -X POST 'http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD' \
  --data 'params={"callId":"1502262225","cidInterval":60}' \
  --data 'cidMerge=true' \
  --data 'zip=true'
 
==== Direct URL Examples (GET) =====
 
These work for simple cases but may fail with special characters:


  http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"cdrId":"76"}
  http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"cdrId":"76"}
  http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"callId":"1502262225"}
  http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"callId":"1502262225"}
  http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"callId":"1502262225","cidInterval":60}
  http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"callId":"1502262225","cidInterval":60}
http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"callId":"1502262225","cidInterval":60,"cidMerge":true}
http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"callId":"1502262225","cidInterval":60,"cidMerge":true,"zip":true}


=== listCdrIds ===
=== listCdrIds ===
Line 824: Line 837:
=== AI Summary for RAG ===
=== AI Summary for RAG ===


'''Summary:''' This article covers VoIPmonitor's custom login (LDAP/script examples, parameters), CDR HTTP API (inputs/outputs, examples), sharing CDRs, getting PCAPs, URL searches, HTTP API 2 (getVoipCalls, recordings, active calls, reports, shares, PCAPs, CDR lists, audio graphs), direct links, SIP history retrieval, license checks, and resolving license lockout. The LDAP troubleshooting section provides step-by-step instructions for debugging LDAP login issues by testing the custom_login.php script from the command line. A new troubleshooting subsection addresses the specific issue where LDAP users can authenticate but cannot view CDRs despite being assigned to groups with correct permissions, explaining how to properly configure the is_admin flag and id_group variable. The license lockout resolution section explains three options when the GUI is locked due to exceeding the licensed channel limit: manually deleting CDRs from the database (self-service), upgrading the license tier, or contacting support for immediate lockout removal.
'''Summary:''' This article covers VoIPmonitor's custom login (LDAP/script examples, parameters), CDR HTTP API (inputs/outputs, examples), sharing CDRs, getting PCAPs, URL searches, HTTP API 2 (getVoipCalls, recordings, active calls, reports, shares, PCAPs, CDR lists, audio graphs), direct links, SIP history retrieval, license checks, and resolving license lockout. The LDAP troubleshooting section provides step-by-step instructions for debugging LDAP login issues by testing the custom_login.php script from the command line. A new troubleshooting subsection addresses the specific issue where LDAP users can authenticate but cannot view CDRs despite being assigned to groups with correct permissions, explaining how to properly configure the is_admin flag and id_group variable. The license lockout resolution section explains three options when the GUI is locked due to exceeding the licensed channel limit: manually deleting CDRs from the database (self-service), upgrading the license tier, or contacting support for immediate lockout removal. The getPCAP documentation now includes important troubleshooting guidance on using curl --data-urlencode to properly encode params strings, which is a common solution for API requests that return success:false responses.


'''Keywords:''' custom login, LDAP, LDAP troubleshooting, CLI testing, group permissions, is_admin, id_group, LDAP users cannot view CDR, groupIdNum, CDR API, HTTP API, getVoipCalls, getVoiceRecording, active calls, reportSummary, getShareURL, getPCAP, SIP history, license check, license lockout, concurrent calls limit, delete CDRs manually, license upgrade
'''Keywords:''' custom login, LDAP, LDAP troubleshooting, CLI testing, group permissions, is_admin, id_group, LDAP users cannot view CDR, groupIdNum, CDR API, HTTP API, getVoipCalls, getVoiceRecording, active calls, reportSummary, getShareURL, getPCAP, PCAP download, success:false API error, curl data-urlencode, URL encoding, params encoding, PCAP API curl example, SIP history, license check, license lockout, concurrent calls limit, delete CDRs manually, license upgrade


'''Key Questions:'''
'''Key Questions:'''
Line 840: Line 853:
* How to share CDRs via API?
* How to share CDRs via API?
* What is HTTP API 2 and its methods?
* What is HTTP API 2 and its methods?
* How to retrieve PCAP files via API?
* Why does getPCAP API return success:false?
* How to use curl --data-urlencode with getPCAP API?
* What is the correct curl syntax for getPCAP endpoint?
* How to URL encode params string in API requests?
* How to retrieve SIP history?
* How to retrieve SIP history?
* How to check VoIPmonitor license via API?
* How to check VoIPmonitor license via API?

Revision as of 04:48, 6 January 2026

Important: Correct API Endpoint Path

All API requests MUST be sent to the correct endpoint path:

  • Correct: /voipmonitor/php/api.php
  • Incorrect: /voipmonitor/api.php

Using the wrong path (missing the /php/ directory) will cause API calls to fail with various errors.

If your VoIPmonitor GUI is installed in the default web root (/var/www/html), use:

curl -X POST 'http://yourserver/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD'

If using a subdirectory like /demo:

curl -X POST 'http://yourserver/demo/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD'

Custom Login

VoIPmonitor supports custom authentication mechanisms (such as LDAP) via the custom_login.php script. This script intercepts login requests from the web GUI and allows you to validate credentials against external systems.

Important: Web API (HTTP API 2) authentication uses local VoIPmonitor database credentials directly and does NOT use custom_login.php or LDAP authentication. API requests submit user and password parameters that are validated against the local database.

LDAP Example

Complete LDAP example available in GUI directory: scripts/ldap_custom_login_example.php.

Ensure php-ldap package (or equivalent) is installed on the OS hosting the LDAP script.

Troubleshooting LDAP Login Issues

If LDAP authentication is working for the local admin user but failing for non-admin users, you can debug the script manually from the command line to isolate LDAP connectivity issues.

Step 1: Enable Debug Mode for CLI Testing

Edit the custom_login.php file and **uncomment the debug block** at the top of the script (if present):

# debug for manual run
if (!function_exists('debug_log')) {
function debug_log($txt) {
echo $txt . "\n";
}
}
# uncomment next line for test with manual run from command line (php SCRIPTNAME)
custom_login('testuser', 'testpass');
Step 2: Run Script Manually

Execute the script directly from the command line:

cd /var/www/html/scripts/
php custom_login.php

This will test the script with the hardcoded 'testuser' credentials and output any connection failure messages directly to the console.

Step 3: Check LDAP Server Configuration

Verify the LDAP server configuration in your script:

  • Check the $ldapsrvs variable contains correct LDAP server IP addresses
  • Verify the LDAP server ports are correct and accessible
  • Ensure network connectivity exists from the VoIPmonitor server to the LDAP endpoints

If the CLI test shows connection failures, verify network connectivity:

telnet <ldap_server_ip> <ldap_port>
# or
nc -zv <ldap_server_ip> <ldap_port>
Step 4: Verify Required Dependencies

Ensure the LDAP PHP extension is installed:

# Debian/Ubuntu
php -m | grep ldap
sudo apt-get install php-ldap

# CentOS/RHEL
php -m | grep ldap
sudo yum install php-ldap
Step 5: Check User Mapping

The custom_login function must return a valid array containing a required numeric unique identifier (id). If your script successfully authenticates against LDAP but users cannot log in, verify:

1. The user exists in the VoIPmonitor local database (users table) 2. The script correctly queries the local database to retrieve the user's ID 3. The returned array includes the id field

Create users in the GUI (Settings → Users) with the same usernames as in your LDAP directory if you require local user record mapping.

Step 6: LDAP Users Cannot View CDRs Despite Being Assigned to Groups

If LDAP users can authenticate successfully but cannot view CDRs even though they are assigned to groups with the correct permissions in the GUI, the issue is likely caused by the is_admin flag in your custom_login.php return array.

When is_admin is set to false (the default recommended setting), VoIPmonitor applies the group permissions from the user's local database record. However, if your script incorrectly includes is_admin with any value (even false itself), it may interfere with group-based permission inheritance depending on your specific configuration.

To fix this issue:

1. Ensure your script returns the correct id_group value that matches the group assigned in the GUI Users & Audit section.

2. Set is_admin to false (or omit it entirely to use default values) to allow group permissions to be applied correctly:

return(array(
    'username' => $user,
    'is_admin' => false,  // Allows group permissions to be applied
    'id' => $userIdUniqueNum,
    'id_group' => $groupIdNum,  // Must match GUI group ID
    // ... other parameters
));

3. Debug the $groupIdNum variable by running your script manually from the command line:

cd /var/www/html/scripts/
php custom_login.php

Check the debug output to verify that $groupIdNum is being assigned the correct integer value before the return statement.

4. Implement a fallback mechanism for users without a valid role to prevent login failures. For example:

if ($groupIdNum === 0){
    debug_log("User $user does not have valid permissions to login, setting the group 1 with low permissions");
    $groupIdNum = 1;
}

This ensures users without group mappings can still log in with restricted access rather than being completely blocked.

Custom Script

Custom login enables implementing your own mechanism. Create file: scripts/custom_login.php with function custom_login.

Location: <GUI_INSTALL_DIR>/scripts/custom_login.php

<?php
function custom_login($user, $password) {
        debug_log('custom_login');
        return(array(
                'username' => $user,
                'is_admin' => false,
                'id' => $userIdUniqueNum, // required numeric unique identifier for each user
// 'id_group' => 1, // you can set user rights with the gui's group id too
                'enable_sensors' => array(2,3)
        ));
}
?>

Returned array parameters:

  • enable_sensors - array(A,B,...) where the number is number of the sensor. If no enable_sensors provided the user will see all sensors CDR.
  • username
  • name
  • secret
  • id_group
  • group_name
  • group_blocked
  • can_cdr
  • can_write_cdr
  • can_play_audio
  • can_download_audio
  • can_listen_active_call
  • can_show_fax
  • can_pcap
  • can_upload_pcap
  • can_messages
  • can_view_content_message
  • can_view_message_url
  • is_admin
  • no_rtp
  • simple_cdr
  • hide_cdr_groups
  • can_graphs
  • can_tracker
  • can_activecalls
  • can_register
  • can_sip_msg
  • can_livesniffer
  • can_capture_rules
  • crules_remove_expire_time
  • can_audit
  • can_alerts_edit
  • can_alerts_show_sent
  • can_reports_edit
  • can_reports_show_sent
  • can_cdr_share_local_public
  • can_cdr_share_local_private
  • can_cdr_share_voipmonitor_org
  • hide_license_information
  • can_ipacc
  • can_mtr
  • can_show_sql_query
  • can_sensors_operations
  • show_only_connected_calls
  • can_dashboard
  • dashboard_read_only
  • can_report_functions
  • hide_change_password
  • hide_user_configuration
  • password_expired
  • can_svg_paint
  • can_3d_rtp_charts
  • can_network
  • can_edit_codebooks
  • can_edit_all_templates
  • can_delete_all_templates
  • ip
  • number
  • domain
  • vlan
  • custom_headers_cdr
  • custom_headers_message
  • ip_number_domain_or
  • note
  • email
  • blocked
  • blocked_reason
  • max_bad_login_attempt
  • password_expiration_days
  • enable_login_ip
  • uc_color_theme_shift_h
  • uc_color_theme_shift_s
  • uc_color_theme_shift_v
  • uc_color_theme_shift
  • uc_font_main_menu
  • uc_disable_confirm_before_unload
  • uc_enable_dns_cdr
  • uc_enable_dns_message
  • uc_enable_flags_cdr_number
  • uc_enable_flags_cdr_ip
  • uc_enable_flags_message_number
  • uc_enable_flags_message_ip
  • uc_csv_field_separator
  • count_audit_log
  • req_2fa

CDR HTTP API

Retrieves CDR rows in JSON, using WEB GUI filters: Call_Detail_Record_-_CDR#Filter_Form_button.

Requires valid session: GUI_automate_login. Send parameters via POST.

Disable authorization (safe environments): GUI > Settings > System Configuration > Disable authorization for API usage.

CURL Notes

Use -G and --data-urlencode for special characters (e.g., + in caller).

Example:

curl -G -X GET 'http://localhost/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' --data-urlencode 'params=[{"startTime":"2013-01-01","endTime":"2013-08-01","caller":"910251414414"},{"startTime":"2013-01-01","endTime":"2013-08-01","caller":"1+1","customHeaders":"Cell-ID-Caller,Cell-ID-Called"}]'

Input

HTTP POST address: php/model/sql.php

Mandatory Parameters

task:LISTING module:CDR
fdatefrom:DATE or fdateto:DATE is required due to mysql overloading

Suppress Results

suppress_results:1

will not list CDR but only {"total":"135"}

Datetime Range

fdatefrom:1986-01-09T00:00:00 fdateto:2013-05-28T00:00:00

Caller / Called Numbers

fcaller: caller num
fcalled: called num
fcallerd_type: 0 (if type is 0 searching is done for fcaller OR fcalled and value is taken from fcaller. If value is 1 searching is done for fcaller AND fcalled)

Domain

fcaller_domain: caller domain fcalled_domain: caller domain
fcallerd_domain_type:0 (if type is 0 searching is done for fcaller OR fcalled and value is taken from fcaller. If value is 1 searching is done for fcaller AND fcalled)

Caller ID Name

fcallername: caller name

SIP Caller / Called IP

fsipcallerip: caller SIP IP fsipcalledip: called SIP IP
fsipcallerdip_type:0 (if type is 0 searching is done for fcaller OR fcalled and value is taken from fcaller. If value is 1 searching is done for fcaller AND fcalled)

RTP Source / Destination IP

fa_saddr: 192.168.0.1
fb_saddr: 192.168.0.2
fab_saddr_type:0 (if type is 0 searching is done for fcaller OR fcalled and value is taken from fcaller. If value is 1 searching is done for fcaller AND fcalled)

Codecs

fcodec: 4, 12

list of numbers delimited by ','. Here is list of numbers and its codecs

define("PAYLOAD_PCMU", 0); define("PAYLOAD_GSM", 3); define("PAYLOAD_G723", 4); define("PAYLOAD_PCMA", 8); define("PAYLOAD_G722", 9); define("PAYLOAD_QCELP", 12); define("PAYLOAD_CN", 13); define("PAYLOAD_G729", 18); define("PAYLOAD_ILBC", 97); define("PAYLOAD_SPEEX", 98); define("PAYLOAD_SILK", 301); define("PAYLOAD_SILK8", 302); define("PAYLOAD_SILK12", 303); define("PAYLOAD_SILK16", 304); define("PAYLOAD_SILK24", 305); define("PAYLOAD_ISAC", 306); define("PAYLOAD_ISAC16", 307); define("PAYLOAD_ISAC32", 308); define("PAYLOAD_T38", 1000);

Call Duration

example: less than 30 and greater than 10 seconds

fdurationgt: 30 fdurationlt: 10

PDD

example: greater than 10 and less than 30 seconds

fpddgt: 10 fpddlt: 30

SIP Response Code

fsipresponse: 503

Interrupted Call

false or true

fbye:false

Direction (by trunk) false or true

ftrunk:

SIP user agent

fa_ua: caller agent string fb_ua: called agent string
fab_ua_type:0 (if type is 0 searching is done for fcaller OR fcalled and value is taken from fcaller. If value is 1 searching is done for fcaller AND fcalled)

SIP Call-ID header

fcallid: string

SIP sensor ID (database ID)

fsensor_id:

Paging

page:1 start:0 limit:30

Ordering

sort:[{"property":"calldate2","direction":"DESC"}]

Special Ordering

orderByLoss: orderByDelay: orderByFixed1: orderByFixed2: orderByAdapt: orderByCallDuration_asc: orderByCallDuration_desc: orderBySrcSIP_IP_asc: orderBySrcSIP_IP_desc: orderByDstSIP_IP_asc: orderByDstSIP_IP_desc: orderBySrcNumber_asc: orderBySrcNumber_desc: orderByDstNumber_asc: orderByDstNumber_desc: orderByCallerName_asc: orderByCallerName_desc: orderByLastSIPrespNum_asc: orderByLastSIPrespNum_desc:

RTP

frtcp_maxjitter: frtcp_avgjitter: frtcp_maxfr: frtcp_avgfr: fmosf1: fmosf2: fmosadapt: f_d50: f_d70: f_d90: f_d120: f_d150: f_d200: f_d300: floss1: floss2: floss3: floss4: floss5: floss6: floss7: floss8: floss9: floss10: ffilterTemplate:

Output

JSON formatted array of CDR.

GUI in Default DocumentRoot

Example for /var/www/html

curl -X POST '192.168.76.201/php/model/sql.php?module=bypass_login&user=voipmonitor&pass=voipmonitor'

returns something like this

{"SID":"ahs2ubdhc0ukb262be60v900ko","cookie_name":"PHPSESSID","success":true,"_vm_version":240034,"_debug":false}

take the SID which you will put to cookie_name variable

curl -X POST -k --cookie "PHPSESSID=ahs2ubdhc0ukb262be60v900ko" "http://192.168.76.201/php/model/sql.php?task=LISTING&module=CDR&fdatefrom=2013-05-08T00:00:00&fcaller=190"

GUI in Demo Subdirectory

Example for /var/www/html/demo

curl -X POST '192.168.76.201/demo/php/model/sql.php?module=bypass_login&user=voipmonitor&pass=voipmonitor'

returns something like this

{"SID":"ahs2ubdhc0ukb262be60v900ko","cookie_name":"PHPSESSID-demo","success":true,"_vm_version":240034,"_debug":false}

take the SID which you will put to cookie_name variable

curl -X POST -k --cookie "PHPSESSID-demo=ahs2ubdhc0ukb262be60v900ko" "http://192.168.76.201/demo/php/model/sql.php?task=LISTING&module=CDR&fdatefrom=2013-05-08T00:00:00&fcaller=190"

Example Output for LISTING Task

See attached link: output of the API LISTING task

Share CDR

Share CDR via request to php/model/utilities.php. For SIP+RTP, set type2 to "rtp"; for SIP only, type2:null.

Show Link Local Public

task=shareCdr&params={"type":"share_cdr_show","type2":null,"subType":"self_protected_link","id":[128024514],"emailFields":null}

Show Link Local Private

task=shareCdr&params={"type":"share_cdr_show","type2":null,"subType":"self_login_link","id":[128024514],"emailFields":null}

Show Link share.voipmonitor.org

task=shareCdr&params={"type":"share_cdr_show","type2":null,"subType":"share_link","id":[128024590],"emailFields":null}

Customizing share.voipmonitor.org Domain

To brand the share service with your own domain instead of using the default share.voipmonitor.org, edit the brand.php file in your GUI directory and add the following definitions:

define('BRAND_SHARESITE', 'share.yourdomain.fr');
define('BRAND_DOMAIN', 'yourdomain.fr');

Replace 'yourdomain.fr' with your actual domain. This causes share links to use your branded domain instead of share.voipmonitor.org.

Get PCAP File

GET or POST request with CDR ID:

http://voipmonitor/php/pcap.php?id=203800251

Optionally filter out RTP: disable_rtp=1

Search CDR by URL

Build URL for CDR display in browser:

http://localhost/admin.php?cdr_filter={fcallid:"uDR8mtloKFa1F8625VL2OXSFp.RuG73v"}

cdr_filter uses same arguments as WEB_API#CDR_HTTP_API

HTTP API 2

Preferred API for audio files by search criteria. Requests via HTTP POST or GET.

Rate Limit

Enable in GUI > Settings > System Configuration > API maximal concurrent connections. Limit per user.

getVoipCalls

Input Data

  • startTime - all calls which started >= startTime
  • startTimeTo - all calls which started <= startTimeTo (not mandatory)
  • callEnd - all calls which ends <= callEnd (not mandatory)
  • caller - caller number
  • called - called number
  • callId - Call-ID
  • id_sensor - sensor's number
  • msisdn - when you enter caller and called then cond is 'caller = 9999999 and called = 9999998'. With msisdn the cond is 'caller = 9999997 or called = 9999997'
  • cdrId - ID number in db
  • onlyConnected - 1 to get only connected calls (omit this parameter to retrieve all calls including unconnected)
  • [custom header name]: [custom header value], seach cdrs by this custom header value
  • customHeaders - the names of the returned custom header's values
task: getVoipCalls,
user: USER,
password: PASSWORD,
auditReason: reason text for audit log (not required),
params: {
 startTime: YYYY-MM-DD HH:II:SS,
 startTimeTo: YYYY-MM-DD HH:II:SS,
 callEnd: YYYY-MM-DD HH:II:SS,
 caller: 9999999,
 called: 9999999,
 callId: 'XXXXXXXXXXXXXXXXXXXXXX',
 id_sensor: 5,
 msisdn: 9999997,
 cdrId: 99999,
 onlyConnected: 1,  // Get only connected calls (omit this parameter for all calls including unconnected)
 [custom header name]: [custom header value],
 customHeaders: "Cell-ID-Caller,Cell-ID-Called"
}

Examples

HTTP POST Simple Parameter
echo '{"task": "getVoipCalls", "user": "USER", "password": "PASSWORD", "params": {"startTime": "2013-01-01", "endTime": "2013-08-01", "caller": "910251414414","customHeaders": "Cell-ID-Caller,Cell-ID-Called"}}' | php php/api.php
echo '{"task": "getVoipCalls", "user": "USER", "password": "PASSWORD", "params": {"startTime": "2023-01-01", "endTime": "2023-08-01", "callId": "a90eb404-4c12-363b-4812-56622343fbdf"}}' | php php/api.php
HTTP POST Array Parameter
echo '{"task": "getVoipCalls", "user": "USER", "password": "PASSWORD", "params": [{"startTime": "2013-01-01", "endTime": "2013-08-01", "caller": "910251414"},{"startTime": "2013-01-01", "endTime": "2013-08-01", "caller": "910251415", "customHeaders": "Cell-ID-Caller,Cell-ID-Called"}]}' | php php/api.php
HTTP GET Simple Parameter
http://localhost/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD&params={"startTime":"2013-01-01","endTime":"2013-08-01","caller":"910251414","customHeaders":"Cell-ID-Caller,Cell-ID-Called"}
HTTP GET Array Parameter
http://localhost/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD&params=[{"startTime":"2013-01-01","endTime":"2013-08-01","caller":"910251414"},{"startTime":"2013-01-01","endTime":"2013-08-01","caller":"910251415","customHeaders":"Cell-ID-Caller,Cell-ID-Called"}]

getVoiceRecording

Input Data

task: getVoiceRecording,
user: USER,
password: PASSWORD,
auditReason: reason text for audit log (not required),
params: {
     cdrId: 999999
     callId: 'XXXXXXXXXXXXXXXXXXXXXX',
     "CustomHeaderName": "CustomHeaderValue,
     calldate: '2015-03-01' //default value is current date, not used when cdrId set
}

or

params: { customHeader: 'name of the column in cdr_next table', customHeaderValue: 'your value', calldate: '2015-03-01' } //not recommended
Optional Parameters for Params
                 zip, ogg, : (true|false)
   saveaudio_afterconnect : ("yes"|"no")

Examples

HTTP POST
echo '{"task": "getVoiceRecording", "user": "USER", "password": "PASSWORD", "params": {"cdrId": "4919"}}' | php api.php
echo '{"task": "getVoiceRecording", "user": "USER", "password": "PASSWORD", "params": {"cdrId": [6,7],"saveaudio_afterconnect":"yes"}}' | php api.php > /tmp/m6_m7.wav.zip
echo '{"task": "getVoiceRecording", "user": "USER", "password": "PASSWORD", "params": {"callId": "XXXXXXXXXXXXXXXXXXXXXX"}}' | php api.php
echo '{"task": "getVoiceRecording", "user": "USER", "password": "PASSWORD", "params": {"Cust_header": "CustValue"}}' | php api.php
HTTP GET
http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD&params={"cdrId":4919}
http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD&params={"cdrId":4919,"saveaudio_afterconnect":"yes"}
http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD&params={"callId":"XXXXXXXXXXXXXXXXXXXXXX"}
http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD&params={"callId":"XXXXXXXXXXXXXXXXXXXXXX","cidInterval":10}
http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD&params={"callId":"XXXXXXXXXXXXXXXXXXXXXX","cidInterval":10,"saveaudio_afterconnect":"yes"}
http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD&params={"Cust_header":"CustValue"}

listActiveCalls

Input Data

task: listActiveCalls,
user: USER,
password: PASSWORD,
params: {
   sensorId: 'sensor number',
   callId: 'callId'
}
sensorId and callId are optional.

Examples

HTTP POST
echo '{"task": "listActiveCalls", "user": "USER", "password": "PASSWORD", "params": {"sensorId": "1"}}' | php api.php
HTTP GET
http://localhost/php/api.php?task=listActiveCalls&user=USER&password=PASSWORD&params={"sensorId":"1"}

handleActiveCall

Start/stop RTP recording. Pausing saves empty RTP frames to PCAP; affects 'Listening to Active call' (no audio from paused calls).

Input Data

task: handleActiveCall,
user: USER,
password: PASSWORD,
auditReason: reason text for audit log (not required),
params: {
  sensorId: 'sensor number',
  command: 'command (can be only pausecall/unpausecall now)',
  callRef: 'call reference'
}

Examples

HTTP POST
echo '{"task": "handleActiveCall", "user": "USER", "password": "PASSWORD", "params": {"sensorId": "1","command":"pausecall","callRef":"0x7f0e4c3c2680"}}' | php api.php
HTTP GET
http://localhost/php/api.php?task=handleActiveCall&user=USER&password=PASSWORD&params={"sensorId":"1","command":"pausecall","callRef":"0x7f0e4c3c2680"}

reportSummary

Generates a pre-configured summary report as an image. This is the only type of report available via the web API.

Important: Reports must be created in the GUI before use with the API.

Report Creation

Before using this API task: 1. Navigate to GUI → Reports → Daily Report 2. Create a new report of type summary 3. Fill in the Description field - this text becomes your report_name for API calls 4. Configure any charts or filters as needed for the report 5. Save the report

The API generates reports that have been pre-configured in the GUI - you cannot create new report configurations via the API.

Input Data

task: reportSummary,
user: USER,
password: PASSWORD,
params: {
   report_name: the Description field from your GUI report,
   datetime_from: datetime from (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
   datetime_to: datetime to (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
   json: true or false (returns JSON response instead of image)
}

Examples

HTTP POST
echo '{"task": "reportSummary", "user": "USER", "password": "PASSWORD", "params": {"report_name": "test summary", "datetime_from": "2017-12-20", "datetime_to": "2017-12-20"}}' | php api.php
HTTP GET
http://localhost/php/api.php?task=reportSummary&user=USER&password=PASSWORD&params={"report_name":"test summary","datetime_from":"2017-12-20","datetime_to":"2017-12-20"}

getShareURL

Parameters like getVoiceRecording. Returns public link for LEGs by CID. Use callId (SIP Call-ID string) or cdrId (database ID) to identify the call. If 'sip_history' true, only SIP history (RTP ignored).

Options: 'anonIps' anonymizes IPs/domains; 'validDays' limits validity.

Examples

HTTP GET (with RTP, by SIP Call-ID)
http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD&params={"callId":"1502262225","cidInterval":60,"rtp":true,"anonIps":true,"validDays":15}
http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD&params={"callId":"1502262225","rtp":true}
HTTP GET (by database ID/CdrId)
curl -G -X POST 'http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD' --data-urlencode 'params={"cdrId":"12345","rtp":true}'

This returns a URL in the format: http://localhost/master/cdr.php?cdrId=12345&hash=HASH_VALUE

HTTP GET (only SIP)
http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD&params={"callId":"1502262225","cidInterval":60}
http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD&params={"callId":"1502262225"}
HTTP GET (SIP History)
http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD&params={"callId":"1502262225","cidInterval":60, "sip_history": true}
http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD&params={"callId":"1502262225","sip_history": true}

getPCAP

Parameters like getVoiceRecording. Returns PCAP (merged legs if multiple in interval). Zip auto if multiple.

= curl with data-urlencode

Use -G and --data-urlencode to properly encode the params string, especially when it contains special characters or complex bracket structures. This prevents success:false responses due to malformed parameters.

HTTP GET (with cURL recommended)
curl -G -X GET 'http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD' --data-urlencode 'params={"callId":"1502262225","cidInterval":60,"cidMerge":true}'
HTTP POST (with cURL recommended for complex params)
curl -X POST 'http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD' \
  --data 'params={"callId":"1502262225","cidInterval":60}' \
  --data 'cidMerge=true' \
  --data 'zip=true'

Direct URL Examples (GET) =

These work for simple cases but may fail with special characters:

http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"cdrId":"76"}
http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"callId":"1502262225"}
http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD&params={"callId":"1502262225","cidInterval":60}

listCdrIds

Returns 'size' CDR records with basic info, starting from 'offset' ID.

Input Data

task: listCdrIds,
user: USER,
password: PASSWORD,
flags: number, //not required, bitfield format: 0x01 .. simpleOutput, 0x02 .. date in ISO8601 format
params: {
      offset: starting cdr id,
      size: number of cdr records to return
}}

Example

echo '{"task": "listCdrIds", "user": "USER", "password": "PASSWORD", "params": {"offset":"offset_num","size":"number of cdr records"}}' | php api.php

Request

task: listCdrIds,
user: USER,
password: PASSWORD,
flags: number, //not required, bitfield format: 0x01 .. simpleOutput, 0x02 .. date in ISO8601 format
params: json_encode: {
         offset: starting cdr id,
         size: number of cdr records to return
}

Example

http://localhost/php/api.php?task=listCdrIds&user=USER&password=PASSWORD&params={"offset":"offset_num","size":"number_of_cdr_records"}

getAudioGraph

Input Data

task: getAudioGraph,
user: USER,
password: PASSWORD,
params: {
    cdrId : number (CDR.id),
    type : S/P/ALL ( Spectrogram / Peaks=Waveform / ALL=including both types and both sides )
    side : L/R ( Left / Right )
    height: px
generating: 1 / 0 ( optional param, default 0, tells if audiograph data can be generated from packets in a spooldir. This parameter is needed if you don't use 'save_audiograph = yes' in the sensor config. If generating is 0 then the api call is looking only for created audiographs.)
}

Output

Depends on 'type' (zip if "type":"ALL"):

PNG image
zip file

Example

http://192.168.88.46/voipmonitor-git/gui/php/api.php?task=getAudioGraph&user=USER&password=PASSWORD&params={"cdrId":191,"type":"S","side":"R","height":"100"}

Direct Links

Active calls: index.php?activecalls=1&hidegrid=1&hidemenu=1

SIP History

Retrieves SIP history in various forms.

Parameters

action: action., currently brief_data, brief, getMSC actions. required
id: cdr id of the call, required
dns_lookup: 0|1 ... make dns lookup
ip_not_allowed: exclude this ips from the output (possibility to hide some internal information)

Example of Usage

# first get auth session
curl -X POST '192.168.76.201/php/model/sql.php?module=bypass_login&user=voipmonitor&pass=voipmonitor'
{"SID":"ahs2ubdhc0ukb262be60v900ko","cookie_name":"PHPSESSID","success":true,"_vm_version":240034,"_debug":false}
  • 'brief_data' action get SIP history data in JSON format
curl -X POST -k --cookie "PHPSESSID=ahs2ubdhc0ukb262be60v900ko" "http://192.168.76.201/php/pcap2text.php?action=brief_data&id=677&dns_lookup=0&ip_not_allowed=10.1.1.1,10.2.2.0/24
{"results":[{"num":"1","time":0,"src":"80.92.240.130","dst":"185.71.40.210","srcip":"80.92.240.130","dstip":"185.71.40.210","srcport":"5060","dstport":"5060","packet_len":"1046","direction":"-->","protocol":"SIP\/SDP","spec_type":null,"msg":"INVITE sip:2260@10.133.67.250:5060 len:1046","type":"request"},{"num":"2","time":0.054963111877441406,"src":"185.71.40.210","dst":"80.92.240.130","srcip":"185.71.40.210","dstip":"80.92.240.130","srcport":"5060","dstport":"5060","packet_len":"437","direction":"-->","protocol":"SIP","spec_type":null,"msg":"100 Trying len:437","type":"response"},{"num":"3","time":0.9610240459442139,"src":"185.71.40.210","dst":"80.92.240.130","srcip":"185.71.40.210","dstip":"80.92.240.130","srcport":"5060","dstport":"5060","packet_len":"588","direction":"-->","protocol":"SIP","spec_type":null,"msg":"180 Ringing len:588","type":"response"},{"num":"4","time":28.761795043945312,"src":"80.92.240.130","dst":"185.71.40.210","srcip":"80.92.240.130","dstip":"185.71.40.210","srcport":"5060","dstport":"5060","packet_len":"412","direction":"-->","protocol":"SIP","spec_type":null,"msg":"CANCEL sip:2260@10.133.67.250:5060 len:412","type":"request"},{"num":"5","time":28.795578002929688,"src":"185.71.40.210","dst":"80.92.240.130","srcip":"185.71.40.210","dstip":"80.92.240.130","srcport":"5060","dstport":"5060","packet_len":"433","direction":"-->","protocol":"SIP","spec_type":null,"msg":"200 OK len:433","type":"response"},{"num":"6","time":28.800518035888672,"src":"185.71.40.210","dst":"80.92.240.130","srcip":"185.71.40.210","dstip":"80.92.240.130","srcport":"5060","dstport":"5060","packet_len":"448","direction":"-->","protocol":"SIP","spec_type":null,"msg":"487 Request Cancelled len:448","type":"response"},{"num":"7","time":28.811052083969116,"src":"80.92.240.130","dst":"185.71.40.210","srcip":"80.92.240.130","dstip":"185.71.40.210","srcport":"5060","dstport":"5060","packet_len":"466","direction":"-->","protocol":"SIP","spec_type":null,"msg":"ACK sip:226@10.133.67.250:5060 len:466","type":"request"}],"total":7,"errors":{},"success":true,"_debug":false}
  • 'brief' action get SIP history in simple HTML format (as table tag)
curl -X POST -k --cookie "PHPSESSID=ahs2ubdhc0ukb262be60v900ko" "http://192.168.76.201/php/pcap2text.php?action=brief&id=677&dns_lookup=0&ip_not_allowed=10.1.1.1,10.2.2.0/24
  • 'genMSC' action get SIP history as diagram in HTML format
curl -X POST -k --cookie "PHPSESSID=ahs2ubdhc0ukb262be60v900ko" "http://192.168.76.201/php/pcap2text.php?action=getMSC&id=677&dns_lookup=0&ip_not_allowed=10.1.1.1,10.2.2.0/24

Check License

  • Basic test for license (covers ionCube issues):
'http://localhost:88/php/apilicensecheck.php?task=licenseCheck'
{"status":1,"message":"license file key.php expired. Current date: 2021-02-23 Expiration date: 2021-02-16"}
'http://localhost:88/php/apilicensecheck.php?task=licenseCheck'
{"status":0,"message":"License OK."}
  • Test concurrent calls limit (requires functional ionCube):
'http://localhost:88/php/apilicensecheck.php?task=licenseCallsLimitCheck'

Examples:

{"status":1,"message":"You have exceeded the license limit for concurrent calls and the system has been locked. Contact support."}
{"status":1,"message":"You have exceeded the license limit for concurrent calls. The system will be locked in 14 days. Contact support."}
{"status":0,"message":"Limit violation for 2nd consecutive day."}

Resolving License Lockout

If the GUI is locked due to exceeding the licensed channel limit for more than two consecutive days, you have the following options:

Manually Delete CDRs from Database (Self-Service Option)

Reduce the concurrent call count by deleting old CDR records from the database. This can be done directly via SQL:

-- Warning: This permanently deletes call records
-- Always backup before running DELETE operations

-- Delete CDRs older than a specific date (adjust date as needed)
DELETE FROM cdr WHERE calldate < '2024-01-01';

-- Delete specific CDRs by ID range
DELETE FROM cdr WHERE ID BETWEEN 1000 AND 5000;

After deleting CDRs, the system may need time to recalculate the concurrent call count. Monitor the license status using the API endpoint above.

Important Notes:

  • Deleting CDRs is permanent and cannot be undone
  • This only affects CDR records in the database, not captured audio files (PCAPs)
  • The concurrent call count is based on recent CDR data; deleting older records may reduce the count below the license limit
  • Always perform a full database backup before manual CDR deletion

Upgrade License Tier

Contact VoIPmonitor support to upgrade your license to a higher channel count tier:

  • Higher-tier licenses support more concurrent calls
  • Upgrading prevents future lockout issues
  • Contact via the customer portal or email to request a license upgrade

Contact Support for Lockout Removal

If you need immediate unlock without deleting CDRs:

  • Contact VoIPmonitor support via customer portal or email
  • State that the system is locked due to exceeding the concurrent call limit
  • Support can temporarily increase the limit or clear the lock on their end
  • After support clears the lock, verify via Tools > System Status > License and GUI status

AI Summary for RAG

Summary: This article covers VoIPmonitor's custom login (LDAP/script examples, parameters), CDR HTTP API (inputs/outputs, examples), sharing CDRs, getting PCAPs, URL searches, HTTP API 2 (getVoipCalls, recordings, active calls, reports, shares, PCAPs, CDR lists, audio graphs), direct links, SIP history retrieval, license checks, and resolving license lockout. The LDAP troubleshooting section provides step-by-step instructions for debugging LDAP login issues by testing the custom_login.php script from the command line. A new troubleshooting subsection addresses the specific issue where LDAP users can authenticate but cannot view CDRs despite being assigned to groups with correct permissions, explaining how to properly configure the is_admin flag and id_group variable. The license lockout resolution section explains three options when the GUI is locked due to exceeding the licensed channel limit: manually deleting CDRs from the database (self-service), upgrading the license tier, or contacting support for immediate lockout removal. The getPCAP documentation now includes important troubleshooting guidance on using curl --data-urlencode to properly encode params strings, which is a common solution for API requests that return success:false responses.

Keywords: custom login, LDAP, LDAP troubleshooting, CLI testing, group permissions, is_admin, id_group, LDAP users cannot view CDR, groupIdNum, CDR API, HTTP API, getVoipCalls, getVoiceRecording, active calls, reportSummary, getShareURL, getPCAP, PCAP download, success:false API error, curl data-urlencode, URL encoding, params encoding, PCAP API curl example, SIP history, license check, license lockout, concurrent calls limit, delete CDRs manually, license upgrade

Key Questions:

  • How to implement custom login in VoIPmonitor?
  • How to debug LDAP login issues from the command line?
  • What to do when non-admin users cannot log in via LDAP?
  • How to test LDAP connectivity in custom_login.php?
  • Why can LDAP users authenticate but not view CDRs even with correct group permissions?
  • How does the is_admin flag affect group permissions in custom_login.php?
  • How to set up id_group for LDAP users to inherit GUI group permissions?
  • What is the fallback mechanism for users without valid group roles?
  • What parameters does the CDR HTTP API support?
  • How to share CDRs via API?
  • What is HTTP API 2 and its methods?
  • How to retrieve PCAP files via API?
  • Why does getPCAP API return success:false?
  • How to use curl --data-urlencode with getPCAP API?
  • What is the correct curl syntax for getPCAP endpoint?
  • How to URL encode params string in API requests?
  • How to retrieve SIP history?
  • How to check VoIPmonitor license via API?
  • How to resolve GUI lockout due to exceeding licensed channel limit?
  • Can I manually delete CDRs to unlock a locked VoIPmonitor license?
  • How do I upgrade my VoIPmonitor license tier?
  • What are the options when the license concurrent calls limit is exceeded?