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.
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.
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
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
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.
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)
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));
{
"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 | Example | What it means |
|---|---|---|---|
| 0 | From | 27692712595 | The caller's phone number (caller ID). This is the number of the person who called, in E.164 format without the + prefix. |
| 1 | To | Reception (9001) | Who the call was routed to — includes the staff member or group name and their internal extension number in brackets. |
| 2 | Date/Time | 1780668765 | Unix 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. |
| 3 | Total Duration | 45 | How long the call lasted in seconds, including ring time. For a missed call this is the ring time before the caller hung up. |
| 4 | Rating Duration | 45 | Billable talk time in seconds — only counts once the call is answered. Zero for missed/failed calls. |
| 5 | Rating Cost | 0.12 | Cost of the call in your configured currency (rand). Blank if cost rating is not enabled on your account. |
| 6 | Status | Answered | Call outcome: Answered (connected and talked), Not Answered (rang, nobody picked up), Failed (could not connect), Busy (line was busy). |
| 7 | Unique ID | 1780668735.114440 | Internal call identifier. Use this to cross-reference a specific call. Has the format timestamp.sequence. |
| 8 | Recording Path | (empty) | File path to the recording on the archive storage server, if archiving is configured. Empty when recordings are stored locally. |
| 9 | Recording Available | True | Whether 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. |
| 10 | Location Type | Internal routing classification (inbound, outbound, internal, etc.). | |
| 11 | MOS | 4.4 | Mean 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. |
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 message | Cause and fix |
|---|---|
IP or Hostname not allowed | Your server's IP is not on the approved list. Contact NexysCloud to add it. |
Selected action not allowed | The API key does not have permission for the action you called. Only pbxware.cdr.download is permitted. |
Tenant not allowed | The server= value does not match your account's tenant ID. Use server=26. |
Required field 'start=...' contains invalid data | Date format is wrong. Use Mon-DD-YYYY (e.g. Jun-01-2026), not ISO format. |