Usage for billing-aligned usage queries and per-sandbox
time-series drilldowns. Use Tags to set and read sandbox tags used
by the usage aggregator.1234import { Usage, Tags } from "@opencomputer/sdk"; const usage = new Usage("https://app.opencomputer.dev", process.env.OPENCOMPUTER_API_KEY!); const tags = new Tags("https://app.opencomputer.dev", process.env.OPENCOMPUTER_API_KEY!);
apiUrl may include or omit /api; both
https://app.opencomputer.dev and https://app.opencomputer.dev/api
work.usage.forSandbox(sandboxId, opts?)body sandboxIdstringrequiredbody fromstringYYYY-MM-DD) or RFC3339 lower bound. Default: now minus
1 hour.body tostringYYYY-MM-DD) or RFC3339 upper bound. Default: now.
Window must be at most 30 days.Promise<SandboxUsageResponse>12345678910111213141516const r = await usage.forSandbox("sb-abc123", { from: "2026-05-27T00:00:00Z", to: "2026-05-27T01:00:00Z", }); const utilization = r.totals.memoryAllocatedGbSeconds === 0 ? 0 : r.totals.memoryUsedGbSeconds / r.totals.memoryAllocatedGbSeconds; console.log(`${(utilization * 100).toFixed(0)}% memory utilization`); for (const point of r.points) { // point.ts, point.allocatedMemoryMb, point.usedMemoryMbAvg // are ready to render as chart series. }
usage.bySandbox(opts?)body fromstringYYYY-MM-DD) or RFC3339 lower bound. Default: now minus
30 days.body tostringYYYY-MM-DD) or RFC3339 upper bound. Default: now.
Window must be at most 90 days.body filterRecord<string, string>"tag:team". Values are
exact tag values, comma-separated OR values, or "" to match
sandboxes without that tag key.body sortstring"-memoryGbSeconds" (default) or "-diskOverageGbSeconds".body limitnumberbody cursorstringnextCursor.Promise<UsageBySandboxResponse>12345678910111213141516171819const page = await usage.bySandbox({ from: "2026-05-01T00:00:00Z", to: "2026-06-01T00:00:00Z", filter: { "tag:team": "payments" }, limit: 20, }); for (const item of page.items) { console.log(item.sandboxId, item.memoryGbSeconds, item.tags); } if (page.nextCursor) { const next = await usage.bySandbox({ from: "2026-05-01T00:00:00Z", to: "2026-06-01T00:00:00Z", filter: { "tag:team": "payments" }, cursor: page.nextCursor, }); }
usage.byTag(tagKey, opts?):.
HTTP API ->body tagKeystringrequired"team" or "team:subsystem".body filterRecord<string, string>body fromstringYYYY-MM-DD) or RFC3339 lower bound. Default: now minus
30 days.body tostringYYYY-MM-DD) or RFC3339 upper bound. Default: now.
Window must be at most 90 days.body sortstring"-memoryGbSeconds" (default) or "-diskOverageGbSeconds".body limitnumberbody cursorstringnextCursor.Promise<UsageByTagResponse>1234567891011const byTeam = await usage.byTag("team", { filter: { "tag:env": "prod" }, }); for (const row of byTeam.items) { console.log(row.tagValue, row.memoryGbSeconds, row.sandboxCount); } console.log("untagged", byTeam.untagged.memoryGbSeconds); const bySubsystem = await usage.byTag("team:subsystem");
tags.set(sandboxId, tags)body sandboxIdstringrequiredbody tagsRecord<string, string>required{} clears all tags.Promise<{ tags: Record<string, string>; tagsLastUpdatedAt: string | null }>12345await tags.set("sb-abc123", { team: "payments", env: "prod", "team:subsystem": "checkout", });
tags.get(sandboxId)Promise<{ tags: Record<string, string>; tagsLastUpdatedAt: string | null }>12const current = await tags.get("sb-abc123"); console.log(current.tags);
tags.listKeys()Promise<TagKeyInfo[]>1234const keys = await tags.listKeys(); for (const key of keys) { console.log(key.key, key.sandboxCount, key.valueCount); }
*GbSeconds fields are GiB-seconds. For example, a sandbox
provisioned at 4096 MiB for one minute reports 240
memoryAllocatedGbSeconds.memoryAllocatedGbSeconds is billing-aligned provisioned memory.
memoryUsedGbSeconds is measured resident memory from the worker
collector, so it can lag by a few minutes after a sandbox starts.12345678interface SandboxUsageResponse { sandboxId: string; alias?: string; from: string; to: string; totals: SandboxUsageTotals; points: SandboxUsagePoint[]; }
123456789interface SandboxUsagePoint { ts: string; memoryAllocatedGbSeconds: number; memoryUsedGbSeconds: number; uptimeSeconds: number; allocatedMemoryMb: number; usedMemoryMbAvg: number; usedMemoryMbPeak: number; }
1234567interface SandboxUsageTotals { memoryAllocatedGbSeconds: number; memoryUsedGbSeconds: number; uptimeSeconds: number; memoryAllocatedPeakMb: number; memoryUsedPeakMb: number; }
123456789interface UsageSandboxItem { sandboxId: string; alias?: string; status?: string; tags: Record<string, string>; tagsLastUpdatedAt: string | null; memoryGbSeconds: number; diskOverageGbSeconds: number; }
1234567interface UsageTagItem { tagKey: string; tagValue: string; memoryGbSeconds: number; diskOverageGbSeconds: number; sandboxCount: number; }