Sandbox Usage
curl --request GET \
--url https://app.opencomputer.dev/api/sandboxes/{id}/usage \
--header 'X-API-Key: <api-key>'import requests
url = "https://app.opencomputer.dev/api/sandboxes/{id}/usage"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://app.opencomputer.dev/api/sandboxes/{id}/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://app.opencomputer.dev/api/sandboxes/{id}/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 => [
"X-API-Key: <api-key>"
],
]);
$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://app.opencomputer.dev/api/sandboxes/{id}/usage"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.opencomputer.dev/api/sandboxes/{id}/usage")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.opencomputer.dev/api/sandboxes/{id}/usage")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"sandboxId": "sb-abc",
"alias": "my-agent",
"from": "2026-05-27T00:00:00Z",
"to": "2026-05-28T00:00:00Z",
"totals": {
"memoryAllocatedGbSeconds": 86400,
"memoryUsedGbSeconds": 51640,
"uptimeSeconds": 86400,
"memoryAllocatedPeakMb": 1024,
"memoryUsedPeakMb": 742
},
"points": [
{
"ts": "2026-05-27T00:00:00Z",
"memoryAllocatedGbSeconds": 60.0,
"memoryUsedGbSeconds": 35.86,
"uptimeSeconds": 60,
"allocatedMemoryMb": 1024,
"usedMemoryMbAvg": 612,
"usedMemoryMbPeak": 720
},
{
"ts": "2026-05-27T00:01:00Z",
"memoryAllocatedGbSeconds": 60.0,
"memoryUsedGbSeconds": 40.02,
"uptimeSeconds": 60,
"allocatedMemoryMb": 1024,
"usedMemoryMbAvg": 683,
"usedMemoryMbPeak": 742
}
]
}
Usage
Sandbox Usage
GET
/
api
/
sandboxes
/
{id}
/
usage
Sandbox Usage
curl --request GET \
--url https://app.opencomputer.dev/api/sandboxes/{id}/usage \
--header 'X-API-Key: <api-key>'import requests
url = "https://app.opencomputer.dev/api/sandboxes/{id}/usage"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://app.opencomputer.dev/api/sandboxes/{id}/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://app.opencomputer.dev/api/sandboxes/{id}/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 => [
"X-API-Key: <api-key>"
],
]);
$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://app.opencomputer.dev/api/sandboxes/{id}/usage"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.opencomputer.dev/api/sandboxes/{id}/usage")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.opencomputer.dev/api/sandboxes/{id}/usage")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"sandboxId": "sb-abc",
"alias": "my-agent",
"from": "2026-05-27T00:00:00Z",
"to": "2026-05-28T00:00:00Z",
"totals": {
"memoryAllocatedGbSeconds": 86400,
"memoryUsedGbSeconds": 51640,
"uptimeSeconds": 86400,
"memoryAllocatedPeakMb": 1024,
"memoryUsedPeakMb": 742
},
"points": [
{
"ts": "2026-05-27T00:00:00Z",
"memoryAllocatedGbSeconds": 60.0,
"memoryUsedGbSeconds": 35.86,
"uptimeSeconds": 60,
"allocatedMemoryMb": 1024,
"usedMemoryMbAvg": 612,
"usedMemoryMbPeak": 720
},
{
"ts": "2026-05-27T00:01:00Z",
"memoryAllocatedGbSeconds": 60.0,
"memoryUsedGbSeconds": 40.02,
"uptimeSeconds": 60,
"allocatedMemoryMb": 1024,
"usedMemoryMbAvg": 683,
"usedMemoryMbPeak": 742
}
]
}
Per-sandbox memory usage over a window, as 1-minute points plus
envelope totals. Allocated memory is the tier the sandbox was
provisioned at, integrated over time; used memory is the actual
resident memory consumed by the sandbox process, sampled every 60s.
Preview: Usage and tag APIs are new. Endpoints, response fields,
and SDK method names may change before GA; temporary inaccuracies or
rough edges are possible while the surface settles.
Request
string
required
Sandbox ID.
string
Lower bound. Accepts either an ISO date (
2026-05-27, interpreted
as UTC midnight) or an RFC3339 timestamp. Default: now minus 1 hour.string
Upper bound. Same accepted formats as
from. Default: now. Window
must be ≤ 30 days.Response
string
required
Echo of the requested sandbox ID.
string
The sandbox’s display name (set at create time). Absent if no alias
was provided.
string
required
RFC3339 lower bound of the window the response covers — either the
caller’s
from, or the server default (now - 1h) when omitted.string
required
RFC3339 upper bound. Either the caller’s
to, or the server
default (now) when omitted.object
required
Envelope totals for the full window. Each additive field equals the
sum of the matching field across
points[] — useful for getting
the headline numbers without iterating.Show properties
Show properties
number
required
Total GiB-seconds the sandbox was provisioned for. This is the
physical quantity the bill is computed from. For a sandbox at
1 GiB running for 1 hour, this is
3600.number
required
Total GiB-seconds the sandbox actually consumed (integrated
resident memory). Compare against
memoryAllocatedGbSeconds to
see headroom — 1 - used/allocated is wasted provisioning.integer
required
Number of seconds the sandbox was provisioned (i.e., had an
open scale event) within the window. A 1-hour window where the
sandbox ran the whole time returns
3600.integer
required
Maximum provisioned memory tier (MiB) seen in the window.
Reflects the highest size the sandbox was resized to.
integer
required
Maximum measured resident memory (MiB) in any sample during the
window. Useful for detecting workloads that briefly approached
their tier ceiling.
object[]
required
Time-ordered array of 1-minute buckets covering
[from, to).
Buckets are minute-aligned in UTC. Boundary buckets are clamped to
the original window — a mid-minute from produces a partial first
bucket whose integrals reflect only the overlap with the requested
range.Minutes where the sandbox was not provisioned (before first start,
after final stop) appear with all fields at 0 rather than as
missing entries — gaps read as continuous flat zero on a chart.Show properties
Show properties
string
required
RFC3339 timestamp of the bucket start (minute-aligned, UTC).
The bucket covers
[ts, ts + 1 minute).number
required
Provisioned memory integrated over this minute, in GiB-seconds.
Summing this across all points reproduces
totals.memoryAllocatedGbSeconds exactly.number
required
Measured resident memory integrated over this minute, in
GiB-seconds. Same compositional property — summing reproduces
totals.memoryUsedGbSeconds.integer
required
Seconds within this minute the sandbox was provisioned. Usually
60; 0 when not running; a fractional value (e.g., 30)
appears in the resize or start/stop bucket where the sandbox
began or ended part-way through the minute.integer
required
Time-weighted average of the provisioned memory tier (MiB)
across this bucket. When a resize falls inside the bucket, this
shows the blend (e.g., 30s at 2048 + 30s at 4096 →
3072).
Designed to render directly as a step line on a chart.integer
required
Average measured resident memory (MiB) across samples that fell
in this bucket. The natural Y value for a “memory used” chart.
integer
required
Maximum measured resident memory (MiB) across samples in this
bucket. Catches sub-minute spikes that the average smooths out.
Units
All*GbSeconds fields are GiB-seconds (binary, 230
bytes/GiB), not decimal GB. For a sandbox provisioned at 1024 MiB
running for one minute, memoryAllocatedGbSeconds is
1024/1024 × 60 = 60. For a measured RSS of 612 MiB,
memoryUsedGbSeconds is 612/1024 × 60 ≈ 35.86.
{
"sandboxId": "sb-abc",
"alias": "my-agent",
"from": "2026-05-27T00:00:00Z",
"to": "2026-05-28T00:00:00Z",
"totals": {
"memoryAllocatedGbSeconds": 86400,
"memoryUsedGbSeconds": 51640,
"uptimeSeconds": 86400,
"memoryAllocatedPeakMb": 1024,
"memoryUsedPeakMb": 742
},
"points": [
{
"ts": "2026-05-27T00:00:00Z",
"memoryAllocatedGbSeconds": 60.0,
"memoryUsedGbSeconds": 35.86,
"uptimeSeconds": 60,
"allocatedMemoryMb": 1024,
"usedMemoryMbAvg": 612,
"usedMemoryMbPeak": 720
},
{
"ts": "2026-05-27T00:01:00Z",
"memoryAllocatedGbSeconds": 60.0,
"memoryUsedGbSeconds": 40.02,
"uptimeSeconds": 60,
"allocatedMemoryMb": 1024,
"usedMemoryMbAvg": 683,
"usedMemoryMbPeak": 742
}
]
}
Use the aggregator for cross-sandbox questions
To rank sandboxes by usage, useGET /api/usage
— that endpoint serves cross-sandbox aggregates and supports
filter/sort/cursor. The per-sandbox endpoint here is for “look at
this one sandbox in detail.”