cdrquery
GET /api/?service=cdrquery&sql=…
Retrieves call detail records (CDR) by running a SQL SELECT statement. Rows are returned as XML. The sql parameter must be sent in the URL query string.
The webserviceview table
The SQL queries are performed on the table webserviceview, a read-only view with one row per call attempt made from your system, which includes the following columns:
| Column | Type | Description |
|---|---|---|
id | int unsigned | Record number, unique and increasing. Use it to page through large result sets. |
cdr_campaign_name | varchar(50) | Campaign name. For API calls this is the spread_name you sent, or API custom dial. |
cdr_start_call | datetime | When the call attempt started, server local time (Israel). |
cdr_end_call | datetime | When the call attempt ended. |
cdr_totac_sec | smallint | Call duration in seconds. |
cdr_status | varchar(17) | Outcome of the attempt as text, for example answered, no answer or busy. Empty when the attempt has no final status yet. |
cdr_uniqueid | varchar(35) | Unique identifier of the call attempt in the telephony platform. |
cdr_campaign_id | int unsigned | Internal campaign number. 0 for calls placed through the API. |
cdr_contacts_id | int unsigned | Internal phone-book contact number. 0 for calls placed through the API. |
cdr_destination | bigint | Number called, as digits without a leading zero, for example 523456789. |
cdr_ddi | bigint | Caller number presented, as digits without a leading zero. |
cdr_private_field1 | varchar(50) | Your private_field1 value from the makecall request. |
cdr_private_field2 | varchar(50) | Your private_field2 value. |
cdr_private_field3 | varchar(50) | Your private_field3 value. |
cdr_meta_data | json | Additional details of the call recorded by the dialer, as a JSON document. Its keys depend on the call flow. |
Parameters
| Parameter | Description | Constraints |
|---|---|---|
sql (required) | A single SELECT statement, URL-encoded. | Must read from webserviceview and from no other table: exactly one FROM, no sub-queries, joins or unions. Avoid column aliases that contain the word "from". |
Writing efficient queries
- Always filter on
cdr_start_calland add aLIMIT. The view covers your system's whole call history. - Select only the columns you need.
cdr_meta_datacan be large; leave it out unless you use it. - Filter on
cdr_private_field1to find the result of one call you placed, or oncdr_campaign_nameto pull a whole campaign. - To fetch new records since your last poll, remember the highest
idyou received and queryWHERE id > {last_id} ORDER BY id LIMIT 1000.
Request examples
cURL
curl -G "https://dialer2.maskyoo.com/{system_name}/api/" \
-H "Authorization: Bearer 3f9c2a1e7b4d…" \
--data-urlencode "service=cdrquery" \
--data-urlencode "sql=SELECT id, cdr_start_call, cdr_destination, cdr_status, cdr_totac_sec, cdr_private_field1 FROM webserviceview WHERE cdr_start_call >= '2026-09-01' AND cdr_start_call < '2026-10-01' ORDER BY id LIMIT 500"
PHP
<?php
$sql = "SELECT id, cdr_start_call, cdr_destination, cdr_status, cdr_totac_sec, cdr_private_field1 FROM webserviceview WHERE cdr_start_call >= '2026-09-01' AND cdr_start_call < '2026-10-01' ORDER BY id LIMIT 500";
$url = "https://dialer2.maskyoo.com/{system_name}/api/?" . http_build_query([
"service" => "cdrquery",
"sql" => $sql, // must be in the query string, not a POST body
]);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer 3f9c2a1e7b4d…"],
CURLOPT_RETURNTRANSFER => true,
]);
$body = curl_exec($ch);
curl_close($ch);
$xml = @simplexml_load_string($body);
if ($xml === false) {
throw new RuntimeException("cdrquery rejected: " . trim($body)); // "error 2954:1" or "error 2954:2"
}
if (isset($xml->status) && (string)$xml->status === "Error") {
throw new RuntimeException("cdrquery SQL error: " . $xml->description);
}
foreach ($xml->row as $row) {
print_r((array)$row); // one associative array per call record
}
C#
using System.Net.Http;
using System.Net.Http.Headers;
using System.Xml.Linq;
var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "3f9c2a1e7b4d…");
var sql = "SELECT id, cdr_start_call, cdr_destination, cdr_status, cdr_totac_sec, cdr_private_field1 FROM webserviceview WHERE cdr_start_call >= '2026-09-01' AND cdr_start_call < '2026-10-01' ORDER BY id LIMIT 500";
var url = "https://dialer2.maskyoo.com/{system_name}/api/?service=cdrquery&sql=" + Uri.EscapeDataString(sql);
var body = await http.GetStringAsync(url);
if (!body.TrimStart().StartsWith("<"))
throw new Exception($"cdrquery rejected: {body.Trim()}"); // "error 2954:1" / "error 2954:2"
var root = XDocument.Parse(body).Root!;
if (root.Element("status")?.Value == "Error")
throw new Exception($"cdrquery SQL error: {root.Element("description")?.Value}");
foreach (var row in root.Elements("row"))
{
var record = row.Elements().ToDictionary(e => e.Name.LocalName, e => e.Value);
Console.WriteLine(string.Join(" | ", record.Select(kv => $"{kv.Key}={kv.Value}")));
}
Responses
Response — HTTP 200, success (XML rows)
<?xml version="1.0" encoding="utf-8" ?>
<root>
<row>
<id>184213</id>
<cdr_start_call>2026-09-03 10:15:42</cdr_start_call>
<cdr_destination>523456789</cdr_destination>
<cdr_status>ANSWERED</cdr_status>
<cdr_totac_sec>27</cdr_totac_sec>
<cdr_private_field1>APPT-48213</cdr_private_field1>
</row>
<row>
<id>184214</id>
<cdr_start_call>2026-09-03 10:16:05</cdr_start_call>
<cdr_destination>545550123</cdr_destination>
<cdr_status>NO ANSWER</cdr_status>
<cdr_totac_sec>0</cdr_totac_sec>
<cdr_private_field1>APPT-48214</cdr_private_field1>
</row>
</root>
Response — HTTP 200, SQL error (XML)
<?xml version="1.0"?>
<root>
<service>cdrquery</service>
<status>Error</status>
<description>1054: Unknown column 'calldate' in 'where clause'</description>
</root>
Response — HTTP 200, validation error (plain text)
error 2954:2
All responses of this service
| HTTP | Format | Body | Meaning |
|---|---|---|---|
| 200 | XML | <root><row>…</row>…</root> | One row per record, one child element per selected column, named after the column. No matches gives <root></root>. |
| 200 | XML | <status>Error</status> <description>1054: Unknown column 'x' in 'field list'</description> | SQL error, with the database error number and text. |
| 200 | text | error 2954:1 | The statement contains more than one FROM. |
| 200 | text | error 2954:2 | The statement does not read from webserviceview, or names it more than once. |