curl --request GET \
--url https://api.sidenet.ai/v1/requests/stats \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.sidenet.ai/v1/requests/stats"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.sidenet.ai/v1/requests/stats', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sidenet.ai/v1/requests/stats",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.sidenet.ai/v1/requests/stats"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.sidenet.ai/v1/requests/stats")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sidenet.ai/v1/requests/stats")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"resolution": "day",
"totals": {
"requests": 1284,
"errors": 12,
"threads": 611,
"users": 402,
"messages": 1190,
"cost": 14.72,
"avg_latency_ms": 3870,
"input_tokens": 1820400,
"output_tokens": 240310,
"scoring_runs": 320,
"scoring_cost": 0.64
},
"series": [
{
"bucket": "2026-10-27T00:00:00+00:00",
"requests": 61,
"errors": 1,
"users": 24,
"cost": 0.71,
"scoring_cost": 0.02,
"avg_latency_ms": 3550
}
],
"by_group": [
{
"group_id": 7,
"external_id": "grp_84f20c19",
"name": "Acme",
"requests": 900,
"errors": 8,
"users": 300,
"cost": 10.4,
"avg_latency_ms": 3900
}
],
"by_agent": [
{
"agent_id": "6f1c0f4e-2b7a-4a51-9a2f-0c9d1b3e5a10",
"name": "Support",
"requests": 850,
"errors": 8,
"cost": 9.9,
"avg_latency_ms": 4100
}
],
"by_workflow": [
{
"workflow_id": "4c2f9e18-7a63-4d05-b1e8-93a7c0f2d641",
"name": "Nightly digest",
"requests": 30,
"errors": 0,
"cost": 1.5,
"avg_latency_ms": 30000
}
],
"by_model": [
{
"model": "openai/gpt-4o",
"calls": 870,
"cost": 12.1,
"input_tokens": 1700000,
"output_tokens": 221000
}
],
"by_tool": [
{
"tool": "Acme_CRM_get_customer",
"runs": 410,
"errors": 3
}
],
"by_scorer": [
{
"scorer": "answer-relevancy",
"runs": 320,
"billed_runs": 318,
"cost": 0.64,
"avg_score": 0.81
}
]
}{
"error": "Bad request",
"details": "to must be after from"
}Request statistics
The figures behind the Studio home page, for one window: totals (requests, errors, distinct threads, users and messages, cost, tokens, average latency), a zero-filled time series, and breakdowns by billing group, agent, workflow, model, tool and scorer. Scorer runs are counted in the window they ran in, on their own group, the way the monthly statement bills them, and kept apart from the other requests (scoring_runs, scoring_cost, by_scorer). Filters are ANDed. One database call however large the window.
curl --request GET \
--url https://api.sidenet.ai/v1/requests/stats \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.sidenet.ai/v1/requests/stats"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.sidenet.ai/v1/requests/stats', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sidenet.ai/v1/requests/stats",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.sidenet.ai/v1/requests/stats"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.sidenet.ai/v1/requests/stats")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sidenet.ai/v1/requests/stats")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"resolution": "day",
"totals": {
"requests": 1284,
"errors": 12,
"threads": 611,
"users": 402,
"messages": 1190,
"cost": 14.72,
"avg_latency_ms": 3870,
"input_tokens": 1820400,
"output_tokens": 240310,
"scoring_runs": 320,
"scoring_cost": 0.64
},
"series": [
{
"bucket": "2026-10-27T00:00:00+00:00",
"requests": 61,
"errors": 1,
"users": 24,
"cost": 0.71,
"scoring_cost": 0.02,
"avg_latency_ms": 3550
}
],
"by_group": [
{
"group_id": 7,
"external_id": "grp_84f20c19",
"name": "Acme",
"requests": 900,
"errors": 8,
"users": 300,
"cost": 10.4,
"avg_latency_ms": 3900
}
],
"by_agent": [
{
"agent_id": "6f1c0f4e-2b7a-4a51-9a2f-0c9d1b3e5a10",
"name": "Support",
"requests": 850,
"errors": 8,
"cost": 9.9,
"avg_latency_ms": 4100
}
],
"by_workflow": [
{
"workflow_id": "4c2f9e18-7a63-4d05-b1e8-93a7c0f2d641",
"name": "Nightly digest",
"requests": 30,
"errors": 0,
"cost": 1.5,
"avg_latency_ms": 30000
}
],
"by_model": [
{
"model": "openai/gpt-4o",
"calls": 870,
"cost": 12.1,
"input_tokens": 1700000,
"output_tokens": 221000
}
],
"by_tool": [
{
"tool": "Acme_CRM_get_customer",
"runs": 410,
"errors": 3
}
],
"by_scorer": [
{
"scorer": "answer-relevancy",
"runs": 320,
"billed_runs": 318,
"cost": 0.64,
"avg_score": 0.81
}
]
}{
"error": "Bad request",
"details": "to must be after from"
}Authorizations
Organization API key, generated in studio.sidenet.ai. Backend only — never in a browser.
Query Parameters
Start of the window (inclusive). Default: 30 days before to.
"2026-10-01T00:00:00Z"
End of the window (exclusive). Default: now.
"2026-11-01T00:00:00Z"
Comma-separated environments.
"prod,staging"
Comma-separated billing group ids (your stable ids).
"grp_84f20c19"
Comma-separated copilot ids.
"cccccccc-0000-4000-8000-000000000001"
Comma-separated agent ids; every version of the agent counts.
"6f1c0f4e-2b7a-4a51-9a2f-0c9d1b3e5a10"
Time series bucket. auto picks hour up to 2 days, day up to 93 days, month beyond.
auto, hour, day, month