The Daytona V2 client libraries and the daytona CLI. Package names are
@daytona/sdk (npm) and daytona / module daytona (PyPI); the CLI lives in
cli/.
The SDKs expose Daytona's API through resource handles and namespaces for processes, files, Git, code execution, ports and computer use.
.
├── cli/ daytona CLI (Go)
├── contract/ OpenAPI contracts the SDKs and CLI generate their wire types from
├── sdk-python/ daytona (module daytona) — root client + daytona.v2 (async-native, sync surface generated) + daytona.v0 (bundled at publish)
├── sdk-typescript/ @daytona/sdk — root client + /v2 + /v0 (bundled at publish), ESM + CJS
├── upgrade/ daytona-upgrade — 0.x → 2.x migration tool: npm (upgrade/typescript/) + PyPI (upgrade/python/) packages,
│ one shared mapping (mapping/), the generated MIGRATION.md
├── examples/ runnable examples for both SDKs
├── e2e/ live API e2e, run.sh (needs DAYTONA_API_KEY)
├── scripts/ bundle-v0.sh — publish-time v0 namespace bundling; its output is never committed
│ (+ v0-sdk-version, the pinned 0.x tag the v0 namespace vendors;
│ resolve-v0-tag.sh, bundle_v0_python.py, check-no-bundled-v0.sh, changelog/)
└── docs/ RELEASING.md, VERSIONING.md, PREPARING_YOUR_CHANGES.md, adr/ (architecture decision records)
- Serializable handles.
sandbox.to_json()/toJSON()returns aSandboxHandleJSON: a credential-free snapshot of the sandbox's metadata, the same in both SDKs. Another worker reconnects withd.v2.get(id); a process reconnects withsandbox.process.connect(...)— built for RL rollouts that fan work across workers. A reconnected code process (ProcessKindcode) handle can still replay logs and wait/kill, but it does not reconstruct a decomposedInterpreterResulton another worker. - Detached vs awaited, typed apart.
start()→ handle;run()→ result. - Shareable volumes. The v2 client exposes
volumes.create/get/list/delete, with explicititer()traversal for all pages. Attach volumes using thevolumescreate option and refresh mounted data withsandbox.volumes.pull(). The CLI exposes thevolumecommand group and--volumeon Linux and macOS sandbox creates. See the volume examples. - Everything replayable. Cursor-paged
logs(), SSE streaming with resume,wait()long-poll; nothing requires having been attached. - Filesystem watches are SSE-backed. Both SDKs expose start-gated directory
watches over
GET /files/watch; TS callbacks are awaited sequentially and Python exposes a drainable event queue. - Filesystem pre-signed transfer URLs are minted by the API.
Both SDKs POST
{method, path, expires_at}to/sandboxes/{id}/files/signand compose the download/upload link from their own toolbox base plus the returnedsignature/expires_at.sandbox.rotate_signing_key()/sandbox.rotateSigningKey()POST/sandboxes/{id}/signing-key/rotate, receive 204 with no body and invalidate every outstanding link for the sandbox shortly after.expires_in_seconds/expiresInSecondsmust be from 1 to 604800 (7 days) before any request — never-expiring links do not exist. A per-sandbox proxy override may be given either as a concrete sandbox URL or as the{sandboxId}/{sandbox_id}template — the placeholder is a path segment (https://proxy.example/sandboxes/{sandboxId}); a placeholder in the scheme, host, query or fragment is rejected, and the id is percent-encoded into it identically in both SDKs. Direct toolbox URLs are not supported here: pre-signed URLs require the sandbox's toolbox proxy URL. - Interpreter = code executions (
kind:"code"): Python and TS/JS with setup progress on thesetupchannel. Timeouts are CLIENT-side (on expiry the SDK interrupts the kernel like ^C). Richresults[]/logs/errordecomposition comes fromrunCode()/interpreter.run(), not from rehydrating a serialized code-process handle elsewhere. If an explicit named context vanished, the SDK surfaces the typedSESSION_NOT_FOUNDerror; the caller recreates the context and chooses what to rerun. - Sandbox service namespaces stay mirrored. Both SDKs expose
portsandcomputer-usealongsideprocess,fs,git,interpreter, andpty, with matching wire fields and mirrored tests. - Network policy (Linux and macOS sandboxes) uses explicit compare-and-swap. Both SDKs expose an
additive create-time
network_policy/networkPolicyfield andget_network_policy/update_network_policy/reset_network_policy(Python) plusgetNetworkPolicy/updateNetworkPolicy/resetNetworkPolicy(TypeScript) forGET|PUT /sandboxes/{id}/network-policy. The read side carries desired vs applied policy, the quoted desired ETag,applied_start_id/applied_revision, and pending/failed metadata; writes use full replacement with caller-suppliedIf-Match, and reset sends a literal JSONnull. The serializers preserve omitted vsnullvs[]for domain lists; with domains present they omitblock_allunless the caller sets it, and an explicit false is rejected locally asNETWORK_POLICY_DOMAINS_REQUIRE_BLOCK_ALL; they also keep the read-sideversion: 2field out of write input. The API rejects unsupported sandbox configurations. - Runtime-managed sandbox secret attachments use the same compare-and-swap shape.
Both SDKs expose them on the sandbox handle: Python
sandbox.get_secrets()/sandbox.replace_secrets(secrets=..., if_match=...), TypeScriptsandbox.getSecrets()/sandbox.replaceSecrets(secrets, { ifMatch }), forGET|PUT /sandboxes/{id}/secrets. Responses carry the desired secret names, desired/applied revision state, the quoted desired ETag, the applystatus(pending/applied/failed) with itserror, and capture metadata; writes are full replacement only, use caller-suppliedIf-Match, and never send or return secret values. - Typed errors from one catalog. Status-level bases → code-specific
subclasses with
code/source; each SDK's constants are drift-tested against the contract artifactcontract/toolbox-openapi.json. - Mac reservations buy physical Macs. Both SDKs reserve one Mac per
reservation, individually or in bulk. Sandbox CPU, memory, and disk sizes
are per-create inputs.
MacModelexposesmax_sandboxesanddefault_size. - Signals use bare names on the surface (
TERM,INT, …),SIG*on the wire.
(cd sdk-python && uv venv && uv pip install -e '.[dev]' && .venv/bin/python -m pytest -x -q)
(cd sdk-typescript && npm install && npm run typecheck && npm test && npm run build)
(cd cli && go vet ./... && go test ./...)
scripts/test-upgrade.sh # both daytona-upgrade packages + mapping / guide driftThe TypeScript suite also runs a live toolbox test when
DAYTONA_SDKTS_TOOLBOX_URL points at a reachable sandbox toolbox, and skips it
otherwise. The end-to-end suites (e2e/, run with e2e/run.sh) run against
a Daytona deployment when DAYTONA_API_KEY is set. Details: each package's
DEVELOPMENT.md.
Releases: RELEASING.md · VERSIONING.md ·
CHANGELOG.md. Every PR that changes an SDK adds one changelog
fragment under changelog.d/ (not a line in CHANGELOG.md);
see changelog.d/README.md.
The SDKs are licensed under Apache-2.0; the CLI (cli/) under
AGPL-3.0. See COPYRIGHT and
CONTRIBUTING.md.