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. 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"
}
}Authorizations
API key as bearer token in Authorization header
Body
1Metric name
2Dimension to group by (up to 2). Use the /meta endpoint for available dimensions.
20Show child attributes
Show child attributes
Time granularity
"day"
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
Maximum total rows returned. Defaults to 1000. On time-series queries with dimensions and no explicit group_limit, the server may raise this to accommodate the expected number of unique time-bucket/dimension combinations.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Response
Analytics query results
Show child attributes
Show child attributes