Skip to main content
GET
/
api
/
usage
Usage Aggregator
curl --request GET \
  --url https://app.opencomputer.dev/api/usage \
  --header 'X-API-Key: <api-key>'
{
  "from": "2026-03-23T00:00:00Z",
  "to":   "2026-04-22T00:00:00Z",
  "groupBy": "sandbox",
  "total": { "memoryGbSeconds": 20000, "diskOverageGbSeconds": 360 },
  "items": [
    {
      "sandboxId": "sb-abc",
      "alias": "my-agent",
      "status": "running",
      "tags": { "env": "prod", "team": "payments" },
      "tagsLastUpdatedAt": "2026-04-19T14:02:00Z",
      "memoryGbSeconds": 8000,
      "diskOverageGbSeconds": 120
    }
  ],
  "nextCursor": null
}
Aggregate usage grouped by sandbox or by tag. Dollars are not exposed — the platform returns the same physical quantities the invoice is computed from. For per-sandbox time-series drilldown (memory utilization over time, 1-minute resolution), see GET /api/sandboxes/:id/usage.
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.
All *GbSeconds fields are GiB-seconds (binary, 230 bytes/GiB), not decimal GB. For a sandbox provisioned at 1024 MiB running for one second, memoryGbSeconds is 1.
Freshness: accurate to the minute under normal conditions. A sandbox that exited uncleanly continues to accrue against its provisioned tier until the platform reconciles state — the same behavior the billing pipeline uses, so the numbers here match the invoice.

Request

groupBy
string
required
sandbox for top sandboxes, or tag:<key> for usage by tag value. Keys may contain : — everything after the first : is the tag key (so groupBy=tag:team:payments groups by the key team:payments).
from
string
Inclusive lower bound. Accepts either an ISO date (2026-05-27, interpreted as UTC midnight) or an RFC3339 timestamp. Default: now minus 30 days. Max window: 90 days.
to
string
Exclusive upper bound. Same accepted formats as from. Default: now.
filter[tag:<key>]
string
One param per dimension. Comma-separated values are OR’d within that dimension; different filter[...] params are AND’d across dimensions. Passing the same filter[...] key twice returns 400 — put multiple OR values in one comma-separated string instead. Empty value (filter[tag:team]=) matches sandboxes without the team key.
sort
string
-memoryGbSeconds (default) or -diskOverageGbSeconds.
limit
integer
Max items per page. Default 50, max 500.
cursor
string
Opaque cursor from a prior response’s nextCursor.

Response

from
string
required
RFC3339 echo of the effective window lower bound.
to
string
required
RFC3339 echo of the effective window upper bound.
groupBy
string
required
Echo of the requested groupBy value.
total
object
required
Aggregate across all rows matching the window and filters, not just the current page. Use this for headline numbers; sum items[] if you need a per-page subtotal instead.
items
object[]
required
Paginated rows, sorted by sort (default: largest first).When groupBy=sandbox, each row is one sandbox:When groupBy=tag:<key>, each row is one tag value:
untagged
object
Only present when groupBy=tag:<key>. Sibling bucket for sandboxes that lack the grouping key — without it, untagged sandboxes would silently disappear from the rollup. Same shape as a tag row minus tagKey/tagValue.
nextCursor
string
Opaque cursor to pass as cursor= on the next request, or null when no further pages exist.
{
  "from": "2026-03-23T00:00:00Z",
  "to":   "2026-04-22T00:00:00Z",
  "groupBy": "sandbox",
  "total": { "memoryGbSeconds": 20000, "diskOverageGbSeconds": 360 },
  "items": [
    {
      "sandboxId": "sb-abc",
      "alias": "my-agent",
      "status": "running",
      "tags": { "env": "prod", "team": "payments" },
      "tagsLastUpdatedAt": "2026-04-19T14:02:00Z",
      "memoryGbSeconds": 8000,
      "diskOverageGbSeconds": 120
    }
  ],
  "nextCursor": null
}