NexysPBX API Tester

NexysCloud Internal Tool

Connection

📋 CDR Download
🔒 Security Audit
📖 Client Guide

Download Call Records

Security Audit

Runs 10 checks to verify this API key is correctly scoped: in-scope access works, all other actions are blocked, and the key cannot reach any other tenant (IDOR test). Write actions are sent with no parameters — they fail at validation before executing.

Overview

Your NexysPBX phone system exposes a JSON API that lets you pull your own call records directly into your application, spreadsheet, or reporting tool. The API is read-only and locked to your account — it cannot see other clients' data and cannot change anything on your system.

Your key is locked to one action (download call records), one tenant (your own account), and specific IP addresses you register with NexysCloud. Even if the key were compromised, it could only be used from your approved IPs.

The API URL format

Every request is a plain HTTPS GET to the following URL — just swap in your details:

https://IP_ADDRESS/?apikey=YOUR_KEY&action=pbxware.cdr.download&server=TENANT_ID&start=Mon-DD-YYYY&end=Mon-DD-YYYY

Date format

Dates must be in Mon-DD-YYYY format — three-letter month, two-digit day, four-digit year:

Jun-01-2026   ✔ correct
2026-06-01    ✘ wrong — will return a validation error
01/06/2026    ✘ wrong

Example — cURL (command line)

curl -k "https://169.239.11.11/?apikey=YOUR_KEY&action=pbxware.cdr.download&server=26&start=Jun-01-2026&end=Jun-30-2026"

The -k flag tells cURL to accept the server's self-signed certificate.

Example — Python

import requests, json

url = "https://169.239.11.11/"
params = {
    "apikey" : "YOUR_KEY",
    "action" : "pbxware.cdr.download",
    "server" : "26",
    "start"  : "Jun-01-2026",
    "end"    : "Jun-30-2026",
}

response = requests.get(url, params=params, verify=False)
data = response.json()

print(f"Total records: {data['records']}")
for call in data['csv']:
    print(call)

Example — JavaScript (Node.js / fetch)

const params = new URLSearchParams({
  apikey : 'YOUR_KEY',
  action : 'pbxware.cdr.download',
  server : '26',
  start  : 'Jun-01-2026',
  end    : 'Jun-30-2026',
});

const res  = await fetch(`https://169.239.11.11/?${params}`, { /* agent for self-signed cert */ });
const data = await res.json();

console.log('Calls this period:', data.records);
data.csv.forEach(row => console.log(row));

Response structure

{
  "success"   : "Success.",
  "next_page" : true,      // more pages available — see Pagination
  "limit"     : 99,        // records per page
  "records"   : 99,        // records on this page
  "header"    : ["From","To","Date/Time", ...],
  "csv"       : [
    ["27692712595","Reception (9001)","1780668765","45","45","","Answered","1780668735.114440","","False","",4.4],
    ...
  ]
}

Field reference — what each column means

#FieldExampleWhat it means
0From27692712595The caller's phone number (caller ID). This is the number of the person who called, in E.164 format without the + prefix.
1ToReception (9001)Who the call was routed to — includes the staff member or group name and their internal extension number in brackets.
2Date/Time1780668765Unix timestamp (seconds since 1 Jan 1970 UTC). Convert to a readable date with: new Date(val * 1000) in JS, or datetime.fromtimestamp(val) in Python.
3Total Duration45How long the call lasted in seconds, including ring time. For a missed call this is the ring time before the caller hung up.
4Rating Duration45Billable talk time in seconds — only counts once the call is answered. Zero for missed/failed calls.
5Rating Cost0.12Cost of the call in your configured currency (rand). Blank if cost rating is not enabled on your account.
6StatusAnsweredCall outcome: Answered (connected and talked), Not Answered (rang, nobody picked up), Failed (could not connect), Busy (line was busy).
7Unique ID1780668735.114440Internal call identifier. Use this to cross-reference a specific call. Has the format timestamp.sequence.
8Recording Path(empty)File path to the recording on the archive storage server, if archiving is configured. Empty when recordings are stored locally.
9Recording AvailableTrueWhether a recording exists for this call. True = the call was recorded; False = not recorded. Note: the audio file itself is not downloadable via this API — contact NexysCloud for access.
10Location TypeInternal routing classification (inbound, outbound, internal, etc.).
11MOS4.4Mean Opinion Score — a voice quality rating from 1 (very poor) to 5 (excellent). 4.0+ is good quality; below 3.5 indicates a network problem.

Pagination

The API returns up to 99 records per page. If next_page is true, there are more records. Fetch the next page by adding &page=2 (then &page=3, etc.) to your request until next_page is false.

https://IP/?apikey=KEY&action=pbxware.cdr.download&server=26&start=Jun-01-2026&end=Jun-30-2026&page=2

Error responses

Error messageCause and fix
IP or Hostname not allowedYour server's IP is not on the approved list. Contact NexysCloud to add it.
Selected action not allowedThe API key does not have permission for the action you called. Only pbxware.cdr.download is permitted.
Tenant not allowedThe server= value does not match your account's tenant ID. Use server=26.
Required field 'start=...' contains invalid dataDate format is wrong. Use Mon-DD-YYYY (e.g. Jun-01-2026), not ISO format.