Projects
Create and manage projects within your organization.
Projects group resources and credentials inside an organization. Organizations contain projects, and projects contain everything else: every sandbox, image, snapshot, volume, secret, registry credential, and API key is scoped to exactly one project.
Projects are the unit of isolation. Nothing is shared between projects implicitly: a secret or volume in one project is invisible to sandboxes in another, and a project's API key cannot see other projects' resources. Organizations are the unit of membership and billing.
| Concept | Description |
|---|---|
| Organization | The unit of membership and billing. Members, invitations, and credits belong to the organization. Contains any number of projects. |
| Project | The unit of isolation. Holds sandboxes, images, snapshots, volumes, secrets, registry credentials, and API keys. |
| API key | Minted per project. Confined to that project and to its permission scopes; revoking a key takes effect immediately for new requests. |
Every organization has a project named default that cannot be renamed or deleted. The name is reserved, so no other project can use it.
Project access
Projects also decide which organization members can reach their resources:
- Organization admins can access every project.
- Every member can access the
defaultproject. - Any other project is visible only to members who have been added to it. Members who are not on a project get a
404for it, as if it did not exist.
Whoever creates a project is added to it automatically.
Projects are managed on the dashboard's Projects page and switched in the header's organization and project switcher. These routes use your dashboard session token (an OIDC bearer JWT), not a project API key, and need matching organization project permissions.
Create projects
Create a project. Names are trimmed, unique per organization, and up to 100 characters.
- Go to Daytona Dashboard
- Click Create Project
- Enter a Name for the project
- Click Create Project
You can also click the project switcher in the header and choose Create Project.
daytona project create my-project --org ORG_IDThe creator field is null unless the caller holds the members read permission.
Operations
List projects
List the projects you can access in an organization. The default project is always listed first.
daytona project list --org ORG_IDSelect project
Select the project that later CLI commands run against. The selection is per organization, so switching organizations restores your last project there. Pass an ID or an unambiguous name; with no argument, the CLI shows a picker at a terminal.
daytona project use PROJECT_IDGet by ID
Get a single project.
daytona project get PROJECT_IDRename projects
Rename a project. The default project cannot be renamed.
- Go to Daytona Dashboard
- Click the ⋮ menu of the project
- Click Rename
- Enter the new name and confirm
daytona project update PROJECT_ID --name my-renamed-project --org ORG_IDDelete projects
Delete a project, revoking its API keys and removing its secrets and registries.
The default project cannot be deleted.
- Go to Daytona Dashboard
- Click the ⋮ menu of the project
- Click Delete
- Confirm the deletion
daytona project delete PROJECT_ID --org ORG_IDProject budgets
A project budget caps the project's spend in each calendar month, in UTC, at list price and before credits. When the month-to-date spend reaches the budget, creating, forking, starting, or resuming a sandbox in the project, or restoring one from a snapshot, is refused. After the organization's grace period, running persistent sandboxes are stopped and running ephemeral sandboxes are deleted. The hold lifts at the start of the next month; when the grace period would end after that, no sandbox is ended that month.
Spend is evaluated periodically and can lag usage by several minutes. Reading a budget requires the budgets read permission; setting or removing it requires budgets write.
Get a project budget
Get a project's monthly budget and this month's spend. The SDKs, and the API with an API key, read the budget of the API key's project.
from daytona import Daytona
daytona = Daytona()
budget = daytona.v2.get_project_budget()
if budget is None:
print("The project has no budget")
else:
print(f"Spent {budget.spent_cents} of {budget.monthly_limit_cents} cents")Set a project budget
Set or replace a project's monthly budget. Project budgets require the Team plan or above.
- Go to Daytona Dashboard
- Click the project
- In the Budget section, click Set budget, or Edit budget to replace an existing one
- Enter the Monthly budget in USD
- Click Save
# The argument is optional; omit it to use the selected project
daytona project budget set PROJECT_ID --monthly-usd 500| Flag | Type | Description |
|---|---|---|
--monthly-usd | string | Required. Monthly budget in US dollars, at least 1.00 and at most two decimals, such as 500 or 499.99. |
Remove a project budget
Remove a project's monthly budget. Removing it releases a budget hold on the project; sandboxes that were already stopped stay stopped.
- Go to Daytona Dashboard
- Click the project
- In the Budget section, click Remove budget
- Confirm with Remove
# The argument is optional; omit it to use the selected project
daytona project budget remove PROJECT_IDLifecycle defaults
Lifecycle defaults set the timeouts that new sandboxes in a project receive when the create request leaves them out. A project stores two blocks: one for ephemeral sandboxes, whose timeouts always delete the sandbox, and one for persistent sandboxes, which also sets the action each timeout fires and whether the sandbox wakes on request.
Daytona reads the defaults only when it creates a sandbox. Each field the create request sets overrides the matching default, saving new defaults never changes existing sandboxes, and a fork keeps its parent's policy. A Windows persistent sandbox runs an inherited pause as stop and ignores wake on request.
Get lifecycle defaults
Get a project's stored lifecycle defaults and the policy a create without lifecycle settings receives for each sandbox type.
- Go to Daytona Dashboard
- Click the project
- Open the Settings tab and find the Sandbox Lifecycle Policy section
curl 'https://api.daytona.com/projects/PROJECT_ID/lifecycle-policy' \
--header 'Authorization: Bearer YOUR_OIDC_TOKEN'{
"policy": {
"ephemeral": { "timeout_secs": 1800, "idle_timeout_secs": 600 },
"persistent": {
"timeout_secs": 28800,
"on_timeout": "pause",
"idle_timeout_secs": 900,
"on_idle_timeout": "stop",
"wake_on_request": true
}
},
"max_timeout_secs": 86400,
"effective": {
"linux": {
"ephemeral": { "timeout_secs": 1800, "on_timeout": "delete", "timeout_source": "project", "timeout_capped": false, "idle_timeout_secs": 600, "on_idle_timeout": "delete", "wake_on_request": false },
"persistent": { "timeout_secs": 28800, "on_timeout": "pause", "timeout_source": "project", "timeout_capped": false, "idle_timeout_secs": 900, "on_idle_timeout": "stop", "wake_on_request": true }
},
"windows": {
"ephemeral": { "timeout_secs": 1800, "on_timeout": "delete", "timeout_source": "project", "timeout_capped": false, "idle_timeout_secs": 600, "on_idle_timeout": "delete", "wake_on_request": false },
"persistent": { "timeout_secs": 28800, "on_timeout": "stop", "timeout_source": "project", "timeout_capped": false, "idle_timeout_secs": 900, "on_idle_timeout": "stop", "wake_on_request": false }
},
"gpu": {
"ephemeral": { "timeout_secs": 1800, "on_timeout": "delete", "timeout_source": "project", "timeout_capped": false, "idle_timeout_secs": 600, "on_idle_timeout": "delete", "wake_on_request": false }
}
}
}The response has the following fields:
| Field | Description |
|---|---|
policy | Holds the stored values. An unset field is null. The exception is wake_on_request, which is always a boolean. |
max_timeout_secs | The organization's effective maximum timeout, in seconds. |
effective | Holds what a create with no lifecycle settings receives. |
timeout_source | The value in each effective block is project, platform, or none. |
timeout_capped | The value in each effective block is true when a stored timeout above max_timeout_secs is capped to max_timeout_secs. |
Update lifecycle defaults
Update a project's lifecycle defaults. Each block is updated as a whole: a block left out of the request is kept, an empty value clears it, and a sent block replaces the stored one, so a field left out of a sent block is unset.
- Go to Daytona Dashboard
- Click the project
- Open the Settings tab
- In the Sandbox Lifecycle Policy section, click the edit button on the Ephemeral sandboxes or Persistent sandboxes card
- Set the timeouts and actions, then click Save
curl 'https://api.daytona.com/projects/PROJECT_ID/lifecycle-policy' \
--request PATCH \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
--data '{
"ephemeral": { "timeout_secs": 1800, "idle_timeout_secs": 600 },
"persistent": {
"timeout_secs": 28800,
"on_timeout": "pause",
"idle_timeout_secs": 900,
"on_idle_timeout": "stop",
"wake_on_request": true
}
}'| Field | Type | Description |
|---|---|---|
ephemeral | object | Sets the timeouts for ephemeral sandboxes. null clears the block. If omitted, the stored block is kept. |
ephemeral.timeout_secs | integer | Sets the seconds until an ephemeral sandbox is deleted, from 1 to the organization's maximum timeout. By default, it is unset. |
ephemeral.idle_timeout_secs | integer | Sets the idle seconds until an ephemeral sandbox is deleted. Values below 60 are raised to 60. By default, it is unset. |
persistent | object | Sets the timeouts for persistent sandboxes. null clears the block. If omitted, the stored block is kept. |
persistent.timeout_secs | integer | Sets the seconds until on_timeout fires, from 1 to the organization's maximum timeout. By default, it is unset. |
persistent.on_timeout | string | Sets the action when timeout_secs elapses: stop, pause, or delete. It requires timeout_secs. When unset, the default action of the sandbox type applies. |
persistent.idle_timeout_secs | integer | Sets the idle seconds until on_idle_timeout fires. Values below 60 are raised to 60. It requires on_idle_timeout. By default, it is unset. |
persistent.on_idle_timeout | string | Sets the action when idle_timeout_secs elapses: stop, pause, or delete. It requires idle_timeout_secs. By default, it is unset. |
persistent.wake_on_request | boolean | Resumes a parked sandbox on inbound authenticated traffic. It applies only to Linux persistent sandboxes. The default is false. |
Project members
Control which organization members can access a non-default project. Listing members requires the members read permission; adding and removing them requires the members write permission. Organization admins are members of every project implicitly and do not need to be added.
List project members
daytona project member list --project PROJECT_IDThe implicit flag is true for organization admins, who have access without a membership entry.
Add project members
Add a single member, or several at once with the bulk endpoint.
daytona project member add USER_ID --project PROJECT_ID --org ORG_ID
daytona project member add --bulk USER_ID_1,USER_ID_2 --project PROJECT_ID --org ORG_ID| Flag | Type | Description |
|---|---|---|
--bulk | string | A comma-separated list of user IDs, emails, or names. Cannot be combined with a positional user. |
Remove project members
Remove a member from a project. Unless they are an organization admin, removal also revokes the API keys they minted in the project; admins keep access through their role.
daytona project member remove USER_ID --project PROJECT_ID --org ORG_IDProject service accounts
List project service accounts
List the service accounts that can hold API keys in a project. A service account mints keys only in projects it has been added to. The default project is open to every service account.
daytona project service-account list --project PROJECT_IDAdd project service accounts
Add a service account to a project. Archived service accounts cannot be added, and you must hold every permission the account holds.
daytona project service-account add SERVICE_ACCOUNT_ID --project PROJECT_ID --org ORG_IDRemove project service accounts
Remove a service account from a project, revoking every API key it holds there.
daytona project service-account remove SERVICE_ACCOUNT_ID --project PROJECT_ID --org ORG_IDProject secrets
List project secrets
daytona secret list --project PROJECT_IDGet a project secret
Get a project secret. The response contains the secret's metadata only; the value is write-only and never returned. See secrets for how sandboxes use secrets.
daytona secret get MY_API_KEY --project PROJECT_IDSet a project secret
Set a project secret, replacing any with the same name. The value is encrypted at rest.
printf %s 'secret-value' | daytona secret set MY_API_KEY --stdin --project PROJECT_ID| Flag | Type | Description |
|---|---|---|
--stdin | bool | Strips exactly one trailing newline (or CRLF) from the value. |
--from-file | string | Strips exactly one trailing newline (or CRLF) from the value. |
Delete a project secret
daytona secret delete MY_API_KEY --project PROJECT_IDProject registries
List project registries
daytona registry list --project PROJECT_IDGet a project registry
Get a project registry credential by its host. The response contains the credential's metadata only; the password is write-only and never returned.
daytona registry get ghcr.io --project PROJECT_IDSet a project registry
Set a registry credential for a host, replacing any existing one. The kind must match the host, so a misconfigured credential fails when you save it rather than when an image is pulled.
| Kind | Accepted host |
|---|---|
basic | Any host. Docker Hub aliases are stored as index.docker.io. |
ghcr | ghcr.io |
gcr | gcr.io, *.gcr.io, or *-docker.pkg.dev |
ecr | <account-id>.dkr.ecr.<region>.amazonaws.com. The access keys must belong to the AWS account named in the host. |
printf %s 'YOUR_GITHUB_PAT' | daytona registry set ghcr.io \
--kind ghcr \
--username YOUR_GITHUB_USERNAME \
--password-stdin \
--project PROJECT_ID| Flag | Type | Description |
|---|---|---|
--kind | string | The default is basic. For an existing registry, an omitted --kind keeps the stored kind. |
Delete a project registry
daytona registry delete ghcr.io --project PROJECT_ID