Analytics
3 endpoint-uri. Fiecare cale de mai jos este relativă la URL-ul de bază al API-ului și include deja prefixul /api/v1 — vezi convențiile pentru autentificare, paginare, erori și idempotență.
| Endpoint | ||
|---|---|---|
| GET | /analytics/overview | The §116 dashboard figures that belong to Observe |
| POST | /analytics/query | Run an ad-hoc analytics query and return timeseries, KPI, table, histogram, percentile or funnel results |
| GET | /analytics/vocabulary | The vocabulary a client needs to build a query UI without hard-coding it |
Endpoint-uri
The §116 dashboard figures that belong to Observe
GET/analytics/overview
- Necesită
analytics.read. - Window is always start-of-today to now in the given
timezonequery param (default UTC); it cannot be changed
bash
curl -X GET "$CALLAGENT_API_URL/analytics/overview" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/analytics/overview`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/analytics/overview');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.get(
f"{os.environ['CALLAGENT_API_URL']}/analytics/overview",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Răspunsuri
| Status | Corp |
|---|---|
200 | data-wrapped object |
Erori
| Status | Când apare |
|---|---|
403 | The API key lacks the analytics.read scope |
Exemplu de răspuns, generat din schemă:
json
{
"data": {
"range": {
"from": "+40712345678",
"to": "+40712345678",
"timezone": "string"
},
"calls_today": {
"value": 1,
"previous": 1,
"change_percent": 1,
"metric": "string",
"format": "2026-01-01T12:00:00+00:00",
"sample": 1
},
"minutes": {
"value": 1,
"previous": 1,
"change_percent": 1,
"metric": "string",
"format": "2026-01-01T12:00:00+00:00",
"sample": 1
},
"cost": {
"value": 1,
"previous": 1,
"change_percent": 1,
"metric": "string",
"format": "2026-01-01T12:00:00+00:00",
"sample": 1
},
"success_rate": {
"value": 1,
"previous": 1,
"change_percent": 1,
"metric": "string",
"format": "2026-01-01T12:00:00+00:00",
"sample": 1
},
"pickup_rate": {
"value": 1,
"previous": 1,
"change_percent": 1,
"metric": "string",
"format": "2026-01-01T12:00:00+00:00",
"sample": 1
},
"latency": {
"metric": "string",
"format": "2026-01-01T12:00:00+00:00",
"sample": 1,
"percentiles": {}
}
}
}Run an ad-hoc analytics query and return timeseries, KPI, table, histogram, percentile or funnel results
POST/analytics/query
- Necesită
analytics.read. - An invalid_query 422 uses {"error":{"code","message"}} instead of the platform's {"error":{"type",...}} envelope, so error type-switching breaks here
Corpul cererii
| Câmp | Tip | Obligatoriu | Note |
|---|---|---|---|
type | timeseries · kpi · table · histogram · percentile · funnel … | null | — | |
metric | string | null | — | |
metrics | string[] | null | — | |
dimension | string | null | — | |
filters | string[] | null | — | |
granularity | hour · day · week · month · null | null | — | |
preset | string | null | — | |
from | string | null | — | date-time |
to | string | null | — | date-time |
percentiles | string[] | null | — | |
buckets | integer | null | — | min 2. max 200 |
steps | string[] | null | — | |
limit | integer | null | — | min 1. max 1000 |
timezone | string | null | — |
bash
curl -X POST "$CALLAGENT_API_URL/analytics/query" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"type": "timeseries",
"granularity": "hour",
"from": "+40712345678",
"to": "+40712345678",
"buckets": 1,
"limit": 25
}'js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/analytics/query`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"type": "timeseries",
"granularity": "hour",
"from": "+40712345678",
"to": "+40712345678",
"buckets": 1,
"limit": 25
}),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/analytics/query');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'type' => 'timeseries',
'granularity' => 'hour',
'from' => '+40712345678',
'to' => '+40712345678',
'buckets' => 1,
'limit' => 25,
]),
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.post(
f"{os.environ['CALLAGENT_API_URL']}/analytics/query",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
json={
"type": "timeseries",
"granularity": "hour",
"from": "+40712345678",
"to": "+40712345678",
"buckets": 1,
"limit": 25
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Răspunsuri
| Status | Corp |
|---|---|
200 | data-wrapped object |
Erori
| Status | Când apare |
|---|---|
403 | The API key lacks the analytics.read scope |
422 | The payload failed validation, or the query itself was rejected as invalid |
Exemplu de răspuns, generat din schemă:
json
{
"data": {
"value": 1,
"previous": 1,
"change_percent": 1,
"metric": "string",
"format": "2026-01-01T12:00:00+00:00",
"sample": 1
}
}The vocabulary a client needs to build a query UI without hard-coding it
GET/analytics/vocabulary
- Necesită
analytics.read.
bash
curl -X GET "$CALLAGENT_API_URL/analytics/vocabulary" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/analytics/vocabulary`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/analytics/vocabulary');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.get(
f"{os.environ['CALLAGENT_API_URL']}/analytics/vocabulary",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Răspunsuri
| Status | Corp |
|---|---|
200 | data-wrapped object |
Erori
| Status | Când apare |
|---|---|
403 | The API key lacks the analytics.read scope |
Exemplu de răspuns, generat din schemă:
json
{
"data": {
"metrics": {},
"dimensions": {},
"widget_types": {},
"granularities": {}
}
}