Skip to content
Docs / SDKs Pages

SDKs

raw.computer has an SDK for TypeScript and one for Python. Both are generated from the API's OpenAPI document, so every operation of the HTTP API is a typed method of theirs, named by its operationId, and both behave the same way: the version they were made from on every request, an Idempotency-Key on every POST, retries as Retry-After says, and one typed error.

Early access: the packages are not on npm or PyPI yet. They will be npm install rawcomputer and pip install rawcomputer. Until then, use the HTTP API or the CLI, which do the same.

TypeScript

For Node 20 or later, Bun, Deno, Workers and browsers: anywhere fetch runs.

import { Raw, RawError } from 'rawcomputer';

const raw = new Raw(); // RAW_API_KEY, or RAW_TOKEN with RAW_WORKSPACE

const me = await raw.getMe();
const acting = me.workspace ? `${me.workspace.code} (${me.workspace.id})` : 'no workspace';
console.log(
	`me: ${me.user.email} with a ${me.api_key.kind} key, in ${acting}, API version ${me.raw_version}`
);

for (const workspace of (await raw.listWorkspaces()).data)
	console.log(
		`workspace: ${workspace.code} · ${workspace.name} (${workspace.id}) as ${workspace.relation}`
	);

console.log(`sandboxes: ${(await raw.listSandboxes()).data.length}`);

try {
	await raw.createSandbox({ body: { class: 'std', size: '4x8' } });
} catch (e) {
	if (!(e instanceof RawError)) throw e;
	console.log(`createSandbox: RawError ${e.status} ${e.code}: ${e.message}`);
	console.log(`  next step: ${e.next_step.message} ${e.next_step.url ?? ''}`.trimEnd());
	console.log(`  docs: ${e.docs}`);
}
me: ada@example.com with a workspace key, in default (ws_01m6zbey4kf5db2f5qbn7fwppy), API version 2026-11-08
workspace: default · Default (ws_01m6zbey4kf5db2f5qbn7fwppy) as developer
sandboxes: 0
createSandbox: RawError 503 capacity_unavailable: No cell serves std yet: raw.computer is in early access.
  next step: Read the early-access note; sandbox creates open when the first cell does. https://raw.computer/docs/limits#early-access
  docs: https://raw.computer/docs/errors#capacity_unavailable

A method takes one object with the parts its operation has: body, path (raw.getSandbox({ path: { id } })), query (raw.listSandboxes({ query: { limit: 10 } })) and headers. Its answer and its body are typed from the document; every type is exported (import type { Sandbox } from 'rawcomputer').

Python

For Python 3.11 or later. AsyncRaw is the same client with every method awaited.

from rawcomputer import Raw, RawError
from rawcomputer.models import SandboxCreate

raw = Raw()  # RAW_API_KEY, or RAW_TOKEN with RAW_WORKSPACE

me = raw.get_me()
acting = f"{me.workspace.code} ({me.workspace.id})" if me.workspace else "no workspace"
print(f"me: {me.user.email} with a {me.api_key.kind} key, in {acting}, API version {me.raw_version}")

for workspace in raw.list_workspaces().data:
    print(f"workspace: {workspace.code} · {workspace.name} ({workspace.id}) as {workspace.relation}")

print(f"sandboxes: {len(raw.list_sandboxes().data)}")

try:
    raw.create_sandbox(body=SandboxCreate(class_="std", size="4x8"))
except RawError as e:
    print(f"create_sandbox: RawError {e.status} {e.code}: {e.message}")
    print(f"  next step: {e.next_step.message} {e.next_step.url or ''}".rstrip())
    print(f"  docs: {e.docs}")
me: ada@example.com with a personal key, in default (ws_01m6zbey4kf5db2f5qbn7fwppy), API version 2026-11-08
workspace: default · Default (ws_01m6zbey4kf5db2f5qbn7fwppy) as admin
sandboxes: 0
create_sandbox: RawError 503 capacity_unavailable: No cell serves std yet: raw.computer is in early access.
  next step: Read the early-access note; sandbox creates open when the first cell does. https://raw.computer/docs/limits#early-access
  docs: https://raw.computer/docs/errors#capacity_unavailable

Methods are the operationIds in snake_case (get_me, list_workspaces, create_sandbox). A path parameter comes first (raw.get_sandbox("sbx_…")), everything else by keyword (body=, limit=, raw_workspace=). Request and answer classes are in rawcomputer.models; a field the API may leave out is UNSET.

Credentials

What TypeScript Python
A workspace API key (rc_live_…) new Raw({ apiKey }) Raw(api_key)
A personal token (rc_pat_…) and its workspace new Raw({ apiKey: token, workspace }) Raw(token, workspace="ws_…")
Another origin new Raw({ baseUrl }) Raw(base_url=…)

Left out, they are read from the environment as the CLI reads it: RAW_TOKEN, else RAW_API_KEY; RAW_WORKSPACE; RAW_API_URL. Make a key in the console under API keys; a personal token is what raw login keeps. A token acts as its person in the workspace it names (sent as Raw-Workspace) and in none without it; one call can name another (headers: { 'Raw-Workspace': … } in TypeScript, raw_workspace= in Python). A credential of neither kind is refused before any request is sent.

Versions

Every request names the API version the SDK was made from in Raw-Version (RAW_VERSION, today 2026-11-08), so an answer has the shape the SDK reads whatever version the key is pinned to. A value the API adds later (a new state, a new error code) is read as it came, never refused.

Idempotency and retries

  • Every POST carries an Idempotency-Key, made by the SDK unless the call names its own, and each retry sends the same one: a POST that reached the API is answered as the first time and never done twice (Idempotency).
  • 429 and a 5xx with Retry-After are sent again after it, when the wait is at most maxRetryWait / max_retry_wait (60 seconds); a longer wait is yours to choose, and the error's retry_at says when.
  • 500, 502 and 504 without Retry-After, and a request that got no answer, are sent again after 0.5, 1, 2… seconds, when they are safe to repeat: a GET, or a POST with its key.
  • At most maxRetries / max_retries (3) times. Anything else is yours at once: a 4xx, and a 503 capacity_unavailable, which no wait mends.

Errors

Every answer that is not a success throws (TypeScript) or raises (Python) a RawError:

Field Holds
status the HTTP status
code the stable code to branch on: one of Errors
message what happened, in one sentence
next_step what to do: message, and where one helps, url, api ("POST /v1/api_keys") and cli
docs the code on the Errors page
retry_at when a retry is expected to succeed, on capacity_full and rate_limited; else null / None

A request that got no answer at all, after its retries, throws what fetch or httpx2 threw.