curl --request POST \
--url https://openrouter.ai/api/v1/analytics/query \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"dimensions": [
"model"
],
"granularity": "day",
"limit": 100,
"metrics": [
"request_count"
],
"time_range": {
"end": "2025-01-08T00:00:00Z",
"start": "2025-01-01T00:00:00Z"
}
}
'import requests
url = "https://openrouter.ai/api/v1/analytics/query"
payload = {
"dimensions": ["model"],
"granularity": "day",
"limit": 100,
"metrics": ["request_count"],
"time_range": {
"end": "2025-01-08T00:00:00Z",
"start": "2025-01-01T00:00:00Z"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
dimensions: ['model'],
granularity: 'day',
limit: 100,
metrics: ['request_count'],
time_range: {end: '2025-01-08T00:00:00Z', start: '2025-01-01T00:00:00Z'}
})
};
fetch('https://openrouter.ai/api/v1/analytics/query', 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://openrouter.ai/api/v1/analytics/query",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'dimensions' => [
'model'
],
'granularity' => 'day',
'limit' => 100,
'metrics' => [
'request_count'
],
'time_range' => [
'end' => '2025-01-08T00:00:00Z',
'start' => '2025-01-01T00:00:00Z'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://openrouter.ai/api/v1/analytics/query"
payload := strings.NewReader("{\n \"dimensions\": [\n \"model\"\n ],\n \"granularity\": \"day\",\n \"limit\": 100,\n \"metrics\": [\n \"request_count\"\n ],\n \"time_range\": {\n \"end\": \"2025-01-08T00:00:00Z\",\n \"start\": \"2025-01-01T00:00:00Z\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://openrouter.ai/api/v1/analytics/query")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"dimensions\": [\n \"model\"\n ],\n \"granularity\": \"day\",\n \"limit\": 100,\n \"metrics\": [\n \"request_count\"\n ],\n \"time_range\": {\n \"end\": \"2025-01-08T00:00:00Z\",\n \"start\": \"2025-01-01T00:00:00Z\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/analytics/query")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"dimensions\": [\n \"model\"\n ],\n \"granularity\": \"day\",\n \"limit\": 100,\n \"metrics\": [\n \"request_count\"\n ],\n \"time_range\": {\n \"end\": \"2025-01-08T00:00:00Z\",\n \"start\": \"2025-01-01T00:00:00Z\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"data": [
{
"date__day": "2025-01-01T00:00:00.000Z",
"request_count": 1500
}
],
"metadata": {
"query_time_ms": 42,
"row_count": 1,
"truncated": false
}
}
}{
"error": {
"code": 400,
"message": "Invalid request parameters"
}
}{
"error": {
"code": 401,
"message": "Missing Authentication header"
}
}{
"error": {
"code": 403,
"message": "Only management keys can perform this operation"
}
}{
"error": {
"code": 408,
"message": "Operation timed out. Please try again later."
}
}{
"error": {
"code": 500,
"message": "Internal Server Error"
}
}Query analytics data
Execute an analytics query with specified metrics, dimensions, filters, and time range. A workspace-scoped management key needs activity:view_all on its own workspace and reads only that workspace: it is refused a workspace filter naming another workspace, it excludes legacy rows with no workspace (including for the default workspace), and possible-cache metrics such as possible_cached_tokens return 400. Management key required.
curl --request POST \
--url https://openrouter.ai/api/v1/analytics/query \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"dimensions": [
"model"
],
"granularity": "day",
"limit": 100,
"metrics": [
"request_count"
],
"time_range": {
"end": "2025-01-08T00:00:00Z",
"start": "2025-01-01T00:00:00Z"
}
}
'import requests
url = "https://openrouter.ai/api/v1/analytics/query"
payload = {
"dimensions": ["model"],
"granularity": "day",
"limit": 100,
"metrics": ["request_count"],
"time_range": {
"end": "2025-01-08T00:00:00Z",
"start": "2025-01-01T00:00:00Z"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
dimensions: ['model'],
granularity: 'day',
limit: 100,
metrics: ['request_count'],
time_range: {end: '2025-01-08T00:00:00Z', start: '2025-01-01T00:00:00Z'}
})
};
fetch('https://openrouter.ai/api/v1/analytics/query', 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://openrouter.ai/api/v1/analytics/query",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'dimensions' => [
'model'
],
'granularity' => 'day',
'limit' => 100,
'metrics' => [
'request_count'
],
'time_range' => [
'end' => '2025-01-08T00:00:00Z',
'start' => '2025-01-01T00:00:00Z'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://openrouter.ai/api/v1/analytics/query"
payload := strings.NewReader("{\n \"dimensions\": [\n \"model\"\n ],\n \"granularity\": \"day\",\n \"limit\": 100,\n \"metrics\": [\n \"request_count\"\n ],\n \"time_range\": {\n \"end\": \"2025-01-08T00:00:00Z\",\n \"start\": \"2025-01-01T00:00:00Z\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://openrouter.ai/api/v1/analytics/query")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"dimensions\": [\n \"model\"\n ],\n \"granularity\": \"day\",\n \"limit\": 100,\n \"metrics\": [\n \"request_count\"\n ],\n \"time_range\": {\n \"end\": \"2025-01-08T00:00:00Z\",\n \"start\": \"2025-01-01T00:00:00Z\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/analytics/query")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"dimensions\": [\n \"model\"\n ],\n \"granularity\": \"day\",\n \"limit\": 100,\n \"metrics\": [\n \"request_count\"\n ],\n \"time_range\": {\n \"end\": \"2025-01-08T00:00:00Z\",\n \"start\": \"2025-01-01T00:00:00Z\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"data": [
{
"date__day": "2025-01-01T00:00:00.000Z",
"request_count": 1500
}
],
"metadata": {
"query_time_ms": 42,
"row_count": 1,
"truncated": false
}
}
}{
"error": {
"code": 400,
"message": "Invalid request parameters"
}
}{
"error": {
"code": 401,
"message": "Missing Authentication header"
}
}{
"error": {
"code": 403,
"message": "Only management keys can perform this operation"
}
}{
"error": {
"code": 408,
"message": "Operation timed out. Please try again later."
}
}{
"error": {
"code": 500,
"message": "Internal Server Error"
}
}Body
Maximum rows per distinct combination of dimensions. When omitted on time-series queries (granularity + dimensions), auto-computed to avoid truncating time windows. Explicit values override the default and may truncate time buckets if set lower than the number of buckets in the range. Ignored when no dimensions are specified.
100
Was this page helpful?