# Organizations (/docs/organizations)

Daytona provides organizations as a way to group resources and enable collaboration. Users can work individually in their personal organization or together in a collaborative organization.

Manage your organizations in the [Daytona Dashboard ↗](https://app.daytona.com/dashboard) or through the [API](/docs/api/daytona).

<OrganizationsVisual />

## Personal vs Collaborative [#personal-vs-collaborative]

Every Daytona user starts with a personal organization for solo use and experimentation. Collaborative organizations are created manually for teams, with shared access and controls.

| **Feature**        | **Personal organization**        | **Collaborative organization**                 |
| ------------------ | -------------------------------- | ---------------------------------------------- |
| **Creation**       | Automatic on signup              | Manually by a user                             |
| **Members**        | Single user only                 | Multiple users (invite-based)                  |
| **Access Control** | No roles or permissions          | Roles with fixed permission sets               |
| **Billing**        | Tied to individual user          | Shared across team members                     |
| **Use Case**       | Personal testing, small projects | Company/team development and production        |
| **Quota Scope**    | Per user                         | Shared across all members                      |
| **Deletable**      | No                               | Yes (by admins)                                |

Switch between personal and collaborative organizations with the dropdown in the [Daytona Dashboard ↗](https://app.daytona.com/dashboard) sidebar. Each organization has its own sandboxes, API keys, and resource quotas.

## Create organization [#create-organization]

Create organizations in the [Daytona Dashboard ↗](https://app.daytona.com/dashboard/) or with the [API](/docs/api/daytona).

1. Go to [Daytona Dashboard ↗](https://app.daytona.com/dashboard/)
2. Expand the dropdown at the top-left corner of the sidebar to view your organizations
3. Click <Button>Create Organization</Button>
4. Enter the organization name
5. Select a [region](/docs/regions)
6. Click <Button>Create</Button>

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona org create 'My Organization'
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{
  "name": "My Organization"
}'
```

| **Field** | **Type** | **Description**                                                                                                             |
| --------- | -------- | --------------------------------------------------------------------------------------------------------------------------- |
| `name`    | string | Sets the organization name. The name is trimmed and must be 1 to 100 characters with no control characters. Other values return `400`. This field is required. |

</TabItem>
</Tabs>

## Operations [#operations]

### List organizations [#list-organizations]

List all organizations the authenticated user belongs to.

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona org list
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

</TabItem>
</Tabs>

### Select organization [#select-organization]

Select the organization that following CLI commands run against. The CLI also restores the [project](/docs/projects#select-project) you last used in that organization, or its default project. Pass an ID or an unambiguous name; with no argument, the CLI shows a picker at a terminal.

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona org use ORGANIZATION_ID
```

</TabItem>
</Tabs>

### Get by ID [#get-by-id]

Get an organization by ID.

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona org get ORGANIZATION_ID
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

</TabItem>
</Tabs>

### Current user [#current-user]

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
# The signed-in user, the credential in use, and the selected organization and project
daytona whoami
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
# The calling user: id, email, name
curl 'https://api.daytona.com/me' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

</TabItem>
</Tabs>

### Current organization API key [#current-organization-api-key]

Get the organization API key that authenticates the request, with the organization permissions it holds now. The response never contains the token.

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/api-keys/current' \
  --header 'Authorization: Bearer YOUR_ORG_API_KEY'
```

```json
{
  "id": "KEY_ID",
  "org_id": "ORGANIZATION_ID",
  "name": "my-org-key",
  "key_prefix": "dtno_...",
  "org_permissions": ["read:audit"],
  "created_at": "2026-09-10T12:00:00Z",
  "expires_at": null,
  "last_used_at": "2026-09-11T08:30:00Z",
  "revoked_at": null
}
```

<Callout type="note" title="Notes">
- The request requires an organization API key.
</Callout>

</TabItem>
</Tabs>

### Rename organization [#rename-organization]

Rename an organization. The new name follows the same rules as on create: it is trimmed, and must be 1 to 100 characters with no control characters.

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona org update ORGANIZATION_ID --name 'New Organization Name'
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID' \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{
  "name": "New Organization Name"
}'
```

</TabItem>
</Tabs>

### Leave organization [#leave-organization]

Leave an organization.

1. Go to [Daytona Dashboard ↗](https://app.daytona.com/dashboard/)
2. Expand the dropdown at the top-left corner of the sidebar to view your organizations
3. Select the organization you want to leave
4. Click <Button>Settings</Button> in the sidebar
5. Click <Button>Leave Organization</Button>
6. Confirm by clicking <Button>Leave</Button>

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona org leave ORGANIZATION_ID
```

<Callout type="note" title="Notes">
- The request requires the `read:organization` permission.
- `daytona org leave` asks for confirmation at a terminal and requires `--yes` otherwise.
</Callout>

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
# Leaving is a self-removal: USER_ID is the id returned by GET /me
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/members/USER_ID' \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

</TabItem>
</Tabs>

### Delete organization [#delete-organization]

Delete an organization.

1. Go to [Daytona Dashboard ↗](https://app.daytona.com/dashboard/)
2. Expand the dropdown at the top-left corner of the sidebar to view your organizations
3. Select the organization you want to delete
4. Click <Button>Settings</Button> in the sidebar
5. Click <Button>Delete Organization</Button>
6. Confirm the deletion by typing the organization name and clicking <Button>Delete</Button>

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona org delete ORGANIZATION_ID
```

<Callout type="note" title="Notes">
- The request requires the `delete:organization` permission.
- The organization must not be a personal organization.
- The organization must have no sandboxes, volumes, images, snapshots, or functions, and no live Mac reservation.
- `daytona org delete` asks for confirmation at a terminal and requires `--yes` otherwise.
</Callout>

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID' \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

<Callout type="note" title="Notes">
- The request requires the `delete:organization` permission.
- The organization must not be a personal organization.
- The organization must have no sandboxes, volumes, images, snapshots, or functions, and no live Mac reservation.
</Callout>

</TabItem>
</Tabs>

## Roles [#roles]

Each member of an organization holds one or more roles. A role is a set of permissions, and a member's permissions are the union of the permissions of all roles they hold. Daytona provides the built-in roles below, and an organization on the Enterprise plan can also define [custom roles](#create-custom-role) from its own choice of permissions. The admin role is protected: the organization must always keep at least one admin, and only an admin can grant or remove it. An invitation that names no roles grants the developer role.

| **Role**                       | **Description**                                                                                      |
| ------------------------------ | ---------------------------------------------------------------------------------------------------- |
| **`admin`**                    | Full control of the organization, its members, and everything in it                                  |
| **`maintainer`**               | Full control of everything inside the organization's projects, with no authority over the organization itself |
| **`developer`**                | Run and manage sandboxes, invoke functions, and view everything a sandbox can use                    |
| **`read-only`**                | View every project resource, and change none of them                                                 |
| **`member`**                   | Sign in and see the organization, with no access to any resource                                     |
| **`auditor`**                  | Read the organization's [audit log](/docs/audit-logs), without the ability to turn it off         |
| **`billing`**                  | See what the organization spends and manage how it pays                                              |
| **`spending-viewer`**          | See what the organization spends, and nothing about how it pays                                      |
| **`budget-manager`**           | Set and remove monthly budgets on the projects the member can access                                 |
| **`sso-admin`**                | Configure [single sign-on](/docs/sso) for the organization                                        |
| **`infrastructure-admin`**     | Read-only access to the organization. A reserved role kept so existing assignments continue to work  |
| **`sandboxes-manager`**        | Create, change, and delete sandboxes                                                                 |
| **`snapshots-manager`**        | Create, change, and delete snapshots and images                                                      |
| **`volumes-manager`**          | Create, change, and delete volumes                                                                   |
| **`registries-manager`**       | Create, change, and delete private container registries                                              |
| **`secrets-manager`**          | Create, change, and delete project secrets                                                           |
| **`functions-manager`**        | Deploy, invoke, change, and delete serverless functions                                              |

### List roles [#list-roles]

List all roles in an organization: the built-in roles, then the organization's custom roles by name.

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
# The built-in roles and the permissions each role grants
daytona role list
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
# The built-in roles, then the organization's custom roles
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/roles' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'

# The built-in roles only
curl 'https://api.daytona.com/roles' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

The organization's list has the following fields:

| **Field** | **Description** |
| --------- | --------------- |
| `roles` | The built-in roles, then the custom roles. |
| `max_custom_roles` | The most custom roles the organization can define. |

Each role has the following fields:

| **Field** | **Description** |
| --------- | --------------- |
| `id` | Identifies the role: the identifier of a built-in role, such as `developer`, or the UUID of a custom role. |
| `name` | The display name. |
| `description` | The purpose of the role. |
| `kind` | The kind is `built_in` or `custom`. |
| `project_permissions` | The project permissions the role grants. |
| `organization_permissions` | The organization permissions the role grants. |
| `permissions` | Every permission the role grants: the project permissions, then the organization permissions. |

</TabItem>
</Tabs>

### Get role [#get-role]

Get one role of an organization, built-in or custom, with the permissions it grants.

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
# ROLE_ID is the identifier of a built-in role, such as developer, or the UUID of a custom role
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/roles/ROLE_ID' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

The response has the fields of a role in [list roles](#list-roles).

</TabItem>
</Tabs>

### Create custom role [#create-custom-role]

Define a role from your own choice of permissions. A custom role can grant only permissions you hold. Every role includes the organization read permission, and a role that grants any project permission also includes the permissions to read projects and to create project API keys. Custom roles are assigned like built-in roles, to members, service accounts, and invitations.

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/roles' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{
  "name": "Sandbox operator",
  "description": "Runs and manages sandboxes",
  "project_permissions": ["read:sandboxes", "write:sandboxes"],
  "organization_permissions": ["read:organization", "read:projects", "write:project_api_keys"]
}'
```

| **Field** | **Type** | **Description** |
| --------- | -------- | --------------- |
| `name` | string | Sets the role name, unique in the organization ignoring case and different from the name of every built-in role. Leading and trailing whitespace is removed, and runs of whitespace inside become one space. The result must be from `1` to `64` characters. This field is required. |
| `description` | string | Sets the purpose of the role, at most `256` characters. |
| `project_permissions` | string\[\] | Sets the project permissions the role grants. This field is required. |
| `organization_permissions` | string\[\] | Sets the organization permissions the role grants. It must include `read:organization`, and also `read:projects` and `write:project_api_keys` when `project_permissions` is not empty. This field is required. |

The response has the fields of a role in [list roles](#list-roles).

<Callout type="note" title="Notes">
- The request requires the `write:roles` permission and the Enterprise [plan](/docs/billing#get-the-plan).
- The role can grant only permissions you hold.
- [List permissions](#list-permissions) returns the permission identifiers the role can grant.
- The organization can define at most `max_custom_roles` custom roles, as [list roles](#list-roles) returns it.
- Assign the role by its `id` in the `roles` of an invitation, a member, or a service account.
</Callout>

</TabItem>
</Tabs>

### Update custom role [#update-custom-role]

Change the name, description, or permissions of a custom role. A permission list in the request replaces the role's list. Narrowing a role revokes the API keys of its holders that exceed their new permissions. A preview reports what the same update would change without applying it. Built-in roles cannot be changed.

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
# Report what the update would change, without applying it
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/roles/ROLE_ID/update-preview' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{
  "project_permissions": ["read:sandboxes"]
}'

# Apply the update
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/roles/ROLE_ID' \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{
  "project_permissions": ["read:sandboxes"]
}'
```

| **Field** | **Type** | **Description** |
| --------- | -------- | --------------- |
| `name` | string | Sets the new role name. Whitespace is normalized as on create, and the result must be from `1` to `64` characters. |
| `description` | string | Sets the new purpose of the role, at most `256` characters. |
| `project_permissions` | string\[\] | Replaces the project permissions the role grants. |
| `organization_permissions` | string\[\] | Replaces the organization permissions the role grants. |

The preview response has the following fields:

| **Field** | **Description** |
| --------- | --------------- |
| `revoked_api_keys` | The number of API keys the update would revoke. |
| `affected_members` | The number of members who hold the role. |
| `affected_service_accounts` | The number of active service accounts that hold the role. |
| `pending_invitations` | The number of pending invitations that grant the role. |

The update response has the following fields:

| **Field** | **Description** |
| --------- | --------------- |
| `role` | The updated role, with the fields of a role in [list roles](#list-roles). |
| `revoked_api_keys` | The number of API keys the update revoked. |

<Callout type="note" title="Notes">
- The requests require the `write:roles` permission and the Enterprise [plan](/docs/billing#get-the-plan). An update or preview that only removes permissions does not require the Enterprise plan.
- The role's current and new permissions must be within the permissions you hold, and you must be able to assign roles to every member and service account that holds the role.
</Callout>

</TabItem>
</Tabs>

### Delete custom role [#delete-custom-role]

Delete a custom role. A role that a member, a service account, or a pending invitation holds cannot be deleted; remove it from them first. Built-in roles cannot be deleted.

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/roles/ROLE_ID' \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

</TabItem>
</Tabs>

### List permissions [#list-permissions]

List the permissions that roles and API keys grant. Each permission has an identifier, a display name, and a display category. Project permissions apply to the resources inside a project, and organization permissions apply to the organization itself.

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
# Every permission; scope=project or scope=organization restricts the list to one scope
curl 'https://api.daytona.com/permissions?scope=project' \
  --header 'Authorization: Bearer YOUR_API_KEY'
```

| **Parameter** | **Type**  | **Description**                                                                                     |
| ------------- | --------- | --------------------------------------------------------------------------------------------------- |
| `scope`       | string  | Restricts the list to `project` or `organization` permissions. Any other value returns `400`. Omit it to list both. |

</TabItem>
</Tabs>

## Members [#members]

Daytona provides methods to manage members in an organization.

### List members [#list-members]

List all members in an organization.

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona member list --org ORGANIZATION_ID
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/members' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

</TabItem>
</Tabs>

### Invite members [#invite-members]

Invite a new user to an organization.

1. Go to [Daytona Dashboard ↗](https://app.daytona.com/dashboard/members)
2. Click <Button>Invite Member</Button>
3. Enter the email address of the user you want to invite
4. Select one or more [roles](#roles) for the new user under **Roles**

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona invite create mail@example.com --org ORGANIZATION_ID --role developer
```

| **Flag** | **Type** | **Description**                       |
| -------- | -------- | ------------------------------------- |
| `--role` | string | Sets the roles, as a comma-separated list of role slugs. |

<Callout type="note" title="Notes">
- The request requires the `write:members` permission.
- When the deployment sends no email, `daytona invite create` prints the invitation link to share with the invitee.
</Callout>

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
# roles defaults to ["developer"] when omitted
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/invitations' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{
  "email": "mail@example.com",
  "roles": ["developer"]
}'
```

The response has the following fields:

| **Field**    | **Description**                                                                                          |
| ------------ | -------------------------------------------------------------------------------------------------------- |
| `id`         | The invitation ID.                                                                                       |
| `roles`      | The roles the invitee receives on acceptance.                                                            |
| `status`     | The invitation status.                                                                                   |
| `expires_at` | When the invitation expires.                                                                             |
| `accept_url` | The invitation link to share with the invitee when the deployment sends no email, or `null` when the invitation was sent by email. |

</TabItem>
</Tabs>

### Remove members [#remove-members]

Remove a user from an organization.

1. Go to [Daytona Dashboard ↗](https://app.daytona.com/dashboard/members)
2. Click <Button>Remove</Button> next to the user you want to remove
3. Confirm the removal by clicking <Button>Remove</Button>

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
# Preview what the member loses before removing them
daytona member remove USER_ID --org ORGANIZATION_ID --dry-run

daytona member remove USER_ID --org ORGANIZATION_ID
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
# Preview what the member loses before removing them
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/members/USER_ID/removal-preview' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'

curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/members/USER_ID' \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

The removal preview response has the following fields:

| **Field**                | **Description**                                                                                                              |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `revoked_api_keys`       | Holds the count of project and organization API keys that the removal revokes.                                               |
| `revoked_preview_grants` | Holds the count of signed preview grants that the removal deletes. The value is `null` when the count is unknown, not `0`.  |

</TabItem>
</Tabs>

### Update access [#update-access]

Update the access of a member in an organization.

1. Go to [Daytona Dashboard ↗](https://app.daytona.com/dashboard/members)
2. Click the three-dot menu on the member row
3. Click <Button>Edit roles</Button>
4. Select the member's [roles](#roles) and click <Button>Save</Button>

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
# Replace the member's role set
daytona member update USER_ID --org ORGANIZATION_ID --role maintainer,billing

# Rehearse the change without applying it
daytona member update USER_ID --org ORGANIZATION_ID --role read-only --dry-run
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
# Replace the member's role set
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/members/USER_ID' \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{
  "roles": ["maintainer", "billing"]
}'

# Rehearse the change without applying it: { "revoked_api_keys": ..., "revoked_preview_grants": ... }
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/members/USER_ID/update-preview' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{
  "roles": ["read-only"]
}'
```

| **Field** | **Type**   | **Description**                                      |
| --------- | ---------- | ---------------------------------------------------- |
| `roles`   | string\[\] | Replaces the member's whole role set. This field is required.      |

<Callout type="note" title="Notes">
- The requests require the `write:members` permission.
- You cannot change your own roles.
- You can change only a member whose current and requested permissions you hold.
- Only an admin can grant or remove the admin role.
</Callout>

</TabItem>
</Tabs>

## Invitations [#invitations]

View an organization invitation from the link or token in the invitation email.

1. Open the link in the invitation email; it opens [Daytona Dashboard ↗](https://app.daytona.com/dashboard/user/invitations)
2. Review the organization, inviter, roles, and expiry of the invitation

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
# Show the invitation behind the dtni_ token or the link from the invitation email
daytona invite get INVITATION_TOKEN
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
# Show the invitation behind the dtni_ token from the invitation email
curl 'https://api.daytona.com/invitations/lookup' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{ "token": "INVITATION_TOKEN" }'
```

</TabItem>
</Tabs>

### Accept invitation [#accept-invitation]

Accept a pending organization invitation.

1. Open the link in the invitation email; it opens [Daytona Dashboard ↗](https://app.daytona.com/dashboard/user/invitations)
2. Sign in if prompted
3. Review the organization, inviter, roles, and expiry of the invitation
4. Click <Button>Accept</Button>

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona invite accept INVITATION_TOKEN
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/invitations/accept' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{ "token": "INVITATION_TOKEN" }'
```

<Callout type="note" title="Notes">
- The token is single-use.
</Callout>

</TabItem>
</Tabs>

Once a user accepts an invitation to join an organization, they get access to the organization's resource quotas and can create an [API key](/docs/api-keys) and sandboxes.

### Decline invitation [#decline-invitation]

Decline a pending organization invitation.

1. Open the link in the invitation email; it opens [Daytona Dashboard ↗](https://app.daytona.com/dashboard/user/invitations)
2. Sign in if prompted
3. Review the organization, inviter, roles, and expiry of the invitation
4. Click <Button>Decline</Button>
5. Confirm by clicking <Button>Decline</Button>

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona invite decline INVITATION_TOKEN
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/invitations/decline' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{ "token": "INVITATION_TOKEN" }'
```

</TabItem>
</Tabs>

### List pending [#list-pending]

List pending invitations for an organization.

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona invite list --org ORGANIZATION_ID
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/invitations' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

<Callout type="note" title="Notes">
- The request requires the `read:members` permission.
- The list also contains declined and expired invitations; use `declined_at` and `expires_at` to tell them apart from pending ones.
</Callout>

</TabItem>
</Tabs>

### Cancel invitation [#cancel-invitation]

Cancel an invitation for an organization.

1. Go to [Daytona Dashboard ↗](https://app.daytona.com/dashboard/members)
2. Scroll to the **Invitations** table
3. Click the three-dot menu on the invitation row
4. Click <Button>Cancel</Button>
5. Confirm by clicking <Button>Confirm</Button>

<Tabs syncKey="language">
<TabItem label="CLI" icon="seti:shell">

```bash
daytona invite revoke INVITATION_ID --org ORGANIZATION_ID
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/invitations/INVITATION_ID' \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

</TabItem>
</Tabs>

## Limits [#limits]

Get the effective [organization limits](/docs/limits#organization-limits) and the current usage they are checked against. Each limit reports its effective cap and the usage counted against it. The member limit also counts the pending invitations that reserve a seat. A read with an API key returns the limits of the API key's organization and leaves out the member limit.

<Tabs syncKey="language">
<TabItem label="Python" icon="seti:python">

```python
from daytona import Daytona

daytona = Daytona()

limits = daytona.v2.get_limits()
concurrent = limits.sandboxes.concurrent
print(f"Concurrent sandboxes: {concurrent.usage} of {concurrent.limit}")
```

<Callout type="note" title="Notes">
- The request requires the `read:limits` permission with an API key, or the `read:organization` permission when signed in.
- With `jwt_token` authentication, pass `organization_id`.
</Callout>

</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">

```typescript
import { Daytona } from '@daytona/sdk'

const daytona = new Daytona()

const limits = await daytona.v2.getLimits()
const concurrent = limits.sandboxes.concurrent
console.log(`Concurrent sandboxes: ${concurrent.usage} of ${concurrent.limit}`)
```

<Callout type="note" title="Notes">
- The request requires the `read:limits` permission with an API key, or the `read:organization` permission when signed in.
- With `jwtToken` authentication, pass `organizationId`.
</Callout>

</TabItem>
<TabItem label="CLI" icon="seti:shell">

```bash
# The argument is optional; omit it to use the selected organization
daytona org limits ORGANIZATION_ID
```

<Callout type="note" title="Notes">
- The request requires the `read:limits` permission with an API key, or the `read:organization` permission when signed in.
</Callout>

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/limits' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

```json
{
  "sandboxes": {
    "concurrent": { "limit": 10, "usage": 2 },
    "total": { "limit": 50, "usage": 4 },
    "gpu_concurrent": { "limit": 0, "usage": 0 },
    "windows_concurrent": { "limit": 0, "usage": 0 }
  },
  "image_builds": { "concurrent": { "limit": null, "usage": 0 } },
  "storage": {
    "volumes": { "limit": null, "usage": 2 },
    "images": { "limit": null, "usage": 5 },
    "snapshots": { "limit": null, "usage": 3 }
  },
  "members": { "limit": 5, "usage": 3, "pending_invitations": 1 },
  "api_keys_per_organization": { "limit": 1000, "usage": 12 },
  "api_keys_per_project": { "limit": 100, "usage": 7 },
  "secrets_per_project": { "limit": 500, "usage": 20 }
}
```

The response has the following fields:

| **Field**                   | **Description**                                                                                                     |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `limit`                     | Each limit reports its effective cap in `limit`. A value of `null` means no limit. Reaching the cap refuses new work. |
| `usage`                     | Each limit reports the current usage counted against it in `usage`.                                                 |
| `sandboxes`                 | The concurrent, total, GPU, and Windows sandbox limits.                                                 |
| `image_builds`              | The concurrent image build limit.                                                                                   |
| `storage`                   | The volume, image, and snapshot limits.                                                                             |
| `members`                   | The seat cap. `pending_invitations` counts the invitations that reserve a seat until they are accepted or declined. |
| `api_keys_per_organization` | The live API key limit of the organization.                                                                         |
| `api_keys_per_project`      | The live API key limit of any one project, with the highest current usage.                                          |
| `secrets_per_project`       | The secret limit of any one project, with the highest current usage.                                                |

<Callout type="note" title="Notes">
- The request requires the `read:limits` permission with an API key, or the `read:organization` permission when signed in.
</Callout>

</TabItem>
</Tabs>

### Set the timeout cap [#set-the-timeout-cap]

Set or clear the organization's maximum sandbox timeout. Daytona validates every sandbox [timeout](/docs/linux-sandboxes#timeout) against this cap. The cap can be any value up to the platform maximum, and clearing it inherits the platform maximum.

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
# Cap every sandbox timeout in the organization at 1 hour
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID' \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{ "max_sandbox_timeout_seconds": 3600 }'

# Clear the cap and inherit the platform maximum
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID' \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --data '{ "max_sandbox_timeout_seconds": null }'
```

| **Field**                     | **Type**  | **Description**                                                                                     |
| ----------------------------- | --------- | --------------------------------------------------------------------------------------------------- |
| `max_sandbox_timeout_seconds` | integer | Sets the cap in seconds, up to the platform maximum, which is `86400` by default. A value of `null` clears the cap. A value above the platform maximum returns `400`. |

<Callout type="note" title="Notes">
- The request requires the `write:organization` permission.
- The request requires a signed-in user token.
</Callout>

</TabItem>
</Tabs>

## Entitlements and feature flags [#entitlements-and-feature-flags]

Entitlements are the capabilities an organization's plan grants; feature flags are platform switches evaluated per organization. Both are read-only and return every catalog key, so a client never has to guess at an absent key.

### Entitlements [#entitlements]

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/entitlements' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

```json
{
  "entitlements": {
    "preview_warning_opt_out": false
  }
}
```

<Callout type="note" title="Notes">
- The request requires the `read:organization` permission, which every role includes.
</Callout>

</TabItem>
</Tabs>

### Feature flags [#feature-flags]

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/feature-flags' \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN'
```

<Callout type="note" title="Notes">
- The request requires the `read:organization` permission, which every role includes.
</Callout>

</TabItem>
</Tabs>

## Preview warning [#preview-warning]

Turn the preview warning page off or on. It applies to every [sandbox preview](/docs/preview) in the organization and decides whether a visitor sees the warning page first.

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/orgs/ORGANIZATION_ID/preview-warning' \
  --request PATCH \
  --header 'Authorization: Bearer YOUR_OIDC_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{ "disabled": true }'
```

| **Field** | **Type** | **Description** |
| --------- | -------- | --------------- |
| `disabled` | boolean | Turns the preview warning off when `true` and on when `false`. |

<Callout type="note" title="Notes">
- The request requires the `write:organization` permission.
- Turning the preview warning off requires the Team or Enterprise [plan](/docs/billing#get-the-plan).
- Turning the preview warning on is available on every plan.
</Callout>

</TabItem>
</Tabs>

## OpenTelemetry configuration [#opentelemetry-configuration]

Forward the logs, traces, and metrics of every sandbox in the organization to your OpenTelemetry collector. The forwarding configuration holds the OTLP/HTTP endpoint and the request headers to send. Getting the configuration requires the `read:organization` permission, and setting or deleting it requires the `write:organization` permission. For the requests and their fields, see [forward sandbox telemetry](/docs/opentelemetry#forward-sandbox-telemetry).

## Permissions [#permissions]

Organization settings and membership are governed by organization permissions, which you can grant through an [organization role](/docs/organizations#roles).

Every role includes the organization read permission, and leaving an organization requires only that permission. The [audit logs](/docs/audit-logs) record organization changes, invitations, and member changes.

| **Permission**            | **Grants**                                                                                       |
| ------------------------- | ------------------------------------------------------------------------------------------------ |
| **`read:organization`**   | Get the organization, its limits, entitlements, feature flags, and telemetry configuration       |
| **`write:organization`**  | Rename the organization and change its timeout cap, preview warning, and telemetry configuration |
| **`delete:organization`** | Delete the organization                                                                          |
| **`read:members`**        | List members and pending invitations                                                             |
| **`write:members`**       | Invite members, change their access, and cancel invitations                                      |
| **`delete:members`**      | Remove members                                                                                   |
| **`write:roles`**         | Create and update custom roles                                                                   |
| **`delete:roles`**        | Delete custom roles                                                                              |
