Calls, CDR & quick stats

Dashboard-style totals, calls in progress right now, a customer's call history, internal (extension-to-extension) calls, and the Asterisk queue log.

quickstats_get

The same totals as the product's dashboard: this month and today, call count and duration, and — for staff accounts — revenue and margin.

Who may call it: admin, reseller or plain user only — not accountant, not partner.

ParameterRequiredMeaning
uYesCaller's username — this is also the whole fixed hash order.
Note

Hash parameter order: normally just u — except when u is literally admin: then the order is empty and the hash is SHA1(secret key) alone. This exception exists for exactly two methods, this one and local_calls_get below — it does not apply to active_calls_get, even though that one also has a single-parameter u order.

curl -X POST https://api.example.com/api/quickstats_get \
  -d "u=admin" \
  -d "hash=PLACEHOLDER_HASH"
<page>
  <quickstats>
    <this_month>
      <calls>128</calls>
      <duration>46210</duration>
      <revenue>54.20</revenue>
      <self_cost>31.10</self_cost>
      <profit>23.10</profit>
      <margin>42.6</margin>
    </this_month>
    <today>...</today>
    <active_calls>
      <total>2</total>
      <answered_calls>1</answered_calls>
    </active_calls>
  </quickstats>
</page>

<duration> is the technical call duration in seconds (the sum of billsec), not the customer-facing duration shown elsewhere in the product — this one stayed on the old definition deliberately, for compatibility with existing integrations. revenue/self_cost/profit/margin and the whole active_calls block are left out for a plain user caller. Error: Access Denied.

The dashboard's Quick stats — the same totals quickstats_get returns.

active_calls_get

Calls in progress right now.

Who may call it: admin, accountant or reseller always; a plain user only if the installation has switched on Show Active Calls for Users.

ParameterRequiredMeaning
uYesCaller's username — the whole fixed hash order (no exception this time).
curl -X POST https://api.example.com/api/active_calls_get \
  -d "u=admin" \
  -d "hash=PLACEHOLDER_HASH"
<page>
  <active_call>
    <id>58213</id>
    <status>Answered</status>
    <answer_time>00:00:12</answer_time>
    <duration>00:01:47</duration>
    <src>1010</src>
    <user>Demo Company</user>
    <device_name>SIP/1010</device_name>
    <localized_dst>...</localized_dst>
    <dst_user></dst_user>
    <dst_device_name></dst_device_name>
    <destination_name>...</destination_name>
    <provider_name>Demo Carrier</provider_name>
    <channel>PJSIP/1010-00000012</channel>
  </active_call>
</page>

provider_name only appears for admin/accountant, channel only for admin. No active calls answers <page><message>No_data_found</message></page> — that literal, untranslated string, not a sentence. Errors: Access Denied (anonymous), You are not authorized to use this functionality.

Live calls in the product — the same fields active_calls_get returns, updating in real time.

user_calls_get

One customer's billed calls over a period — the API equivalent of the Calls list filtered to one user.

Who may call it: any account type. A plain user always gets their own calls; a reseller passes s_user to pick one of their own customers (or all/blank for every customer they own); admin/accountant pass a numeric s_user or leave it blank for everyone.

ParameterRequiredIn hashMeaning
uYes—Caller's username.
period_start / period_endNo1st, 2ndUnix timestamps; default to today.
s_userNo3rdTarget customer id, or all.
s_call_typeNo4thall (default), answered, busy, no_answer, failed.
s_deviceNo5thNumeric device id, restricts to calls from that device.
s_providerNo6thAdmin/accountant/reseller only.
s_uniqueidNo7thLook up one exact call by its CDR unique id.

Hash parameter order: period_start, period_end, s_user, s_call_type, s_device, s_provider, s_uniqueid — only the ones you send.

curl -X POST https://api.example.com/api/user_calls_get \
  -d "u=admin" \
  -d "s_user=3031" \
  -d "hash=PLACEHOLDER_HASH"
