Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.opencomputer.dev/llms.txt

Use this file to discover all available pages before exploring further.

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.
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 ->
sandboxId
string
required
Sandbox ID.
from
string
ISO date (YYYY-MM-DD) or RFC3339 lower bound. Default: now minus 1 hour.
to
string
ISO date (YYYY-MM-DD) or RFC3339 upper bound. Default: now. Window must be at most 30 days.
Returns: Promise<SandboxUsageResponse>
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 ->
from
string
ISO date (YYYY-MM-DD) or RFC3339 lower bound. Default: now minus 30 days.
to
string
ISO date (YYYY-MM-DD) or RFC3339 upper bound. Default: now. Window must be at most 90 days.
filter
Record<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.
sort
string
"-memoryGbSeconds" (default) or "-diskOverageGbSeconds".
limit
number
Max rows per page. Default 50, max 500.
cursor
string
Cursor returned by the previous page’s nextCursor.
Returns: Promise<UsageBySandboxResponse>
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 ->
tagKey
string
required
Tag key to group by, for example "team" or "team:subsystem".
filter
Record<string, string>
Optional tag filters applied before grouping.
from
string
ISO date (YYYY-MM-DD) or RFC3339 lower bound. Default: now minus 30 days.
to
string
ISO date (YYYY-MM-DD) or RFC3339 upper bound. Default: now. Window must be at most 90 days.
sort
string
"-memoryGbSeconds" (default) or "-diskOverageGbSeconds".
limit
number
Max rows per page. Default 50, max 500.
cursor
string
Cursor returned by the previous page’s nextCursor.
Returns: Promise<UsageByTagResponse>
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 ->
sandboxId
string
required
Sandbox ID.
tags
Record<string, string>
required
Flat tag map. {} clears all tags.
Returns: Promise<{ tags: Record<string, string>; tagsLastUpdatedAt: string | null }>
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 }>
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[]>
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

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