Search calls and explain a call
Цей контент ще не доступний вашою мовою.
searchCalls finds calls by period, number, result and caller, newest first, and marks which calls have vendor attempts, a DID leg or a recording. getCallDetails takes one call from that list and returns all its records grouped by leg, plus a short diagnosis of what happened. Use them to answer “what happened to this call” without querying the customer, vendor and DID records one by one. The Calls screen of the panel is built on these two methods.
Both methods support trusted mode with i_customer.
Who sees what
Section titled “Who sees what”Any customer may call both methods. They show exactly what the call record screens of the panel show to that customer:
- Customer side: calls of the customer’s own accounts and of its direct sub-customers. The root customer is limited in the same way.
- Vendor attempts: the vendor, connection and cost of every routing attempt, only when the customer has system management rights.
- DID legs: only when the customer has the DID pool enabled.
The rights are read from the customer’s settings, never from the request. Each response returns them in rights, so you know which parts were left out.
Both methods read from the database replica, so a call that ended a few seconds ago may not be found yet.
searchCalls
Section titled “searchCalls”Returns one row per customer-side call record, newest first. A call that produced both an account record and a sub-customer record appears twice; side tells them apart.
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
start_date |
string | no | Start of the period by setup time, UTC: 20260115T13:30:00, 2026-01-15T13:30:00 or 2026-01-15 13:30:00. Default: today 00:00 UTC |
end_date |
string | no | End of the period, same formats. Default: now |
phone |
string | no | CLD patterns, see number patterns |
phone_field |
string | no | cld (default): the number after translation rules. cld_in: the number as received. cld_in is slower, it scans the whole period |
phone_clause |
int | no | How phone is matched: 0 like (default), 1 not like, 2 similar to, 3 not similar to |
phone_match |
string | no | begins, contains, ends or exact: adds the % wildcards for you to every phone pattern that has none. Only with phone_clause 0 or 1 |
cli |
string | no | CLI patterns, see number patterns |
cli_clause |
int | no | How cli is matched, same codes as phone_clause |
call_id |
string | no | SIP Call-ID patterns, matched like phone with clause 0 |
scope |
string | no | all (default): accounts and sub-customers. accounts: own accounts only. customers: sub-customers only |
i_account |
int | no | Only this account of yours. Returns account rows only |
i_sub_customer |
int | no | Only this sub-customer. Returns sub-customer rows only. Do not combine with i_account |
bt_pattern |
string | no | Batch tag of your accounts, a pattern with % and _. Does not filter sub-customer rows |
bt_clause |
int | no | 0 like (default), 1 not like, for bt_pattern |
i_account_class |
int | no | Only your accounts of this account class. Does not filter sub-customer rows |
result |
string | no | Which calls, see the table below. Default: non_zero_and_errors |
result_filter |
string | no | One result: 0_0 any (default), 0_1 OK, 0_100 any SIP response code, 1_<code> one SIP code such as 1_486, 2_<id> one internal error of the switch such as 2_7 |
duration_min |
double | no | Minimum duration, seconds |
duration_max |
double | no | Maximum duration, seconds |
cdr_currency |
string | no | ISO 4217 code that cost is converted to, with your exchange rates. Default: your base currency |
limit |
int | no | Rows per page. Default 100, maximum 1000; a larger value is cut to 1000 |
offset |
int | no | Rows to skip. Default 0 |
adaptive |
boolean | no | Default True: search the most recent minutes first and widen the window until the page is full. The rows are the same as without it, only faster. False runs one query over the whole period. A phone, cli or call_id filter turns it off |
result |
Calls returned | Panel label |
|---|---|---|
all |
Every call | All |
complete |
Answered calls (result 0) |
Complete |
incomplete |
Calls that failed with a SIP response code | Incomplete |
non_zero |
Calls with a duration above zero | Non-zero Duration |
errors |
Calls rejected by the switch with an internal error | Errors |
non_zero_and_errors |
non_zero and errors together |
Non-zero Duration & Errors |
The panel’s numeric codes are accepted too: 1 all, 2 incomplete, 3 non_zero_and_errors, 4 non_zero, 5 complete, 6 errors.
Number patterns
Section titled “Number patterns”phone, cli and call_id use the pattern syntax of the CLI and CLD filters in the panel:
- With clause
0(like) and1(not like), the value is a list of patterns separated by commas, semicolons or spaces, at most 50.%matches any characters and_one character. Nothing is added for you:38044%finds the prefix,38044only that exact number. Clause0returns calls that match any pattern, clause1calls that match none. - With clause
2(similar to) and3(not similar to), the value is one SQLSIMILAR TOpattern, for example(38044|38050)%. A pattern with unbalanced brackets or an empty alternative is rejected with the reason.
An exact number or a long prefix of 8 digits or more in phone or cli is the fastest search; a short prefix over a long period is the slowest.
Returns
Section titled “Returns”| Name | Type | Description |
|---|---|---|
result |
string | OK |
calls |
array | The rows, see below |
has_more |
boolean | True when another page exists. There is no total count |
offset |
int | The offset used |
limit |
int | The limit used |
currency |
string | Currency of cost |
narrowed_from |
string | Start of the window the adaptive search needed, UTC; empty (None) when the whole period was searched |
timing |
struct | Time spent per step on the server, in seconds. For troubleshooting only |
rights |
struct | system_mgmt and did_pool, booleans: whether vendor attempts and DID legs are visible to you |
Each row in calls:
| Name | Type | Description |
|---|---|---|
side |
string | account: the record of one of your accounts. customer: the record of a sub-customer |
i_call |
string | ID of the call. Pass it to getCallDetails as an int |
i_cdr |
string | ID of the record: the account record, or the sub-customer record when side is customer |
call_id |
string | SIP Call-ID |
setup_time |
string | Setup time, YYYY-MM-DD HH:MM:SS in UTC |
setup_epoch |
int | Setup time as a Unix timestamp. Pass it to getCallDetails |
connect_time, disconnect_time |
string | Connect and disconnect time in UTC; None when not set |
cli, cld |
string | The numbers after translation rules |
cli_in, cld_in |
string | The numbers as received |
i_account |
int | ID of the account, on account rows; None otherwise |
i_customer |
int | ID of the sub-customer, on customer rows; None otherwise |
owner_name |
string | Username of the account or name of the sub-customer |
duration, billed_duration |
double | Duration and billed duration, seconds |
cost |
double | Charge for the call, in currency |
result |
int | 0 answered, a SIP response code such as 486, or a negative internal error code |
result_text |
string | OK, Timeout, SIP error 486 or the description of the internal error |
delay |
double | Post-dial delay (PDD), seconds |
remote_ip |
string | IP address the call came from |
release_source |
string | Who ended the call, for example caller, callee or system |
prefix, area_name |
string | Billing prefix and destination name |
connected |
boolean | True when the call was answered and lasted more than zero seconds |
attempts |
int | Number of vendor attempts. None without system management rights |
attempts_failed |
int | Number of failed vendor attempts. None without system management rights |
has_recording |
boolean | True when the call has a recording, see getCallRecording |
has_did |
boolean | True when the call arrived on a DID. Always False without the DID pool |
Example
Section titled “Example”Find today’s failed calls to one number:
res = call("searchCalls", { "start_date": "2026-01-15 00:00:00", "end_date": "2026-01-15 23:59:59", "phone": "442079460000", "result": "incomplete", "limit": 20,})for row in res["calls"]: print(row["setup_time"], row["owner_name"], row["result_text"]){ "result": "OK", "calls": [ { "side": "account", "i_call": "8812345", "i_cdr": "9920411", "call_id": "5f0c2a91e7b34d18@192.0.2.10", "setup_time": "2026-01-15 13:42:07", "setup_epoch": 1768484527, "connect_time": None, "disconnect_time": "2026-01-15 13:42:31", "cli": "442071234567", "cld": "442079460000", "cli_in": "02071234567", "cld_in": "02079460000", "i_account": 3092, "i_customer": None, "owner_name": "1001", "duration": 0.0, "billed_duration": 0.0, "cost": 0.0, "result": 486, "result_text": "SIP error 486", "delay": 3.4, "remote_ip": "192.0.2.10", "release_source": "callee", "prefix": "44207", "area_name": "United Kingdom - London", "connected": False, "attempts": 2, "attempts_failed": 2, "has_recording": False, "has_did": False, }, ], "has_more": False, "offset": 0, "limit": 20, "narrowed_from": None, "currency": "USD", "timing": {"views": 0.004, "probe_all": 0.21, "fetch": 0.21, "page": 0.002, "markers": 0.03}, "rights": {"system_mgmt": True, "did_pool": True},}getCallDetails
Section titled “getCallDetails”Returns everything you may see about one call: the record of your account, the records of your sub-customers, the DID legs, every vendor attempt in routing order, and a diagnosis.
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
i_call |
int | yes | ID of the call, from searchCalls or a call record |
setup_epoch |
int | no | Setup time of the call as a Unix timestamp, from searchCalls. Speeds up the lookup; without it the switch looks the call up first |
The records are searched from the day before the call’s setup time to the day after it.
Returns
Section titled “Returns”| Name | Type | Description |
|---|---|---|
result |
string | OK |
call |
struct | i_call (string), call_id, setup_time (UTC), setup_epoch, cli, cld |
account_cdr |
struct | The record of your account, see leg fields. None when the call is not from one of your accounts |
customer_cdrs |
array | The records of your sub-customers, see leg fields |
dids |
array | The DID legs, see below. Empty without the DID pool |
attempts |
array | The vendor attempts in routing order, see below. Empty without system management rights |
has_recording |
boolean | True when the call has a recording |
diagnosis |
array | Notes on what happened, see diagnosis |
rights |
struct | system_mgmt and did_pool, as in searchCalls |
Leg fields
Section titled “Leg fields”account_cdr and each entry of customer_cdrs have these fields. Times are in UTC.
| Name | Type | Description |
|---|---|---|
cli_in, cld_in |
string | The numbers as received |
connect_time, disconnect_time |
string | Connect and disconnect time; None when not set |
connect_epoch, disconnect_epoch |
int | The same as Unix timestamps |
duration, billed_duration |
double | Duration and billed duration, seconds |
cost |
double | Charge for the call, in the currency of the account or sub-customer |
result, result_text |
int, string | Result, as in searchCalls |
delay |
double | Post-dial delay (PDD), seconds |
remote_ip |
string | IP address the call came from |
release_source |
string | Who ended the call |
prefix, area_name |
string | Billing prefix and destination name |
price_1, price_n |
double | Price of the first interval and of the next intervals. Account leg only; None on sub-customer legs |
connected |
boolean | True when the call was answered and lasted more than zero seconds |
account_cdr adds i_cdr (string), i_account, username, lrn_cld and lrn_cld_in (LRN lookup results), pdd1xx (seconds to the first provisional response) and i_protocol. Each sub-customer leg adds i_cdrs_customer (string), i_customer and customer_name.
DID legs
Section titled “DID legs”| Name | Type | Description |
|---|---|---|
side |
string | account: DID charge of your account. customer: DID charge of a sub-customer |
i_row |
string | ID of the DID record |
i_did, did |
int, string | ID and number of the DID |
owner_name |
string | Username of the account or name of the sub-customer |
i_account, i_customer |
int | Owner of the record; the other one is None |
setup_time, connect_time, disconnect_time |
string | Times in UTC |
duration, billed_duration, cost |
double | As on a leg |
result, result_text |
int, string | Result |
price_1, price_n |
double | DID prices used |
Vendor attempts
Section titled “Vendor attempts”| Name | Type | Description |
|---|---|---|
i_cdrs_connection |
string | ID of the vendor record |
i_vendor, vendor_name |
int, string | The vendor |
i_connection, connection_name, connection_destination |
int, string, string | The connection and its destination address |
setup_time, setup_epoch |
string, int | When the attempt started |
connect_time, disconnect_time |
string | Times in UTC |
cli_out, cld_out |
string | The numbers sent to the vendor |
duration, billed_duration, cost |
double | Duration and termination cost |
result, result_text |
int, string | Result of the attempt |
delay |
double | Post-dial delay (PDD) of the attempt, seconds |
remote_ip |
string | IP address the attempt was sent to |
release_source |
string | Who ended the attempt |
media_ip |
string | Media server that recorded the call; empty when not recorded |
connected |
boolean | True when the attempt was answered and lasted more than zero seconds |
Example
Section titled “Example”row = res["calls"][0] # a row from searchCallscard = call("getCallDetails", { "i_call": int(row["i_call"]), "setup_epoch": row["setup_epoch"],})for note in card["diagnosis"]: print(note["level"], note["text"]){ "result": "OK", "call": { "i_call": "8812345", "call_id": "5f0c2a91e7b34d18@192.0.2.10", "setup_time": "2026-01-15 13:42:07", "setup_epoch": 1768484527, "cli": "442071234567", "cld": "442079460000", }, "account_cdr": { "i_cdr": "9920411", "i_account": 3092, "username": "1001", "result": 486, "result_text": "SIP error 486", "delay": 3.4, "release_source": "callee", "connected": False, # … the other leg fields }, "customer_cdrs": [], "dids": [], "attempts": [ { "i_cdrs_connection": "7710233", "vendor_name": "Carrier A", "connection_name": "carrier-a-uk", "remote_ip": "198.51.100.20", "result": 503, "result_text": "SIP error 503", "connected": False, # … the other attempt fields }, { "i_cdrs_connection": "7710234", "vendor_name": "Carrier B", "connection_name": "carrier-b-uk", "remote_ip": "198.51.100.40", "result": 486, "result_text": "SIP error 486", "connected": False, # … the other attempt fields }, ], "has_recording": False, "diagnosis": [ {"code": "busy", "level": "warn", "text": "Destination is busy (486)."}, {"code": "all_attempts_failed", "level": "error", "text": "All 2 vendor attempt(s) failed, last: Carrier B (SIP error 486)."}, ], "rights": {"system_mgmt": True, "did_pool": True},}Diagnosis
Section titled “Diagnosis”diagnosis is a list of notes built by fixed rules from the call’s records. Each note has:
| Name | Type | Description |
|---|---|---|
code |
string | Stable identifier of the rule. Use it in your code |
level |
string | ok: information, nothing to fix. warn: the call worked or ended normally, but something is worth a look. error: the call failed, and the note names the reason |
text |
string | The note in English, with the numbers filled in. Not translated by l10n_lang; the wording may change, so do not parse it |
The rules look at the account leg, or at the first sub-customer leg when the call is not from one of your accounts. The notes come in this order.
1. Outcome. Exactly one of these, by the result of the leg:
code |
level |
When | text |
|---|---|---|---|
connected |
ok | Result 0 and duration above zero |
Call connected, duration 125 s. |
connected_zero |
warn | Result 0 but zero duration |
Call was answered but has zero duration. |
rejected_internal |
error | Negative result: the switch rejected the call itself with an internal error, before any vendor was tried | Rejected before routing: <description of the error>. |
timeout |
error | Result 1 to 199: no final answer in time |
No answer in time (timeout). |
busy |
warn | SIP 486 or 600 |
Destination is busy (486). |
no_answer |
warn | SIP 480, 408 or 487 |
Destination did not answer (480). |
forbidden |
error | SIP 401, 403 or 407 |
Call was refused (403). |
not_found |
error | SIP 404 |
Number not found (404). |
server_error |
error | SIP 500 and above, except 600 |
Operator side failure (503). |
sip_error |
error | Any other SIP response code | SIP error 484. |
2. Who ended the call. Only after connected, when the release source is known:
code |
level |
text |
|---|---|---|
released_by_caller |
ok | Released by the caller. |
released_by_callee |
ok | Released by the callee. |
released_by_system |
warn | Dropped by the system (limit, balance or timeout). The switch ended the call, not one of the parties |
3. Post-dial delay. slow_pdd, level warn, when the post-dial delay of the leg is 10 seconds or more: Slow to answer: post-dial delay 12.4 s.
4. Vendor attempts. Only when you have system management rights:
code |
level |
When | text |
|---|---|---|---|
no_attempts |
error | The call failed and no vendor was tried. Look at authentication and routing | No vendor was tried: the call stopped at authentication or routing. |
all_attempts_failed |
error | The call failed and every vendor attempt failed. The note names the last vendor and its result | All 3 vendor attempt(s) failed, last: Carrier B (SIP error 503). |
connected_after_retries |
warn | An attempt was answered, but only after other attempts | Connected after 3 attempt(s). |
duration_mismatch |
warn | The call was answered and the longest vendor attempt differs from the customer duration by more than 2 seconds. Check the billing of both sides | Customer and vendor durations differ (125 s vs 131 s). |
5. Extras.
code |
level |
When | text |
|---|---|---|---|
via_did |
ok | The call arrived on a DID. Only with the DID pool | Inbound via DID 442079460100. |
has_recording |
ok | The call has a recording. Get it with getCallRecording |
Recording available. |
The panel shows the notes translated by code; new codes may be added later, so show text for a code you do not know.
Errors
Section titled “Errors”| faultCode | faultString | Cause |
|---|---|---|
402 |
Unrecognized date format in start_date. |
start_date or end_date is not in one of the accepted formats |
402 |
start_date must not be later than end_date. |
The period is reversed |
402 |
Parameter <name> must be an integer., Parameter <name> must be a number., Parameter <name> is out of range. |
A paging, ID, clause or duration parameter has a wrong value, for example a negative offset |
402 |
Unknown scope: <value>, Unknown result filter: <value>, Unknown result_filter: <value>, Unknown phone_field: <value>, Unknown phone_match: <value>, Unknown clause: <value> |
A parameter has a value not listed above |
402 |
Too many patterns (max 50). |
phone, cli or call_id holds more than 50 patterns |
402 |
Unbalanced ")" in the pattern. and similar |
A similar-to pattern is malformed; the message names the problem |
402 |
The search took too long. Narrow the period or use a more specific number. |
searchCalls ran for more than 110 seconds |
402 |
Parameter i_call is required. |
getCallDetails without i_call |
404 |
Call not found or access denied. |
getCallDetails: no such call, or the call belongs to none of your accounts and sub-customers. The two cases are not told apart on purpose |
Related
Section titled “Related”- Call records (CDRs): the Calls screen that uses these methods
- Get the recording of a call
- Get CDRs of an account and Get CDRs of a customer
- Get SDP data of a call
- SIP response codes