<page>
  <pagename>Calls</pagename>
  <language>en</language>
  <error_msg></error_msg>
  <userid>0</userid>
  <username>admin</username>
  <total_calls>3</total_calls>
  <currency>EUR</currency>
  <calls_stat>
    <period><period_start>...</period_start><period_end>...</period_end></period>
    <show_user>3031</show_user>
    <show_device>all</show_device>
    <show_status>all</show_status>
    <calls>
      <call>
        <calldate2>2026-09-24 10:03:11</calldate2>
        <timezone>GMT +00:00</timezone>
        <src>1010</src>
        <dst>...</dst>
        <disposition>ANSWERED</disposition>
        <billsec>42</billsec>
        <nice_billsec>42</nice_billsec>
        <user_rate>0.0120</user_rate>
        <user_price>0.0084</user_price>
        <provider_id>515</provider_id>
        <provider_rate>0.0080</provider_rate>
        <provider_price>0.0056</provider_price>
        <reseller_price>0.0000</reseller_price>
        <hangupcause>16</hangupcause>
        <uniqueid>...</uniqueid>
      </call>
    </calls>
  </calls_stat>
</page>

provider_id/provider_rate/provider_price/reseller_price are left out for a plain user caller. Errors: Dont_be_so_smart (no caller), User was not found.

Also reachable as: /api/user_calls.

local_calls_get

Internal calls — extension to extension, never leaving the PBX.

Who may call it: admin, reseller, accountant or plain user — not a partner.

ParameterRequiredMeaning
uYesCaller's username — the whole fixed hash order, except when it's literally admin (see quickstats_get above — same exception applies here).
from / tillNoUnix timestamps; default to today. Must actually be numeric, and from can't be after till.
s_useridNoAdmin/reseller/accountant only: restrict to one customer's internal calls, must be owned by the caller.
curl -X POST https://api.example.com/api/local_calls_get \
  -d "u=admin" \
  -d "hash=PLACEHOLDER_HASH"
<page>
  <local_calls>
    <call>
      <calldate><date>2026-09-24 10:04:02</date><timezone>GMT +00:00</timezone></calldate>
      <originator_device>SIP/1010</originator_device>
      <originator_caller_id>1010</originator_caller_id>
      <orignator_ip></orignator_ip>
      <orignator_channel></orignator_channel>
      <terminator_user>...</terminator_user>
      <terminator_device>SIP/1004</terminator_device>
      <terminator_ip></terminator_ip>
    </call>
  </local_calls>
</page>

orignator_ip and orignator_channel are spelled exactly like that in the response — an existing misspelling kept for compatibility, not a mistake in this reference; a client parsing the XML has to match the misspelling. Errors: Access Denied, From must be valid timestamp, Till must be valid timestamp, Date from is greater than date till, User was not found, No calls... (with the ellipsis).

queue_log_get

Raw entries from Asterisk's own queue_log file, filtered by time and, optionally, queue/agent/event/call id.

Who may call it: admin only.

ParameterRequiredMeaning
uYesCaller's username.
from / tillNoUnix timestamps; default to today.
queuename / agent / event / callid / data1 / data2NoExact-match filters on the corresponding queue-log fields.

Hash parameter order: deliberately empty, by design (declared that way in the code, the same as subscriptions_get on the billing page) — a normal call hashes to SHA1(secret key) alone, whatever filters you send.

curl -X POST https://api.example.com/api/queue_log_get \
  -d "u=admin" \
  -d "hash=PLACEHOLDER_HASH"
<page>
  <queues>
    <queue>
      <id>1</id>
      <time>2026-09-24 09:00:03</time>
      <call_id>...</call_id>
      <queue_name>Demo Queue</queue_name>
      <agent>...</agent>
      <event>ENTERQUEUE</event>
      <data1></data1>
      <data2></data2>
      <data3></data3>
      <data4></data4>
      <data5></data5>
    </queue>
  </queues>
</page>

Errors: Access Denied (not admin), Queue log is not available on this server (the log file isn't reachable), No data found (no lines matched — note: no ellipsis here, unlike local_calls_get's No calls...).

Check

Call quickstats_get as admin and compare this_month/calls against the number shown on the product's own dashboard.