PLATINUM DOCS

Runtimes

List the execution backends and select one when you create a sandbox.

A runtime is the execution backend that runs a sandbox. The default runtime is microvm. Every sandbox created before runtimes existed is a microvm.

List runtimes

The response lists every registered runtime. A runtime with status: planned is registered but cannot boot yet. Create refuses it with 501.

const { runtimes } = await client.request("GET", "/v1/runtimes");
runtimes = client.request("GET", "/v1/runtimes")["runtimes"]
# no dedicated CLI command — use pt api
pt api /v1/runtimes
curl -sS "$PT_API_URL/v1/runtimes" -H "Authorization: Bearer $PT_TOKEN"

Each entry carries key, label, status, description, and capabilities. Read capabilities before you depend on a feature. A runtime that sets exec: false does not run commands.

Select a runtime

Set runtime when you create a sandbox. Omit it for a microvm.

const sbx = await client.sandboxes.create({ template: "pt-celld", runtime: "cell", worker: "my-worker" });
sbx = client.sandboxes.create(template="pt-celld", runtime="cell", worker="my-worker")
pt sandbox create -t pt-celld --runtime cell --worker my-worker
curl -sS -X POST "$PT_API_URL/v1/sandboxes" \
  -H "Authorization: Bearer $PT_TOKEN" -H "Content-Type: application/json" \
  -d '{"template":"pt-celld","runtime":"cell","worker":"my-worker"}'

The response carries runtime. An unknown runtime is a 400. A runtime that is registered but disabled in this environment is a 501 with code: runtime_not_enabled. A cell runs the pt-celld template and needs a worker (400 worker_required).

Filter by runtime

const { rows } = await client.sandboxes.list({ runtime: "cell" });
rows = client.sandboxes.list(runtime="cell")["rows"]
pt sandbox list --runtime cell
curl -sS "$PT_API_URL/v1/sandboxes?paginated=true&runtime=cell" -H "Authorization: Bearer $PT_TOKEN"

An unknown runtime in the filter is a 400 that names the known runtimes. It is not an empty page.

The cell runtime

A cell is a V8 isolate with a private SQLite database. The database replicates to object storage as it runs. A stopped cell holds no memory. A request rebuilds it from object storage.

A cell does not run commands, open a terminal, or expose a filesystem. Read capabilities on GET /v1/runtimes for the current list.

The cell runtime is switched off by default. An operator enables it per environment with the flags.cell_runtime_enabled setting.

Workers are folders

A cell reads one deployment from the root of its storage prefix, so the org prefix alone would mean one Worker per org and every cell in the org serving it. POST /v1/sandboxes {"runtime": "cell", "worker": "<name>"} roots the cell at workers/<name>/ under the org prefix instead — its own deploy/, cells/ and fleet/. A name is one plain path segment ([a-z0-9-], 1–63 characters, not starting with -); worker on any other runtime is refused with worker_requires_cell. GET /v1/sandboxes?worker=<name> lists that Worker's cells, and every sandbox carries worker (null = the org root).

Deploying a Worker

A Worker is a Cloudflare Workers project — its own wrangler.jsonc, unmodified — deployed with stock celld deploy (celld 0.6.2): Durable Objects, KV, R2, D1, Queues, Workflows, static assets, cron triggers, service bindings, Worker Loaders, Python and Wasm modules, vars.

pt worker deploy ./my-worker                    # runs celld deploy for you (celld + esbuild on PATH, or PT_CELLD)

pt worker deploy asks for a short-lived S3 credential for that one Worker's folder and hands it to celld in the environment:

POST /v1/workers/<name>/storage-credentials   { ttl_seconds? }
  → { access_key_id, secret_access_key, region, endpoint, bucket: "s3://<name>", expires_at }

so any celld tooling works against it — celld deploy, celld r2 get|put|list|delete, celld cell list, celld cell gc --dry-run:

eval "$(pt worker credentials my-worker --env)"
celld deploy ./my-worker --bucket s3://my-worker --endpoint "$ENDPOINT" --region platinum

The endpoint (/v1/worker-storage) speaks S3 for orgs/<org>/workers/<name>/ only: the folder a cell created with worker: <name> boots from. A deploy moves the Worker's pointer, and running cells adopt the new version in place within 30 s — requests in flight finish on the old one.

Object keys are relative to that Worker's folder, including keys with an orgs/ segment of their own. S3 listings and DeleteObjects responses preserve those caller-owned names; they do not expose another organization's or Worker's storage prefix. Provider keys outside the authenticated Worker's folder are rejected rather than returned.

A Worker's values are vars in its wrangler config. A cell on a celld 0.5+ template refuses CELLD_VAR_* in envVars (400 runtime_env_removed): celld will not start with one, and a fleet runs one deployment, so there is no per-cell value. A value that differs per cell belongs in its own Worker (a folder per session, deployed with its vars), or in the request. A cell on a v0.3.0 template still takes CELLD_VAR_* until it is moved.

Without celld: the one-module upload

POST /v1/workers/<name>/versions      multipart: bundle=<index.js>, manifest=<json>
  → { version, script_name, prefix }  version = first 16 hex of sha256(bundle)
POST /v1/workers/<name>/activate      { "version": "…" }
  → { cells: [...], restart_required: false }
GET  /v1/workers · GET /v1/workers/<name> · GET /v1/workers/<name>/versions

The Worker list and a Worker's version list include every object-storage page, including organizations with more than 1,000 Worker folders and Workers with more than 1,000 uploaded versions. Versions remain newest first (version ID ascending when upload timestamps tie), with the active version marked even when it is beyond the first storage page. A failed storage listing fails the request rather than returning or caching a partial list. Only a native NoSuchKey response means that a pointer or version index is absent. Denied reads, transport failures and invalid stored JSON fail the request instead of hiding a Worker, losing its active version or treating an unreadable immutable manifest as a new upload.

It carries one built module and the bindings the manifest can express — Durable Objects, services and string vars (manifestFromWrangler, pinned against manifests celld 0.6.2 wrote). A config that declares anything else (kv_namespaces, r2_buckets, queues, workflows, d1_databases, assets, triggers, worker_loaders, containers, define, rules) is refused by name rather than deployed without it; use celld.