DaytonaConfig
Section titled “DaytonaConfig”@dataclassclass DaytonaConfig()Configuration shared by every API version.
One credential serves both namespaces: api_key (DAYTONA_API_KEY)
or jwt_token (DAYTONA_JWT_TOKEN). A JWT is scoped by
organization_id for v0 and project_id for v2. Fields left unset
are read from the environment by each namespace.
There is no region or API URL field here. Pass region= to a v2 create;
DAYTONA_V2_API_URL, else DAYTONA_API_URL, selects the v2 API
endpoint and never reaches v0.
target is deprecated and applies to .v0 only (the v0 client’s
default region). Pass target to each v0 sandbox create
(CreateSandboxFromSnapshotParams(target=...)) or region_id to each
v0 snapshot create instead. Setting it still works and emits a
DeprecationWarning.
request_timeout (seconds), connection_pool_maxsize and
otel_enabled tune the v2 client’s HTTP transport;
connection_pool_maxsize and otel_enabled reach v0 too.
shared_hub and events (daytona.v2.SandboxEventsConfig) configure
the v2 client’s sandbox-state events hub; v0 has no such hub.
Attributes:
api_keyOptional[str] = Nonejwt_tokenOptional[str] = field(default=None, kw_only=True)organization_idOptional[str] = field(default=None, kw_only=True)project_idOptional[str] = field(default=None, kw_only=True)targetOptional[str] = field(default=None, kw_only=True)request_timeoutOptional[float] = field(default=None, kw_only=True)connection_pool_maxsizeOptional[int] = field(default=None, kw_only=True)otel_enabledOptional[bool] = field(default=None, kw_only=True)shared_hubbool = field(default=True, kw_only=True)eventsOptional[SandboxEventsConfig] = field(default=None, kw_only=True)
Daytona
Section titled “Daytona”class Daytona(_Root)The synchronous client: Daytona().v0 and Daytona().v2.
Every operation goes through a version namespace; the root itself only
holds the shared configuration. with Daytona() as d: (or close())
closes whichever namespace clients were built.
Daytona.__init__
Section titled “Daytona.__init__”def __init__(config: Optional[DaytonaConfig] = None) -> NoneDaytona.v2
Section titled “Daytona.v2”@propertydef v2() -> _DaytonaV2The v2 client (v2’s synchronous client), built on first access.
Owned by the root: close the root, not this client (a closed v2 client stays cached and its calls fail).
Daytona.v0
Section titled “Daytona.v0”@propertydef v0() -> _DaytonaV0The v0 client (the bundled 0.x Daytona), built on first access.
Needs the v0-sdk extra (pip install "daytona[v0-sdk]"); raises
ImportError naming it otherwise.
Daytona.close
Section titled “Daytona.close”def close() -> NoneClose the namespace clients built so far. Idempotent.
Closes the v2 client and the v0 client. The bundled 0.x sync
Daytona has no close(), so the root releases its event socket
(and tracer provider) directly.
AsyncDaytona
Section titled “AsyncDaytona”class AsyncDaytona(_Root)The asynchronous client: AsyncDaytona().v0 and AsyncDaytona().v2.
Same shape as Daytona; the namespace clients are the async ones.
async with AsyncDaytona() as d: (or await close()) closes whichever
namespace clients were built.
AsyncDaytona.__init__
Section titled “AsyncDaytona.__init__”def __init__(config: Optional[DaytonaConfig] = None) -> NoneAsyncDaytona.v2
Section titled “AsyncDaytona.v2”@propertydef v2() -> _AsyncDaytonaV2The v2 client (v2’s asynchronous client), built on first access.
Owned by the root: close the root, not this client (a closed v2 client stays cached and its calls fail).
AsyncDaytona.v0
Section titled “AsyncDaytona.v0”@propertydef v0() -> _AsyncDaytonaV0The v0 client (the bundled 0.x AsyncDaytona), built on first access.
Needs the v0-sdk extra (pip install "daytona[v0-sdk]"); raises
ImportError naming it otherwise.
AsyncDaytona.close
Section titled “AsyncDaytona.close”async def close() -> NoneClose the namespace clients built so far. Idempotent.
DaytonaV2Client
Section titled “DaytonaV2Client”class DaytonaV2Client()The v2 Daytona client.
DaytonaV2Client.images
Section titled “DaytonaV2Client.images”@propertydef images() -> ImageServiceDaytonaV2Client.snapshots
Section titled “DaytonaV2Client.snapshots”@propertydef snapshots() -> SnapshotServiceDaytonaV2Client.secret
Section titled “DaytonaV2Client.secret”@propertydef secret() -> SecretServiceDaytonaV2Client.secrets
Section titled “DaytonaV2Client.secrets”@propertydef secrets() -> SecretServiceDaytonaV2Client.reservations
Section titled “DaytonaV2Client.reservations”@propertydef reservations() -> ReservationServiceDaytonaV2Client.mac_models
Section titled “DaytonaV2Client.mac_models”@propertydef mac_models() -> MacModelServiceDaytonaV2Client.archive
Section titled “DaytonaV2Client.archive”def archive(sandbox: Union[Sandbox, str]) -> NoneArchive a stopped sandbox now (accepts a Sandbox or its id).
DaytonaV2Client.close
Section titled “DaytonaV2Client.close”def close() -> NoneClose HTTP resources, then stop the bridge loop. Idempotent; safe from any thread.
DaytonaV2Client.create
Section titled “DaytonaV2Client.create”def create(image: Optional[str] = None, /, *, name: Optional[str] = None, env: Optional[Dict[str, str]] = None, labels: Optional[Dict[str, str]] = None, resources: Optional[Resources] = None, cpu: Optional[float] = None, memory: Optional[int] = None, disk: Optional[int] = None, ports: Optional[Sequence[PortMapping]] = None, secrets: Optional[Sequence[str]] = None, spot: Optional[bool] = None, lifecycle_policy: Optional[LifecyclePolicyConfig] = None, network_policy: NetworkPolicyInput | None | _UnsetNetworkPolicy = _UNSET_NETWORK_POLICY, cpu_arch: Optional[str] = None, cpu_type: Optional[str] = None, region: Optional[str] = None, toolbox_url: Optional[str] = None, idempotency_key: Optional[str] = None, wait_seconds: int = 60, create_timeout_seconds: Optional[int] = None) -> SandboxCreate from a registered image name or img_… id.
DaytonaV2Client.create_from_build
Section titled “DaytonaV2Client.create_from_build”def create_from_build(builder: ImageBuilder, /, *, idle_expiry_seconds: Optional[int] = None, network_policy: NetworkPolicyInput | None | _UnsetNetworkPolicy = _UNSET_NETWORK_POLICY, **kwargs) -> SandboxBuild an anonymous image first, then create the sandbox from it.
DaytonaV2Client.create_from_snapshot
Section titled “DaytonaV2Client.create_from_snapshot”def create_from_snapshot(snapshot: str, /, *, name: Optional[str] = None, labels: Optional[Dict[str, str]] = None, lifecycle_policy: Optional[LifecyclePolicyConfig] = None, ports: Optional[Sequence[PortMapping]] = None, region: Optional[str] = None, toolbox_url: Optional[str] = None, idempotency_key: Optional[str] = None, wait_seconds: int = 60, create_timeout_seconds: Optional[int] = None) -> SandboxCreate a sandbox from a snapshot.
DaytonaV2Client.create_macos
Section titled “DaytonaV2Client.create_macos”def create_macos(image: str, /, *, cpu: Optional[int] = None, memory: Optional[float] = None, disk: Optional[float] = None, name: Optional[str] = None, env: Optional[Dict[str, str]] = None, labels: Optional[Dict[str, str]] = None, secrets: Optional[Sequence[str]] = None, ports: Optional[Sequence[PortMapping]] = None, persistent: Optional[bool] = None, lifecycle_policy: Optional[LifecyclePolicyConfig] = None, reservation: Optional[str] = None, auto_renew: Optional[bool] = None, region: Optional[str] = None, toolbox_url: Optional[str] = None, idempotency_key: Optional[str] = None, wait_seconds: int = 60, create_timeout_seconds: Optional[int] = None, network_policy: NetworkPolicyInput | None | _UnsetNetworkPolicy = _UNSET_NETWORK_POLICY) -> SandboxCreate a macOS sandbox on a reserved Mac from a macOS image name.
DaytonaV2Client.current_api_key
Section titled “DaytonaV2Client.current_api_key”def current_api_key() -> ProjectApiKeyWithContextDescribe the API key this client authenticates with.
DaytonaV2Client.delete
Section titled “DaytonaV2Client.delete”def delete(sandbox: Union[Sandbox, str]) -> NoneDelete a sandbox (accepts a Sandbox or its id).
DaytonaV2Client.find_by_name
Section titled “DaytonaV2Client.find_by_name”def find_by_name(name: str, /, *, region: Optional[str] = None) -> list[Sandbox]Sandboxes created with name=name, newest first; [] when none.
DaytonaV2Client.get
Section titled “DaytonaV2Client.get”def get(sandbox_id: str, *, toolbox_url: Optional[str] = None) -> SandboxFetch a sandbox by id.
DaytonaV2Client.get_network_policy
Section titled “DaytonaV2Client.get_network_policy”def get_network_policy(sandbox: Union[Sandbox, str]) -> NetworkPolicyInfoDaytonaV2Client.get_project_budget
Section titled “DaytonaV2Client.get_project_budget”def get_project_budget() -> ProjectBudgetReturn the monthly spend budget of the API key’s project.
DaytonaV2Client.iter
Section titled “DaytonaV2Client.iter”def iter(*, cursor: Optional[str] = None, limit: Optional[int] = None) -> Iterator[Sandbox]DaytonaV2Client.list
Section titled “DaytonaV2Client.list”def list(*, cursor: Optional[str] = None, limit: Optional[int] = None, id: Optional[str] = None, name: Optional[str] = None, q: Optional[str] = None, status: Optional[Sequence[str]] = None, vm_class: Optional[Union[VmClass, Sequence[VmClass]]] = None, region: Optional[Sequence[str]] = None, image_ref: Optional[str] = None, image_ref_prefix: Optional[str] = None, labels: Optional[Mapping[str, str]] = None, spot: Optional[bool] = None, forked_from: Optional[str] = None, min_vcpus: Optional[int] = None, max_vcpus: Optional[int] = None, min_memory_mib: Optional[int] = None, max_memory_mib: Optional[int] = None, min_disk_mib: Optional[int] = None, max_disk_mib: Optional[int] = None, created_start_at: Optional[SearchTimestamp] = None, created_end_at: Optional[SearchTimestamp] = None, updated_start_at: Optional[SearchTimestamp] = None, updated_end_at: Optional[SearchTimestamp] = None, last_activity_start_at: Optional[SearchTimestamp] = None, last_activity_end_at: Optional[SearchTimestamp] = None, sort: Optional[SearchSort] = None, order: Optional[SearchOrder] = None) -> ListResult[Sandbox]List sandboxes as one page {items, next_cursor}.
DaytonaV2Client.list_audit_actions
Section titled “DaytonaV2Client.list_audit_actions”def list_audit_actions() -> AuditActionListReturn the actions the audit log can record for each target type.
DaytonaV2Client.pause
Section titled “DaytonaV2Client.pause”def pause(sandbox: Union[Sandbox, str], *, timeout: float = 60) -> NonePause a sandbox (accepts a Sandbox or its id); see Sandbox.pause.
DaytonaV2Client.reset_network_policy
Section titled “DaytonaV2Client.reset_network_policy”def reset_network_policy(sandbox: Union[Sandbox, str], *, if_match: str) -> NetworkPolicyInfoDaytonaV2Client.resume
Section titled “DaytonaV2Client.resume”def resume(sandbox: Union[Sandbox, str], *, timeout: float = 60) -> NoneResume a sandbox (accepts a Sandbox or its id).
DaytonaV2Client.search
Section titled “DaytonaV2Client.search”def search(*, q: Optional[str] = None, name_prefix: Optional[str] = None, id_prefix: Optional[str] = None, status: Optional[Sequence[str]] = None, vm_class: Optional[Union[VmClass, Sequence[VmClass]]] = None, region: Optional[Sequence[str]] = None, image_ref: Optional[str] = None, image_ref_prefix: Optional[str] = None, labels: Optional[Mapping[str, str]] = None, spot: Optional[bool] = None, forked_from: Optional[str] = None, min_vcpus: Optional[int] = None, max_vcpus: Optional[int] = None, min_memory_mib: Optional[int] = None, max_memory_mib: Optional[int] = None, min_disk_mib: Optional[int] = None, max_disk_mib: Optional[int] = None, created_start_at: Optional[SearchTimestamp] = None, created_end_at: Optional[SearchTimestamp] = None, updated_start_at: Optional[SearchTimestamp] = None, updated_end_at: Optional[SearchTimestamp] = None, last_activity_start_at: Optional[SearchTimestamp] = None, last_activity_end_at: Optional[SearchTimestamp] = None, sort: Optional[SearchSort] = None, order: Optional[SearchOrder] = None, limit: Optional[int] = None, cursor: Optional[str] = None) -> SearchResult[Sandbox]Search sandboxes across every region through the search index (GET /sandboxes/search).
DaytonaV2Client.start
Section titled “DaytonaV2Client.start”def start(sandbox: Union[Sandbox, str], *, timeout: float = 60) -> NoneStart a sandbox (accepts a Sandbox or its id).
DaytonaV2Client.stop
Section titled “DaytonaV2Client.stop”def stop(sandbox: Union[Sandbox, str]) -> NoneWarm-stop a sandbox (accepts a Sandbox or its id).
DaytonaV2Client.update_network_policy
Section titled “DaytonaV2Client.update_network_policy”def update_network_policy(sandbox: Union[Sandbox, str], *, network_policy: NetworkPolicyInput, if_match: str) -> NetworkPolicyInfoAsyncDaytonaV2Client
Section titled “AsyncDaytonaV2Client”class AsyncDaytonaV2Client()The v2 Daytona client.
AsyncDaytonaV2Client.create
Section titled “AsyncDaytonaV2Client.create”async def create(image: Optional[str] = None, /, *, name: Optional[str] = None, env: Optional[Dict[str, str]] = None, labels: Optional[Dict[str, str]] = None, resources: Optional[Resources] = None, cpu: Optional[float] = None, memory: Optional[int] = None, disk: Optional[int] = None, ports: Optional[Sequence[PortMapping]] = None, secrets: Optional[Sequence[str]] = None, spot: Optional[bool] = None, lifecycle_policy: Optional[LifecyclePolicyConfig] = None, network_policy: NetworkPolicyInput | None | _UnsetNetworkPolicy = _UNSET_NETWORK_POLICY, cpu_arch: Optional[str] = None, cpu_type: Optional[str] = None, region: Optional[str] = None, toolbox_url: Optional[str] = None, idempotency_key: Optional[str] = None, wait_seconds: int = 60, create_timeout_seconds: Optional[int] = None) -> AsyncSandboxCreate from a registered image name or img_… id.
Omitting image boots the platform default image, the Linux image
the operator marks as default (images.list(platform="true") shows
it with default=True); the returned sandbox’s image names the
image the server booted. When no default is configured the create
fails with DEFAULT_IMAGE_NOT_CONFIGURED (400). An empty or
whitespace-only image is still an error, raised before any request.
Fast path: the server holds this create briefly, so a sandbox that
reaches running within that hold returns in one round trip.
wait_seconds and create_timeout_seconds are budgets: the SDK long-polls any
remainder of wait_seconds client-side, and create_timeout_seconds is the server’s
total budget for reaching running before deletion.
name is non-unique display metadata — and the handle of the
one-sandbox-per-end-user pattern (issue #1935): a named create stamps
labels["name"] = name (find_by_name reads it back) and,
unless idempotency_key is given, derives its idempotency key from
the name (idempotency_key_for_name). A repeated or retried
create(image, name="mate") within one cell is therefore a
get-or-create: the same sandbox comes back, not a second one or a 409
— until the first is deleted, which releases the key. The guarantee is
cell-scoped (creates of one end user that land in two cells make two
sandboxes; pin them to one region), per class, and exact: a same-name create with
different arguments is a 409 too, never a silent replay of the first
sandbox’s parameters. An explicit idempotency_key always wins over
the derived one.
Visible resources. In burstable sandboxes the guest boots with the
burst ceiling (resources.cpu_max / memory_max, or the deployment
cap when omitted), so nproc and /proc/meminfo report that ceiling,
not the guaranteed cpu. Tools that size themselves from the CPU count
(pytest -n auto, make -j$(nproc)) start one worker per visible
CPU. Pass an explicit worker count when you need the guarantee instead of
the ceiling.
toolbox_url overrides the toolbox URL the control plane returns;
the SDK sends the new sandbox’s toolbox credential there, so pass only
a URL you trust — never one read from stored or user-supplied data.
AsyncDaytonaV2Client.create_from_snapshot
Section titled “AsyncDaytonaV2Client.create_from_snapshot”async def create_from_snapshot(snapshot: str, /, *, name: Optional[str] = None, labels: Optional[Dict[str, str]] = None, lifecycle_policy: Optional[LifecyclePolicyConfig] = None, ports: Optional[Sequence[PortMapping]] = None, region: Optional[str] = None, toolbox_url: Optional[str] = None, idempotency_key: Optional[str] = None, wait_seconds: int = 60, create_timeout_seconds: Optional[int] = None) -> AsyncSandboxCreate a sandbox from a snapshot.
toolbox_url overrides the toolbox URL the control plane returns;
the SDK sends the new sandbox’s toolbox credential there, so pass only
a URL you trust — never one read from stored or user-supplied data.
AsyncDaytonaV2Client.create_macos
Section titled “AsyncDaytonaV2Client.create_macos”async def create_macos(image: str, /, *, cpu: Optional[int] = None, memory: Optional[float] = None, disk: Optional[float] = None, name: Optional[str] = None, env: Optional[Dict[str, str]] = None, labels: Optional[Dict[str, str]] = None, secrets: Optional[Sequence[str]] = None, ports: Optional[Sequence[PortMapping]] = None, persistent: Optional[bool] = None, lifecycle_policy: Optional[LifecyclePolicyConfig] = None, reservation: Optional[str] = None, auto_renew: Optional[bool] = None, region: Optional[str] = None, toolbox_url: Optional[str] = None, idempotency_key: Optional[str] = None, wait_seconds: int = 60, create_timeout_seconds: Optional[int] = None, network_policy: NetworkPolicyInput | None | _UnsetNetworkPolicy = _UNSET_NETWORK_POLICY) -> AsyncSandboxCreate a macOS sandbox on a reserved Mac from a macOS image name.
cpu: Whole vCPUs, at least 4; sent as vcpus. Omitted uses half of the claiming Mac, rounded down.
memory: Memory in GiB, at least 4; sent as memory_mib. memory * 1024 must be an integer. Omitted uses half of the claiming Mac, rounded down.
disk: Disk in GiB, at least 80; sent as disk_mib. The whole guest disk, macOS included. disk * 1024 must be an integer. Omitted uses half of the claiming Mac’s sandbox disk room, rounded down to a whole GiB, on a split reservation, or all of it on a whole reservation.
The first successful claim fixes the size, which the sandbox reports from then on.
persistent: Stop keeps the disk on the same Mac. Start and resume use that Mac. Delete erases the disk. At reservation end, the disk is saved as an anonymous image before the Mac is erased; a lost Mac saves it if it comes back within 7 days. If a Mac restarts before it is declared lost, a running persistent sandbox comes back stopped with its disk, a running ephemeral sandbox is lost, and stopped and paused sandboxes are unchanged. Create a sandbox from an image to continue on another Mac.
reservation picks the Mac’s reservation (daytona.reservations):
None uses any fitting reservation of the organization in the region (or
lets the organization’s auto-reserve buy one), "new" buys a reservation of
the cheapest model that fits.
A reservation ID targets that reservation at claim. Acceptance does not reserve room; the sandbox can wait for room or time out.
auto_renew is allowed only with reservation="new". With no reservation
to use it raises ConflictError (NO_ACTIVE_RESERVATION,
NO_FREE_SLOT, MAC_DISK_FULL, AUTO_RESERVE_LIMIT_REACHED,
NO_MAC_AVAILABLE). name, idempotency_key, wait_seconds
and create_timeout_seconds behave as on create.
Creating macOS sandboxes requires the organization’s macos_sandboxes
feature flag; without it the API answers 403
FEATURE_NOT_ENABLED (raised as FeatureNotEnabledError).
secrets attaches project secrets by name, as on create: the
sandbox sees a placeholder in each named variable, and the Mac’s egress
proxy puts the real value in HTTPS requests to the secret’s allowed
domains. Attaching needs the read:secrets permission.
network_policy sets the sandbox’s egress policy, as on
create: the Mac enforces it from the guest’s first boot, and a
sandbox with a policy runs only on a Mac that can enforce it (otherwise
the API answers 503). Change it later with
AsyncSandbox.update_network_policy.
toolbox_url overrides the toolbox URL the control plane returns;
the SDK sends the new sandbox’s toolbox credential there, so pass only
a URL you trust — never one read from stored or user-supplied data.
macOS sandboxes are served by the macOS API cell, not the default
https://api.daytona.com: set
DAYTONA_V2_API_URL=https://api.us-macos.daytona.com before creating
the client. Against the default API the create raises
ConflictError naming that setting; the SDK does not reroute.
AsyncDaytonaV2Client.create_from_build
Section titled “AsyncDaytonaV2Client.create_from_build”async def create_from_build(builder: ImageBuilder, /, *, idle_expiry_seconds: Optional[int] = None, network_policy: NetworkPolicyInput | None | _UnsetNetworkPolicy = _UNSET_NETWORK_POLICY, **kwargs: object) -> AsyncSandboxBuild an anonymous image first, then create the sandbox from it.
Slow path: POST /images followed by create(image.id, ...).
idle_expiry_seconds describes the anonymous image’s idle window;
PLAN-CREATION-SHAPE §5); every other keyword goes to create().
Docker needs no option: every Linux and GPU sandbox has Docker storage
(PLAN-DOCKER-AUTOMATIC-SUPPORT.md). region (the create’s region
selector) is applied to BOTH legs: a Dockerfile-built image lives in
one region and can only boot there (DP-2), so the image is built where
the sandbox will run. If the image build fails, this raises
ImageBuildFailedError and no sandbox exists.
AsyncDaytonaV2Client.get
Section titled “AsyncDaytonaV2Client.get”async def get(sandbox_id: str, *, toolbox_url: Optional[str] = None) -> AsyncSandboxFetch a sandbox by id.
toolbox_url overrides the toolbox URL the control plane returns
(a direct daemon URL, or a proxy URL scoped to this sandbox). The SDK
sends this sandbox’s toolbox credential there (the API key, a project
token, or a minted sandbox token), so pass only a URL you trust —
never one read from stored or user-supplied data.
AsyncDaytonaV2Client.find_by_name
Section titled “AsyncDaytonaV2Client.find_by_name”async def find_by_name(name: str, /, *, region: Optional[str] = None) -> list[AsyncSandbox]Sandboxes created with name=name, newest first; [] when none.
Exact match on the labels["name"] every create*(name=…) stamps,
read through sandbox search. Names are not unique, so this is a list:
a get-or-create caller takes [0] when it is non-empty and calls
create(..., name=name) otherwise — and because that create derives
the same key as the first one, a lost race between two such callers
still yields one sandbox. Search indexes a new sandbox shortly after
its create. Sandboxes that are deleted or deleting are left out.
A deployment without search raises SearchNotConfiguredError
(501).
region scopes the read the way it scopes a create: it is sent as
the same x-daytona-region selector create*() sends, and
"local" (or omitting it) means this API host’s own region — so the lookup reads the cell the named create landed in,
which is the create ledger’s scope.
AsyncDaytonaV2Client.list_audit_actions
Section titled “AsyncDaytonaV2Client.list_audit_actions”async def list_audit_actions() -> AuditActionListReturn the actions the audit log can record for each target type.
AsyncDaytonaV2Client.current_api_key
Section titled “AsyncDaytonaV2Client.current_api_key”async def current_api_key() -> ProjectApiKeyWithContextDescribe the API key this client authenticates with.
Returns its name, masked display parts, the project and organization it acts in, its permissions, expiry and last use. The token itself is never returned.
AsyncDaytonaV2Client.get_project_budget
Section titled “AsyncDaytonaV2Client.get_project_budget”async def get_project_budget() -> ProjectBudgetReturn the monthly spend budget of the API key’s project.
An unset budget is returned with nullable limit and period fields. The key needs the
read:spending permission. Spend is calculated at list price, before
credits, and lags usage by several minutes. While the project is over
its budget, creating or starting a sandbox in it raises
ProjectBudgetExceededError.
AsyncDaytonaV2Client.list
Section titled “AsyncDaytonaV2Client.list”async def list(*, cursor: Optional[str] = None, limit: Optional[int] = None, id: Optional[str] = None, name: Optional[str] = None, q: Optional[str] = None, status: Optional[Sequence[str]] = None, vm_class: Optional[Union[VmClass, Sequence[VmClass]]] = None, region: Optional[Sequence[str]] = None, image_ref: Optional[str] = None, image_ref_prefix: Optional[str] = None, labels: Optional[Mapping[str, str]] = None, spot: Optional[bool] = None, forked_from: Optional[str] = None, min_vcpus: Optional[int] = None, max_vcpus: Optional[int] = None, min_memory_mib: Optional[int] = None, max_memory_mib: Optional[int] = None, min_disk_mib: Optional[int] = None, max_disk_mib: Optional[int] = None, created_start_at: Optional[SearchTimestamp] = None, created_end_at: Optional[SearchTimestamp] = None, updated_start_at: Optional[SearchTimestamp] = None, updated_end_at: Optional[SearchTimestamp] = None, last_activity_start_at: Optional[SearchTimestamp] = None, last_activity_end_at: Optional[SearchTimestamp] = None, sort: Optional[SearchSort] = None, order: Optional[SearchOrder] = None) -> ListResult[AsyncSandbox]List sandboxes as one page {items, next_cursor}.
With only cursor/limit this is the read-your-writes path: one
page of the region-local GET /sandboxes. A sandbox you just created is in
the result; walk further pages with iter() or the returned cursor.
Any other parameter — including id / name (sent as id_prefix
/ name_prefix), q, status, vm_class, region,
labels, the resource and timestamp bounds, sort, order —
switches the call to a single GET /sandboxes/search request, the same
surface as search, and fills total, total_relation and
search totals on the result. That path is eventually consistent: a
committed change is searchable after roughly 2-3 s, it spans every
region rather than only this API host’s. The
cursor it returns is opaque and tied to the exact filter and sort that
produced it (reusing it with a different filter or sort is a 400), and
paging is best-effort under concurrent mutation. If the API host has
search disabled (501, SearchNotConfiguredError with
code == "SEARCH_NOT_CONFIGURED") or the index is unreachable (503,
SearchUnavailableError with code == "SEARCH_UNAVAILABLE"),
drop the search parameters to fall back to the GET /sandboxes path.
AsyncDaytonaV2Client.search
Section titled “AsyncDaytonaV2Client.search”async def search(*, q: Optional[str] = None, name_prefix: Optional[str] = None, id_prefix: Optional[str] = None, status: Optional[Sequence[str]] = None, vm_class: Optional[Union[VmClass, Sequence[VmClass]]] = None, region: Optional[Sequence[str]] = None, image_ref: Optional[str] = None, image_ref_prefix: Optional[str] = None, labels: Optional[Mapping[str, str]] = None, spot: Optional[bool] = None, forked_from: Optional[str] = None, min_vcpus: Optional[int] = None, max_vcpus: Optional[int] = None, min_memory_mib: Optional[int] = None, max_memory_mib: Optional[int] = None, min_disk_mib: Optional[int] = None, max_disk_mib: Optional[int] = None, created_start_at: Optional[SearchTimestamp] = None, created_end_at: Optional[SearchTimestamp] = None, updated_start_at: Optional[SearchTimestamp] = None, updated_end_at: Optional[SearchTimestamp] = None, last_activity_start_at: Optional[SearchTimestamp] = None, last_activity_end_at: Optional[SearchTimestamp] = None, sort: Optional[SearchSort] = None, order: Optional[SearchOrder] = None, limit: Optional[int] = None, cursor: Optional[str] = None) -> SearchResult[AsyncSandbox]Search sandboxes across every region through the search index (GET /sandboxes/search).
Every parameter is optional and they combine as AND. q is free text
over name and image (or an exact id); name_prefix/id_prefix are
the server-side form of list(name=...)/list(id=...); status,
vm_class and region accept a single value or a list (any-of;
lifecycle states use the API’s wire names such as running); labels is a
containment match; the min_*/max_* bounds are inclusive,
*_start_at timestamp bounds are inclusive, and *_end_at bounds
are exclusive. Timestamps accept RFC 3339 strings or datetime objects
(naive values are taken as UTC). sort defaults to
created_at and order to desc; limit is clamped to
1..200 by the server. Returns a SearchResult whose items are
the same AsyncSandbox handles list returns.
Consistency: the index is eventually consistent. A committed create,
update or delete becomes searchable about 2-3 s later, so a sandbox you
just created may not be in the result yet — use get or
list without search filters for read-your-writes. Results span
every region, not only the one this API host serves.
Cursor: next_cursor is opaque and bound to the exact filter and sort
that produced it — presenting it with a different filter or sort is a
400, never a silent reset. Paging is best-effort under concurrent
mutation: each page reads the live index, so a sandbox whose sort field
(status, name, memory_mib, updated_at, …) changes between
two page fetches can appear on both pages or on neither, and creates or
deletes mid-walk shift later pages.
Errors: 400 (BadRequestError) for a malformed or mismatched
cursor, an unknown status/vm_class/sort value, a non-object
labels or a min above its max; 501
(SearchNotConfiguredError with
code == "SEARCH_NOT_CONFIGURED") when this API host has search
disabled; 503 (SearchUnavailableError with
code == "SEARCH_UNAVAILABLE") when the index did not answer. The
server body is the unified {code, message, source, trace_id}
envelope. On 501/503 callers may fall back to list without search
parameters, which never touches the index.
AsyncDaytonaV2Client.iter
Section titled “AsyncDaytonaV2Client.iter”async def iter(*, cursor: Optional[str] = None, limit: Optional[int] = None) -> AsyncIterator[AsyncSandbox]AsyncDaytonaV2Client.start
Section titled “AsyncDaytonaV2Client.start”async def start(sandbox: Union[AsyncSandbox, str], *, timeout: float = 60) -> NoneStart a sandbox (accepts a Sandbox or its id).
AsyncDaytonaV2Client.stop
Section titled “AsyncDaytonaV2Client.stop”async def stop(sandbox: Union[AsyncSandbox, str]) -> NoneWarm-stop a sandbox (accepts a Sandbox or its id).
AsyncDaytonaV2Client.archive
Section titled “AsyncDaytonaV2Client.archive”async def archive(sandbox: Union[AsyncSandbox, str]) -> NoneArchive a stopped sandbox now (accepts a Sandbox or its id).
AsyncDaytonaV2Client.pause
Section titled “AsyncDaytonaV2Client.pause”async def pause(sandbox: Union[AsyncSandbox, str], *, timeout: float = 60) -> NonePause a sandbox (accepts a Sandbox or its id); see Sandbox.pause.
AsyncDaytonaV2Client.resume
Section titled “AsyncDaytonaV2Client.resume”async def resume(sandbox: Union[AsyncSandbox, str], *, timeout: float = 60) -> NoneResume a sandbox (accepts a Sandbox or its id).
AsyncDaytonaV2Client.delete
Section titled “AsyncDaytonaV2Client.delete”async def delete(sandbox: Union[AsyncSandbox, str]) -> NoneDelete a sandbox (accepts a Sandbox or its id).
AsyncDaytonaV2Client.get_network_policy
Section titled “AsyncDaytonaV2Client.get_network_policy”async def get_network_policy(sandbox: Union[AsyncSandbox, str]) -> NetworkPolicyInfoAsyncDaytonaV2Client.update_network_policy
Section titled “AsyncDaytonaV2Client.update_network_policy”async def update_network_policy(sandbox: Union[AsyncSandbox, str], *, network_policy: NetworkPolicyInput, if_match: str) -> NetworkPolicyInfoAsyncDaytonaV2Client.reset_network_policy
Section titled “AsyncDaytonaV2Client.reset_network_policy”async def reset_network_policy(sandbox: Union[AsyncSandbox, str], *, if_match: str) -> NetworkPolicyInfoAsyncDaytonaV2Client.close
Section titled “AsyncDaytonaV2Client.close”async def close() -> NoneClose HTTP resources.
AuditActionGroup
Section titled “AuditActionGroup”class AuditActionGroup(BaseModel)Actions the audit log can record against one target type.
Attributes:
actionsList[StrictStr] = Field(description=‘Actions that can appear against this target type, sorted alphabetically.’)target_typeStrictStr = Field(description=‘The resource type the actions apply to. It matchestarget_typeon an audit log entry.’)additional_propertiesDict[str, Any] = {}
model_config
Section titled “model_config”model_config = ConfigDict(populate_by_name=True, validate_assignment=True, protected_namespaces=())AuditActionGroup.to_str
Section titled “AuditActionGroup.to_str”def to_str() -> strReturns the string representation of the model using alias
AuditActionGroup.to_json
Section titled “AuditActionGroup.to_json”def to_json() -> strReturns the JSON representation of the model using alias
AuditActionGroup.from_json
Section titled “AuditActionGroup.from_json”@classmethoddef from_json(json_str: str) -> Optional[Self]Create an instance of AuditActionGroup from a JSON string
AuditActionGroup.to_dict
Section titled “AuditActionGroup.to_dict”def to_dict() -> Dict[str, Any]Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic’s
self.model_dump(by_alias=True):
Noneis only added to the output dict for nullable fields that were set at model initialization. Other fields with valueNoneare ignored.- Fields in
self.additional_propertiesare added to the output dict.
AuditActionGroup.from_dict
Section titled “AuditActionGroup.from_dict”@classmethoddef from_dict(obj: Optional[Dict[str, Any]]) -> Optional[Self]Create an instance of AuditActionGroup from a dict
AuditActionList
Section titled “AuditActionList”class AuditActionList(BaseModel)The supported audit actions, grouped by target type.
Attributes:
targetsList[AuditActionGroup] = Field(description=‘One entry per target type, sorted by target type.’)additional_propertiesDict[str, Any] = {}
model_config
Section titled “model_config”model_config = ConfigDict(populate_by_name=True, validate_assignment=True, protected_namespaces=())AuditActionList.to_str
Section titled “AuditActionList.to_str”def to_str() -> strReturns the string representation of the model using alias
AuditActionList.to_json
Section titled “AuditActionList.to_json”def to_json() -> strReturns the JSON representation of the model using alias
AuditActionList.from_json
Section titled “AuditActionList.from_json”@classmethoddef from_json(json_str: str) -> Optional[Self]Create an instance of AuditActionList from a JSON string
AuditActionList.to_dict
Section titled “AuditActionList.to_dict”def to_dict() -> Dict[str, Any]Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic’s
self.model_dump(by_alias=True):
Noneis only added to the output dict for nullable fields that were set at model initialization. Other fields with valueNoneare ignored.- Fields in
self.additional_propertiesare added to the output dict.
AuditActionList.from_dict
Section titled “AuditActionList.from_dict”@classmethoddef from_dict(obj: Optional[Dict[str, Any]]) -> Optional[Self]Create an instance of AuditActionList from a dict
ProjectApiKeyWithContext
Section titled “ProjectApiKeyWithContext”class ProjectApiKeyWithContext(BaseModel)A project API key together with its tenant context.
Attributes:
created_atdatetime = Field(description=‘When the API key was created.’)created_byOptional[StrictStr] = Field(default=None, description=‘The user who created the API key, when visible.’)expires_atOptional[datetime] = Field(default=None, description=‘When the API key expires, or null when it does not expire.’)idStrictStr = Field(description=‘The API key ID.’)imported_fromOptional[StrictStr] = Field(default=None, description=‘"v1"when the key was created on Daytona v1 and imported by the v1 ↔ v2 key sync;nullfor a key created on this platform.’)key_prefixOptional[StrictStr] = Field(default=None, description=‘The recognizable leading token characters, when available.’)key_suffixOptional[StrictStr] = Field(default=None, description=‘The recognizable trailing token characters, when available.’)last_used_atOptional[datetime] = Field(default=None, description=‘When the API key was last used, or null when unknown.’)nameStrictStr = Field(description=‘The API key name.’)project_idStrictStr = Field(description=‘The project ID.’)project_permissionsList[StrictStr] = Field(description=‘The project permissions granted to the API key.’)revoked_atOptional[datetime] = Field(default=None, description=‘When the API key was revoked, or null while active.’)service_account_idOptional[StrictStr] = Field(default=None, description=‘The service account that owns the API key, when applicable.’)service_account_nameOptional[StrictStr] = Field(default=None, description=‘The service account name, when applicable and available.’)sync_to_v1StrictBool = Field(description=“Whether the v1 ↔ v2 key sync copies this key to Daytona v1 (for an organization that is kept in sync with v1).truefor a live key a person minted in the organization’sdefaultproject unless it was opted out by updating the API key, and always for a live key imported from v1.falsefor every key the sync never copies: keys in other projects, service-account keys, the dashboard’s own key nameddefault, and revoked or expired keys. A v1 copy can read every sandbox, snapshot and registry of the organization on v1, which has no read permissions.”)contextProjectApiKeyContextadditional_propertiesDict[str, Any] = {}
model_config
Section titled “model_config”model_config = ConfigDict(populate_by_name=True, validate_assignment=True, protected_namespaces=())ProjectApiKeyWithContext.to_str
Section titled “ProjectApiKeyWithContext.to_str”def to_str() -> strReturns the string representation of the model using alias
ProjectApiKeyWithContext.to_json
Section titled “ProjectApiKeyWithContext.to_json”def to_json() -> strReturns the JSON representation of the model using alias
ProjectApiKeyWithContext.from_json
Section titled “ProjectApiKeyWithContext.from_json”@classmethoddef from_json(json_str: str) -> Optional[Self]Create an instance of ProjectApiKeyWithContext from a JSON string
ProjectApiKeyWithContext.to_dict
Section titled “ProjectApiKeyWithContext.to_dict”def to_dict() -> Dict[str, Any]Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic’s
self.model_dump(by_alias=True):
Noneis only added to the output dict for nullable fields that were set at model initialization. Other fields with valueNoneare ignored.- Fields in
self.additional_propertiesare added to the output dict.
ProjectApiKeyWithContext.from_dict
Section titled “ProjectApiKeyWithContext.from_dict”@classmethoddef from_dict(obj: Optional[Dict[str, Any]]) -> Optional[Self]Create an instance of ProjectApiKeyWithContext from a dict
ProjectBudget
Section titled “ProjectBudget”class ProjectBudget(BaseModel)A project’s monthly spend budget and its current state.
Attributes:
created_atOptional[datetime] = Field(description=‘When the budget was first set, or null when no budget is set.’)evaluated_atOptional[datetime] = Field(default=None, description=‘When spend was last evaluated in the current period.nulluntil the first evaluation in the period.’)exceeded_atOptional[datetime] = Field(default=None, description=‘When the project reached its budget this period.nullwhile the project is under its budget.’)monthly_limit_centsOptional[StrictInt] = Field(description=‘The monthly budget, in US cents, or null when no budget is set.’)period_start_dateOptional[date] = Field(description=‘The first day of the current budget period (the calendar month in UTC), asYYYY-MM-DD.’)spent_centsOptional[StrictInt] = Field(default=None, description=‘Month-to-date spend at list price, in US cents, from the last evaluation in the current period.nulluntil the first evaluation in the period.’)stop_atOptional[datetime] = Field(default=None, description=‘When running sandboxes are ended:exceeded_atplus the grace period. On the first sweep after this time, running persistent sandboxes are stopped and running ephemeral sandboxes are deleted; macOS sandboxes, which run on a prepaid Mac reservation, keep running.nullwhenexceeded_atisnull, andnullwhen this time falls on or after the start of the next UTC month: the hold expires at the month boundary, so no sandbox is ended this period.’)updated_atOptional[datetime] = Field(description=‘When a member last set the budget, or null when no budget is set. Spend evaluations do not change it.’)additional_propertiesDict[str, Any] = {}
model_config
Section titled “model_config”model_config = ConfigDict(populate_by_name=True, validate_assignment=True, protected_namespaces=())ProjectBudget.to_str
Section titled “ProjectBudget.to_str”def to_str() -> strReturns the string representation of the model using alias
ProjectBudget.to_json
Section titled “ProjectBudget.to_json”def to_json() -> strReturns the JSON representation of the model using alias
ProjectBudget.from_json
Section titled “ProjectBudget.from_json”@classmethoddef from_json(json_str: str) -> Optional[Self]Create an instance of ProjectBudget from a JSON string
ProjectBudget.to_dict
Section titled “ProjectBudget.to_dict”def to_dict() -> Dict[str, Any]Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic’s
self.model_dump(by_alias=True):
Noneis only added to the output dict for nullable fields that were set at model initialization. Other fields with valueNoneare ignored.- Fields in
self.additional_propertiesare added to the output dict.
ProjectBudget.from_dict
Section titled “ProjectBudget.from_dict”@classmethoddef from_dict(obj: Optional[Dict[str, Any]]) -> Optional[Self]Create an instance of ProjectBudget from a dict
LifecyclePolicyConfig
Section titled “LifecyclePolicyConfig”class LifecyclePolicyConfig(TypedDict, total=False)Per-sandbox lifecycle policy: a wall-clock timeout and an idle timeout, each paired with the action it fires.
timeout_seconds (>= 1, never disabled) fires on_timeout that many
seconds after create, after a daytona.v2.Sandbox.update_lifecycle_policy that
supplies it, and again after every accepted transition to running (start,
resume, wake) — the full budget re-arms each time. Omitted on_timeout
resolves to the class default (pause linux persistent, stop windows
persistent, delete ephemeral and gpu).
idle_expiry_seconds is opt-in and fires on_idle_timeout after that many
seconds without activity; DISABLED clears it. on_idle_timeout has
no default — arming idle_expiry_seconds from nothing requires it.
At create, each field you omit is inherited: first from the project’s
lifecycle defaults (set in the dashboard’s project settings; a persistent
sandbox uses the persistent defaults, every other sandbox the ephemeral
ones), then — for timeout_seconds only — from the platform default timeout
when the platform has it enabled. An action follows its own interval: a
timeout_seconds you pass without on_timeout gets the class default, not
the project’s action. Pass DISABLED as idle_expiry_seconds to opt
out of an inherited idle timeout. Project defaults apply to new sandboxes
only; daytona.v2.Sandbox.update_lifecycle_policy never consults them.
archive_interval_seconds is how long a stopped sandbox waits before it is
archived: its disk moves to object storage, and its next start restores it
first. 60 to 2592000 (30 days); 0 means the maximum. Project
defaults do not set it: omitted at create, the platform default (one day)
applies.
Rejected before posting when inapplicable to the sandbox class: see
LifecycleAction for the action matrix; wake_on_request and
archive_interval_seconds need linux persistent.
Attributes:
timeout_secondsinton_timeoutLifecycleActionidle_expiry_secondsinton_idle_timeoutLifecycleActionwake_on_requestboolarchive_interval_secondsint
ListResult
Section titled “ListResult”@dataclass(frozen=True)class ListResult(Generic[T])Cursor-paginated list result.
total and total_relation are only populated
when the result came from the search index (Daytona.list() with any
search filter); they are None on every other list surface.
Attributes:
itemsList[T]next_cursorOptional[str] = NonetotalOptional[int] = Nonetotal_relationOptional[SearchTotalRelation] = Noneraw_total_relationOptional[str] = None
Resources
Section titled “Resources”@dataclass(frozen=True)class Resources()Sandbox resource request; memory and disk are GiB.
cpu/memory/disk are the request: what is reserved and billed as a
floor. cpu_max/memory_max/disk_max are the limits: the boot shape
and the ceiling, the system cap when omitted. Set each limit equal to its
request for a fixed shape. Requests below the platform minimums are raised
to them, so a fixed shape below a minimum is refused.
Attributes:
cpuOptional[float] = Nonecpu_maxOptional[int] = NonememoryOptional[int] = Nonememory_maxOptional[float] = NonediskOptional[int] = Nonedisk_maxOptional[float] = None
NetworkPolicyInput
Section titled “NetworkPolicyInput”class NetworkPolicyInput(TypedDict, total=False)Attributes:
block_allbool | Noneallow_cidrsSequence[str]allow_domainsOptional[Sequence[str]]
NetworkPolicy
Section titled “NetworkPolicy”@dataclass(frozen=True)class NetworkPolicy()Attributes:
versionintblock_allbool = Falseallow_cidrsList[str] = field(default_factory=list)allow_domainsOptional[List[str]] = None
NetworkPolicyInfo
Section titled “NetworkPolicyInfo”@dataclass(frozen=True)class NetworkPolicyInfo()Attributes:
desiredOptional[NetworkPolicy]desired_revisionintetagstrhttp_statusintappliedOptional[NetworkPolicy] = Noneapplied_revisionOptional[int] = Noneapplied_start_idOptional[str] = NonestatusOptional[str] = NoneerrorOptional[str] = None
SnapshotRef
Section titled “SnapshotRef”@dataclass(frozen=True, slots=True)class SnapshotRef()Attributes:
idstrnameOptional[str] = None
ListSandboxesQuery
Section titled “ListSandboxesQuery”@dataclass(frozen=True)class ListSandboxesQuery(SandboxSearchFilters)Every Daytona.list() parameter.
cursor/limit/id/name keep the region-local GET /sandboxes
semantics and remain the only positional parameters, in that order; any
inherited (keyword-only) search filter routes the call to /sandboxes/search.
Attributes:
cursorOptional[str] = NonelimitOptional[int] = NoneidOptional[str] = NonenameOptional[str] = None
idempotency_key_for_name
Section titled “idempotency_key_for_name”def idempotency_key_for_name(name: str) -> strThe idempotency key create*(name=name) derives when none is given.
"name:" + name when that is a key the API accepts verbatim — printable
ASCII (0x20–0x7E), no surrounding whitespace (the API trims keys
and HTTP strips header padding, so a padded name would not round-trip),
at most 256 characters in total — else "name:sha256:" + hex(sha256(name))
over the UTF-8 bytes. The name: namespace keeps a derived key from ever
colliding with a caller’s explicit key of the same spelling. Deterministic
and identical in the TypeScript SDK, so the two SDKs are one client to the
API’s cell-scoped create ledger: use it to recover or inspect the key
behind a named create.
V0_API_URL: Final[str]
Section titled “V0_API_URL: Final[str]”V0_API_URL = 'https://app.daytona.io/api'DEFAULT_V2_API_URL: Final[str]
Section titled “DEFAULT_V2_API_URL: Final[str]”DEFAULT_V2_API_URL = 'https://api.daytona.com'NAME_LABEL: Final
Section titled “NAME_LABEL: Final”NAME_LABEL = 'name'VmStateSnapshot
Section titled “VmStateSnapshot”VmStateSnapshot = _gen.api.SnapshotListItemSnapshotDetail
Section titled “SnapshotDetail”SnapshotDetail = _gen.api.SnapshotVmClass
Section titled “VmClass”VmClass = Literal['linux', 'windows', 'gpu', 'macos']SnapshotKind
Section titled “SnapshotKind”SnapshotKind = Literal['full', 'checkpoint', 'unknown']LifecycleAction
Section titled “LifecycleAction”LifecycleAction = Literal['stop', 'pause', 'delete']The action a lifecycle trigger fires: on_timeout / on_idle_timeout.
Legal per class: delete everywhere; stop needs a persistent sandbox
(linux or windows — never gpu, which is always ephemeral); pause needs
linux persistent.
DISABLED: int
Section titled “DISABLED: int”DISABLED = -1Clears LifecyclePolicyConfig.idle_expiry_seconds — and only that field.
idle_expiry_seconds value space, identical at create and on
daytona.v2.Sandbox.update_lifecycle_policy: omitted = unchanged (update) /
disabled (create); DISABLED (-1) = clear the idle pair (on_idle_timeout
with it); n > 0 = seconds, a value below 60 raised to 60 server-side and
read back raised; 0 and anything below -1 are rejected.
timeout_seconds does NOT accept it: the timeout cannot be disabled, so
timeout_seconds must be >= 1 (-1 and 0 are rejected).