Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

Usage & Tags

Use 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.
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.
typescript
import { 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!);
The apiUrl may include or omit /api; both https://app.opencomputer.dev and https://app.opencomputer.dev/api work.

usage.forSandbox(sandboxId, opts?)

Return 1-minute memory points plus envelope totals for one sandbox. HTTP API ->
body sandboxIdstringrequired
Sandbox ID.
body fromstring
ISO date (YYYY-MM-DD) or RFC3339 lower bound. Default: now minus 1 hour.
body tostring
ISO date (YYYY-MM-DD) or RFC3339 upper bound. Default: now. Window must be at most 30 days.
Returns: Promise<SandboxUsageResponse>
typescript
const 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?)

Rank sandboxes by usage for an organization. HTTP API ->
body fromstring
ISO date (YYYY-MM-DD) or RFC3339 lower bound. Default: now minus 30 days.
body tostring
ISO date (YYYY-MM-DD) or RFC3339 upper bound. Default: now. Window must be at most 90 days.
body filterRecord<string, string>
Tag filters. Keys are dimensions such as "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 limitnumber
Max rows per page. Default 50, max 500.
body cursorstring
Cursor returned by the previous page's nextCursor.
Returns: Promise<UsageBySandboxResponse>
typescript
const 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?)

Group usage by the value of one tag key. Tag keys may contain :. HTTP API ->
body tagKeystringrequired
Tag key to group by, for example "team" or "team:subsystem".
body filterRecord<string, string>
Optional tag filters applied before grouping.
body fromstring
ISO date (YYYY-MM-DD) or RFC3339 lower bound. Default: now minus 30 days.
body tostring
ISO date (YYYY-MM-DD) or RFC3339 upper bound. Default: now. Window must be at most 90 days.
body sortstring
"-memoryGbSeconds" (default) or "-diskOverageGbSeconds".
body limitnumber
Max rows per page. Default 50, max 500.
body cursorstring
Cursor returned by the previous page's nextCursor.
Returns: Promise<UsageByTagResponse>
typescript
const 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)

Replace the full tag set for a sandbox. Partial updates are not supported: read, modify, then write the full map. HTTP API ->
body sandboxIdstringrequired
Sandbox ID.
body tagsRecord<string, string>required
Flat tag map. {} clears all tags.
Returns: Promise<{ tags: Record<string, string>; tagsLastUpdatedAt: string | null }>
typescript
await tags.set("sb-abc123", { team: "payments", env: "prod", "team:subsystem": "checkout", });

tags.get(sandboxId)

Read the current tag set for a sandbox. HTTP API ->
Returns: Promise<{ tags: Record<string, string>; tagsLastUpdatedAt: string | null }>
typescript
const current = await tags.get("sb-abc123"); console.log(current.tags);

tags.listKeys()

List tag keys seen in the organization, with counts for tagged sandboxes and distinct values. HTTP API ->
Returns: Promise<TagKeyInfo[]>
typescript
const keys = await tags.listKeys(); for (const key of keys) { console.log(key.key, key.sandboxCount, key.valueCount); }

Units

All *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.

Types

SandboxUsageResponse
typescript
interface SandboxUsageResponse { sandboxId: string; alias?: string; from: string; to: string; totals: SandboxUsageTotals; points: SandboxUsagePoint[]; }
SandboxUsagePoint
typescript
interface SandboxUsagePoint { ts: string; memoryAllocatedGbSeconds: number; memoryUsedGbSeconds: number; uptimeSeconds: number; allocatedMemoryMb: number; usedMemoryMbAvg: number; usedMemoryMbPeak: number; }
SandboxUsageTotals
typescript
interface SandboxUsageTotals { memoryAllocatedGbSeconds: number; memoryUsedGbSeconds: number; uptimeSeconds: number; memoryAllocatedPeakMb: number; memoryUsedPeakMb: number; }
UsageSandboxItem
typescript
interface UsageSandboxItem { sandboxId: string; alias?: string; status?: string; tags: Record<string, string>; tagsLastUpdatedAt: string | null; memoryGbSeconds: number; diskOverageGbSeconds: number; }
UsageTagItem
typescript
interface UsageTagItem { tagKey: string; tagValue: string; memoryGbSeconds: number; diskOverageGbSeconds: number; sandboxCount: number; }