List interrupted requests
Incremental feed of requests the client disconnected from (finish_reason = 'client_disconnected'), ordered by ingestion time and queryable in near real time — well suited for incremental polling (no data_not_ready gate).
curl --request GET \
--url https://api.moonshot.ai/v1/admin/organizations/billings/interrupted_requests \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.moonshot.ai/v1/admin/organizations/billings/interrupted_requests"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.moonshot.ai/v1/admin/organizations/billings/interrupted_requests', 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.moonshot.ai/v1/admin/organizations/billings/interrupted_requests",
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.moonshot.ai/v1/admin/organizations/billings/interrupted_requests"
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.moonshot.ai/v1/admin/organizations/billings/interrupted_requests")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moonshot.ai/v1/admin/organizations/billings/interrupted_requests")
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{
"data": [
{
"id": "<string>",
"time": "2023-11-07T05:31:56Z",
"model_id": "<string>",
"key": "<string>",
"key_name": "<string>",
"project_id": "<string>",
"project_name": "<string>",
"prompt_tokens": 1,
"completion_tokens": 1,
"cached_tokens": 1,
"is_off_peak": true,
"off_peak_ratio": "<string>",
"client_request_id": "<string>",
"cache_write_5m_tokens": 1,
"cache_write_1h_tokens": 1
}
],
"has_more": true,
"next": "<string>"
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}billing:read scope.The bill endpoints (daily bills, product bills, request details) return 400 data_not_ready before the current day is finalized; this endpoint is not subject to that restriction: same-day rows are queryable as they are written, and an end beyond now simply returns what has been written so far.X-Msh-Client-Request-Id: when calling the inference API, pass your own request ID in the header (X-Msh-Client-Request-Id: <your-request-id>); our billing details persist it as client_request_id. To reconcile, pull this feed and match your request IDs against client_request_id — whether a request was recorded, and exactly how (token volume, off-peak hit or not) — row by row, with no need to infer from “time + tokens”. For disconnect auditing use the dedicated interrupted_requests feed instead; for amounts, reconcile against daily/product bills (this feed reports tokens only, no amounts) — client_request_id links rows across both APIs exactly. Example: “Why was our gateway request abc123 charged?” → look up its tokens via client_request_id=abc123 in request_details, then verify the day’s amount in daily_bills.Authorizations
Send the Admin API secret as a Bearer token in the Authorization header (Bearer sk-admin-***). Create Admin Keys under Console → Organization → Admin API Keys.
Query Parameters
Start time in milliseconds, inclusive, e.g. 1790784000000 (2026-10-01 00:00 CST).
x >= 0End time in milliseconds, exclusive, e.g. 1792598400000 (2026-10-22 00:00 CST).
x >= 0Project IDs. Every project must belong to the authenticated organization.
Business API key IDs. Every key must belong to the authenticated organization.
Page size. Defaults to 100 for interactive queries; raise it (up to 10000) for bulk pulls — per-page latency may grow for large pages (not an SLA guarantee). 1000 rows.
1 <= x <= 10000Cursor from the previous response next field. The cursor carries only the page position; all query parameters must be restated on every page. Keep them unchanged while paginating (except limit) — the server does not check them for consistency.
Was this page helpful?
curl --request GET \
--url https://api.moonshot.ai/v1/admin/organizations/billings/interrupted_requests \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.moonshot.ai/v1/admin/organizations/billings/interrupted_requests"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.moonshot.ai/v1/admin/organizations/billings/interrupted_requests', 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.moonshot.ai/v1/admin/organizations/billings/interrupted_requests",
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.moonshot.ai/v1/admin/organizations/billings/interrupted_requests"
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.moonshot.ai/v1/admin/organizations/billings/interrupted_requests")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moonshot.ai/v1/admin/organizations/billings/interrupted_requests")
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{
"data": [
{
"id": "<string>",
"time": "2023-11-07T05:31:56Z",
"model_id": "<string>",
"key": "<string>",
"key_name": "<string>",
"project_id": "<string>",
"project_name": "<string>",
"prompt_tokens": 1,
"completion_tokens": 1,
"cached_tokens": 1,
"is_off_peak": true,
"off_peak_ratio": "<string>",
"client_request_id": "<string>",
"cache_write_5m_tokens": 1,
"cache_write_1h_tokens": 1
}
],
"has_more": true,
"next": "<string>"
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}