WEB API: Difference between revisions

From VoIPmonitor.org
(Add important note about query parameter syntax - use equals signs not colons)
(Add wildcard URL encoding keywords to AI Summary)
Line 972: Line 972:
=== 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, resolving license lockout, and GUI configuration. 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. The branding customization section explains how to replace the default "VoIPmonitor" product name in the GUI header and alert emails using the BRAND_NAME constant in system_configuration.php, as well as how to configure custom share domain using brand.php. The listActiveCalls endpoint enables programmatic retrieval of currently active calls from all connected probes, which is essential for real-time monitoring and automation scripts that need to check if a specific phone number is currently in a call.
'''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, resolving license lockout, and GUI configuration. 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. The branding customization section explains how to replace the default "VoIPmonitor" product name in the GUI header and alert emails using the BRAND_NAME constant in system_configuration.php, as well as how to configure custom share domain using brand.php. The listActiveCalls endpoint enables programmatic retrieval of currently active calls from all connected probes, which is essential for real-time monitoring and automation scripts that need to check if a specific phone number is currently in a call. A new section on "Using Wildcards in Filters" explains how to use the percent sign (%) wildcard in API filter parameters, which must be URL-encoded as %25 when passed in API requests. This is critical when filtering caller numbers, called numbers, or other fields using LIKE patterns.


'''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, listActiveCalls, programmatic active calls, real-time call monitoring, check active calls programmatically, 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, branding, BRAND_NAME, brand.php, system_configuration.php, custom company name, customize GUI header, customize alert emails, share.voipmonitor.org, BRAND_SHARESITE, BRAND_DOMAIN
'''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, listActiveCalls, programmatic active calls, real-time call monitoring, check active calls programmatically, 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, branding, BRAND_NAME, brand.php, system_configuration.php, custom company name, customize GUI header, customize alert emails, share.voipmonitor.org, BRAND_SHARESITE, BRAND_DOMAIN, wildcard, wildcards, LIKE filter, percent sign, %25, URL encode percent, API filter, wildcard filter, SQL LIKE, caller filter, called filter, fcaller, fcalled


'''Key Questions:'''
'''Key Questions:'''
Line 993: Line 993:
* What is the correct curl syntax for getPCAP endpoint?
* What is the correct curl syntax for getPCAP endpoint?
* How to URL encode params string in API requests?
* How to URL encode params string in API requests?
* How to use wildcards in API filter parameters?
* How to filter caller numbers using LIKE pattern in API?
* Do I need to URL encode the percent sign (%) when using wildcards in API?
* How to use %25 wildcard character in API requests?
* How to filter for caller numbers starting with specific prefix using API?
* Does the percent sign wildcard need encoding when used in GET parameters?
* 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 08:22, 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 5.5: Ensure Unique User IDs for Individual Settings

Critical: Each LDAP user must return a unique numeric identifier in the id field. If multiple LDAP users return the same id, they will share ALL user settings including timezone, dashboard preferences, and other GUI customizations.

Symptoms of Non-Unique IDs

If your LDAP users see settings changing unexpectedly or appearing to be shared (e.g., changing timezone for one user affects all users), your script is likely returning the same id for all users.

Extracting Unique IDs from LDAP

To ensure each LDAP user has a unique identity, retrieve a unique identifier from your LDAP directory such as uidnumber:

<?php
function custom_login($user, $password) {
    // Connect to LDAP server and authenticate $user/$password
    $connect = ldap_connect('ldap://your-ldap-server');
    ldap_bind($connect, $ldap_user, $ldap_password);

    // Search for the user
    $search = ldap_search($connect, $dn, "(uid=$user)", array('uidnumber', 'cn'));
    $res_id = ldap_get_entries($connect, $search);

    // Extract unique identifier from LDAP
    $userIdUniqueNum = 0;  // Default invalid ID that will cause login fail
    if (isset($res_id[0]['uidnumber'][0])) {
        // Use LDAP uidnumber as unique identifier
        $userIdUniqueNum = (int)$res_id[0]['uidnumber'][0];
    } else if (isset($res_id[0]['cn'][0])) {
        // Fallback: use CRC hash of cn as unique ID
        $userIdUniqueNum = crc32($res_id[0]['cn'][0]);
    }

    return(array(
        'username' => $user,
        'is_admin' => false,
        'id' => $userIdUniqueNum,  // MUST be unique for each user!
    ));
}
?>

Common Mistakes to Avoid:

  • Hardcoded ID: Returning a constant like 'id' => 1 for all users (everyone shares settings)
  • Missing ID: Omitting the id field entirely (login will fail)
  • String ID: Returning a username string instead of a number (ID must be numeric)
  • Non-numeric ID: Using uid string instead of uidnumber integer
Testing Unique ID Logic

Verify that different users return different IDs by running your script manually:

cd /var/www/html/scripts/
PHP_USER=user1 php -r 'require "custom_login.php"; var_dump(custom_login("user1", "test"));'
PHP_USER=user2 php -r 'require "custom_login.php"; var_dump(custom_login("user2", "test"));'

Ensure the ["id"] values differ between users.

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

Important: Query Parameter Syntax

When building API requests, use **equals signs (=)** for parameter assignment in HTTP query strings, not colons.

  • Correct: &fcallerd_type=1&
  • Incorrect: &fcallerd_type:1&

The wiki documentation uses colons to separate parameter names from descriptions (e.g., fcaller: caller num), which is standard documentation format. However, in actual HTTP requests you must use the equals sign for parameter assignment.

Common Syntax Mistakes:

If your filters are not working (e.g., changing the called domain filter does not affect results), double-check that you are using = instead of : in your parameter syntax.

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)

Using Wildcards in Filters

You can use wildcard characters in API filter parameters. However, the % character (used for SQL LIKE patterns) must be URL-encoded as %25 when passed in API requests.

Example: Filter for caller numbers starting with "00"

curl -G -X GET 'http://localhost/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' --data-urlencode 'params={"startTime":"2023-01-01","endTime":"2023-12-31","caller":"%2500"}'

Important Notes:

  • Use %25 to represent a literal % wildcard character in the URL
  • % followed by any two digits in a URL query string is interpreted as a URL-encoded character
  • Without encoding, %25 would be decoded as just %, but the API needs to receive the %25 characters to construct the SQL LIKE pattern correctly
  • The --data-urlencode flag in curl handles this automatically for you

Common wildcard patterns:

  • %2500 - matches caller numbers starting with "00"
  • 123% - matches caller numbers starting with "123" (no encoding needed when % is at the end)
  • %25abc - matches caller numbers containing "abc" anywhere

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 Branding

You can customize VoIPmonitor branding in three ways:

Customizing Product Name

To replace the default "VoIPmonitor" name in the GUI header and alert emails with your own company name, edit the system_configuration.php file:

// File location: ./gui/config/system_configuration.php
define('BRAND_NAME', 'YourCompany');

After making this change: 1. Save the file 2. Log out of the GUI 3. Log back in for the changes to take effect

The new name will appear in the GUI header and in alert emails.

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:

// File location: ./gui/brand.php
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"}
Response Format and IP Address Conversion

The API returns a JSON object with an array of active calls under the rows key.

Important: IP Address Format

The callerip and calledip fields in the response are integer representations of IP addresses, not dotted-decimal format.

To convert these to standard dotted-decimal format:

  • For IPv4: Use INET_NTOA() function in MySQL or similar conversion in your application code
  • For IPv6: Use INET6_NTOA() function

Example MySQL query for conversion:

SELECT INET_NTOA(callerip) as caller_ip, INET_NTOA(calledip) as called_ip FROM live;

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, resolving license lockout, and GUI configuration. 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. The branding customization section explains how to replace the default "VoIPmonitor" product name in the GUI header and alert emails using the BRAND_NAME constant in system_configuration.php, as well as how to configure custom share domain using brand.php. The listActiveCalls endpoint enables programmatic retrieval of currently active calls from all connected probes, which is essential for real-time monitoring and automation scripts that need to check if a specific phone number is currently in a call. A new section on "Using Wildcards in Filters" explains how to use the percent sign (%) wildcard in API filter parameters, which must be URL-encoded as %25 when passed in API requests. This is critical when filtering caller numbers, called numbers, or other fields using LIKE patterns.

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, listActiveCalls, programmatic active calls, real-time call monitoring, check active calls programmatically, 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, branding, BRAND_NAME, brand.php, system_configuration.php, custom company name, customize GUI header, customize alert emails, share.voipmonitor.org, BRAND_SHARESITE, BRAND_DOMAIN, wildcard, wildcards, LIKE filter, percent sign, %25, URL encode percent, API filter, wildcard filter, SQL LIKE, caller filter, called filter, fcaller, fcalled

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 use wildcards in API filter parameters?
  • How to filter caller numbers using LIKE pattern in API?
  • Do I need to URL encode the percent sign (%) when using wildcards in API?
  • How to use %25 wildcard character in API requests?
  • How to filter for caller numbers starting with specific prefix using API?
  • Does the percent sign wildcard need encoding when used in GET parameters?
  • 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?
  • How to replace the default VoIPmonitor branding with a custom company name?
  • How to change the product name in the GUI header and alert emails?
  • How to use BRAND_NAME constant to customize VoIPmonitor branding?
  • How to customize share.voipmonitor.org domain with my own domain?
  • How to use brand.php for custom branding in VoIPmonitor?
  • How do I programmatically check if a call to a specific phone number is currently active?
  • What is the listActiveCalls API used for?
  • How to retrieve active calls from all connected sensors via API?
  • What is the difference between listActiveCalls and getVoipCalls?