AI credentials
Get sandbox AI usage
Proxied AI usage of one sandbox, per day, credential and model.
GET
/
sandboxes
/
{sandboxId}
/
ai-usage
Get sandbox AI usage
curl --request GET \
--url https://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage \
--header 'Authorization: Bearer <token>'import requests
url = "https://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage', 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://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage",
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://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage"
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://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage")
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{
"ok": true,
"type": "sandbox.ai_usage",
"sandboxId": "bx_23456789",
"blocked": false,
"proxied": true,
"credentialProfileId": null,
"since": "2026-09-11",
"usage": [
{
"day": "2026-10-10",
"credential": "claude-subscription",
"model": "claude-sonnet-4-5",
"requests": 412,
"errors": 3,
"inputTokens": 51234,
"outputTokens": 80321,
"cacheReadTokens": 1203344,
"cacheWriteTokens": 90233
}
],
"totals": {
"requests": 412,
"errors": 3,
"inputTokens": 51234,
"outputTokens": 80321,
"cacheReadTokens": 1203344,
"cacheWriteTokens": 90233
},
"dollars": 0.412
}{
"ok": false,
"type": "sandbox.error",
"status": 401,
"code": "unauthorized",
"message": "Unauthorized",
"error": {
"code": "unauthorized",
"message": "Unauthorized",
"status": 401
},
"requestId": "req_01HX..."
}{
"ok": false,
"type": "sandbox.error",
"status": 409,
"code": "provider_not_configured",
"message": "Prompting is locked until Codex is configured on the Agents page.",
"requestId": "req_01HX...",
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
}
}Authorizations
Boat bearer token in the form boat_.... Service API keys authenticate sandbox operations.
Path Parameters
Public Sandbox id returned by create/list/get sandbox calls.
Pattern:
^bx_[23456789abcdefghjkmnpqrstuvwxyz]{8}$Query Parameters
Days of history, today included.
Required range:
1 <= x <= 365Response
The usage.
Example:
true
Stable success envelope discriminator added by v1.
True when the proxy refuses this sandbox's placeholders.
True when the sandbox holds placeholders, not real keys.
The profile the sandbox uses. Null means its owner's default.
Show child attributes
Show child attributes
Token counts are the numbers the provider reports in its replies.
Show child attributes
Show child attributes
⌘I
Get sandbox AI usage
curl --request GET \
--url https://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage \
--header 'Authorization: Bearer <token>'import requests
url = "https://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage', 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://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage",
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://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage"
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://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://boat.dev/api/v1/sandboxes/{sandboxId}/ai-usage")
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{
"ok": true,
"type": "sandbox.ai_usage",
"sandboxId": "bx_23456789",
"blocked": false,
"proxied": true,
"credentialProfileId": null,
"since": "2026-09-11",
"usage": [
{
"day": "2026-10-10",
"credential": "claude-subscription",
"model": "claude-sonnet-4-5",
"requests": 412,
"errors": 3,
"inputTokens": 51234,
"outputTokens": 80321,
"cacheReadTokens": 1203344,
"cacheWriteTokens": 90233
}
],
"totals": {
"requests": 412,
"errors": 3,
"inputTokens": 51234,
"outputTokens": 80321,
"cacheReadTokens": 1203344,
"cacheWriteTokens": 90233
},
"dollars": 0.412
}{
"ok": false,
"type": "sandbox.error",
"status": 401,
"code": "unauthorized",
"message": "Unauthorized",
"error": {
"code": "unauthorized",
"message": "Unauthorized",
"status": 401
},
"requestId": "req_01HX..."
}{
"ok": false,
"type": "sandbox.error",
"status": 409,
"code": "provider_not_configured",
"message": "Prompting is locked until Codex is configured on the Agents page.",
"requestId": "req_01HX...",
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
}
}