> ## Documentation Index
> Fetch the complete documentation index at: https://docs.danubeai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Organizations & Teams

> One governed workspace for your company: members, roles, teams, internal tools, shared credentials and settings

An organization is the unit of governance in Danube. Members share the organization's internal tools and shared credentials, its access policies apply to every agent that calls through a member's key, and every call lands in the organization's audit log.

Every account starts with a personal workspace, shown in the dashboard as **Personal**. Creating a company organization moves your team onto shared governance without changing how agents connect: the same API keys, the same MCP endpoint.

## Roles

Roles are ordered by privilege. A higher role can do everything a lower one can.

| Role | Can do |
| - | - |
| **Owner** | Everything an admin can, plus grant or change the owner role, remove other owners and delete the organization. The last owner cannot be removed or demoted. |
| **Admin** | Manage members, teams, access policies, shared credentials, the organization's own services, settings, the audit log and data-plane agents. Owners and admins skip the allow-lists of [policies](/organizations/policies); only an explicit deny reaches them. |
| **Member** | Use the organization's tools within the access policies. The default role for new members. |
| **Viewer** | Read the organization, its members, teams, services and shared credentials. |

## Set up an organization

<Steps>
  <Step title="Create the organization">
    Go to [Dashboard > Organization](https://danubeai.com/dashboard/organization) and click **Create organization**. Give it a name; the URL slug is derived from the name unless you set one.
  </Step>

  <Step title="Add members">
    Members are added by the email address of an existing Danube account, with a role. There is no invitation email in this release: ask teammates to sign up at [danubeai.com](https://danubeai.com) first, then add them. Members per organization follow the owner's plan (Free: 1, Pro: 5, Team and Enterprise: unlimited); past the limit the request answers `402` with the reason. A personal organization cannot have additional members.
  </Step>

  <Step title="Create teams (optional)">
    Teams group members inside an organization so that [access policies](/organizations/policies) can target a team instead of individuals. Admins add and remove team members on the Organization page; each team member is a `member` or a `lead`.
  </Step>

  <Step title="Switch workspace">
    The workspace switcher at the top of the dashboard sidebar controls which organization you are acting in. Services you register, keys you create, credentials you share and policies you edit belong to the active organization.
  </Step>
</Steps>

## Personal and your organizations

You have one account. The workspace you pick is where you work.

* **An organization** is where its members work together: its internal tools, shared credentials, context, skills and keys. Members start in their organization when they open the dashboard.
* **Personal** is your own sandbox. It shows only your own tools, keys, credentials, skills, workflows and context, and none of any organization's. Nothing in it is shared.

Work in Personal and move what is good into the organization: a [skill](/organizations/skills#share-a-skill-with-your-organization) or a [workflow](/organizations/workflows) moves as it is (same id and link, you keep editing it, **Make private** moves it back), and a [context document](/organizations/context#share-a-document-with-your-organization) is copied.

Switching workspace reloads every page's data for the new one. Plan limits are per account: calls made in any workspace count toward the same monthly quota. The usage analytics on the Tools page are per workspace; an organization's usage is counted from 27 September 2026, when calls started recording the organization they were made in.

## Who sees what: the four visibility tiers

Every service carries a `visibility`, and its tools inherit it.

| Visibility | Who can see and search it | Where its tools run |
| - | - | - |
| `public` | Everyone, signed in or not. The catalog. | Danube |
| `private` | The owner only. | Danube |
| `internal` | The owner and every member of the organization it is scoped to. | Danube |
| `local_only` | The same audience as `internal`. | Only through the organization's [data-plane agent](/organizations/data-plane), inside your network |

The rule is applied everywhere a tool can be read: search, a service's tool list, a tool by id or name, related tools, autocomplete and recommendations. A service or tool you may not see reads as **not found** (`404`), never as forbidden, so an id cannot be confirmed by probing it. Inside an organization the [grant policy](/organizations/policies) narrows this further: a tool a member is not granted is left out of their search results and service tool lists, and a call to it is refused.

Internal and local-only services appear in the dashboard's Tools page on a tab named after the organization, with an **Internal** or **In your network** badge, and stay out of the public catalog.

## The acting organization

A request acts for one organization at a time. It is chosen, in this order:

1. **The `danube-org-id` header.** Send the organization id on any request and Danube acts in that organization, provided the caller is a member; a header naming an organization the caller does not belong to is ignored over the API and refused with `403` by the MCP server. MCP clients that let you set headers pass it through unchanged.
2. **An organization-owned API key.** A key created in a shared organization acts for it with no header at all. The header wins when both are present. A key in a personal organization sets nothing.
3. **The dashboard switcher**, for dashboard sessions. Choosing **Personal** sends your personal organization's id, which acts outside every shared organization: no organization's internal tools, shared credentials, credential rules, parameter defaults, skills or context apply.

The acting organization decides which organization an internal service is registered in through `POST /v1/services`, which shared credential is tried first, whether the organization's [rate and spend caps](/organizations/policies#organization-caps) apply, and which organization's audit log records the call.

## Who can manage a service

Editing a service, deleting it, refreshing its tools, and adding, changing, deprecating or deleting tools under it is allowed for:

* the service's **owner** (the account that registered it),
* an **owner or admin of the organization** the service is scoped to (`internal`, `local_only` or `private` rows registered for the organization),
* a **platform admin**.

Anyone else gets `403 You do not manage this service`, or `404` when they may not see the service at all. An ownerless public catalog row is the platform's and needs a platform admin. Every catalog write is recorded in the [audit log](/organizations/audit-log) as `service.*` or `tool.*`.

## Register an internal service

An owner or admin registers a service for the organization from an OpenAPI URL, an OpenAPI document, a remote MCP server or a [connector spec](/connectors). The service is stamped with the organization, the caller as owner and the visibility chosen: `internal` by default, `local_only` for a service the organization's data-plane agent runs, or `private` for the caller alone. The task-oriented walkthrough is [Onboard an internal tool](/organizations/internal-tools).

**Dashboard:** [Dashboard > Tools > Create Tools](https://danubeai.com/dashboard/tools/new). Set **Owner** to the organization (offered when you are an owner or admin of it) and **Visibility** to *Internal* or *Runs inside your network*, then **Preview import** to see the tools it would create before you click create. The [Connector Builder](https://danubeai.com/dashboard/tools/connector) has the same owner and visibility controls.

**Endpoint:** `POST /v1/organizations/{org_id}/services`, owner or admin, with a session token or an API key.

```bash theme={null}
curl -X POST "https://api.danubeai.com/v1/organizations/ORG_ID/services" \
  -H "danube-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "openapi_url",
    "openapi_url": "https://billing.example.com/openapi.json",
    "name": "Billing",
    "visibility": "internal",
    "dry_run": true
  }'
```

With `"dry_run": true` nothing is written; the response previews the service and every tool, each marked `create`, or `update` when a same-named service you manage already holds a tool at that method and path:

```json theme={null}
{
  "service": {"name": "Billing", "description": "Internal invoicing", "visibility": "internal", "api_base_url": "https://billing.example.com"},
  "tools": [{"name": "Get Invoice", "method": "GET", "path": "/v1/invoices/{id}", "action": "create"}],
  "errors": [],
  "would_exceed_caps": false,
  "sync": "done"
}
```

Without `dry_run` the response is `{"service": {...}, "tool_count": N, "tools_failed": [...], "sync": "done" | "running" | "skipped", "warnings": [...]}`. An MCP server's tools are discovered by a background sync after the row exists (`sync: "running"`); for a `local_only` MCP server the sync runs through the organization's [data-plane agent](/organizations/data-plane#mcp-servers), and a local (stdio) server is refused with `400`. An import that registers no tool, or loses more than half of its operations, deletes the service again and answers `400` with the per-tool errors. A name already carried by a service you cannot manage is refused with `409`.

`POST /v1/services`, the API-key registration route, follows the same rules for anyone who is not a platform admin: `public` is refused with `403` (a public listing goes through `POST /v1/submissions` for review), `internal` and `local_only` need a `danube-org-id` header naming an organization you own or administer (`400` otherwise), and `private` lands in your personal organization. The dashboard's `/openapi` and `/mcp` creation routes default to `private`.

`GET /v1/organizations/{org_id}/services` lists the organization's own services for any member.

## Shared credentials

A credential stored for the organization is used by every member who holds no credential of their own for that service. Owners and admins store one with `PUT /v1/organizations/{org_id}/credentials/{service_id}` and a body of `{"credentials": {"type": "api_key", "value": "..."}}` (any fields the service's credential form takes), or from the credential form on a service page with the organization selected. `POST /v1/credentials/api-key` with `org_id` is the same store. OAuth connections are always personal and cannot be shared.

At call time Danube tries the member's own credential first, then the acting organization's shared credential, then a shared credential of any other organization the member belongs to. A [credential rule](#credential-rules) replaces this order for a service. Every read is written to the audit log as `credential.read`, with `org_shared` in its metadata.

`GET /v1/organizations/{org_id}/credentials` lists the shared credentials for any member: the service, the credential type, who stored it and when. A value never leaves the server. Remove one under **Shared credentials** on the Organization page or with `DELETE /v1/organizations/{org_id}/credentials/{service_id}` (owner or admin).

### Credential rules

An owner or admin can decide, per service, which credential members' calls use:

| Rule | Members' calls use |
| - | - |
| None (default) | The member's own credential, then a shared one, in the order above |
| **Shared only** | Always the organization's shared credential. A member's own credential for the service is ignored |
| **Own only** | Always the member's own credential. No shared credential applies, from this organization or any other |

For example, a company can require every agent to use its one shared Supabase access token while each employee's agent sends Gmail as that employee.

Set a rule under **Credentials for \<organization>** on the service's page, or with `PUT /v1/organizations/{org_id}/credentials/{service_id}/policy` and a body of `{"mode": "shared"}` or `{"mode": "personal"}`. Remove it on the Organization page under **Credential rules** or with `DELETE .../credentials/{service_id}/policy`. Any member can list the rules with `GET /v1/organizations/{org_id}/credentials/policy`. A rule change is recorded in the audit log as `org.credential_policy_update`.

When a member belongs to several organizations, the acting organization's rule for the service applies first, then the first other organization that sets one. A shared credential and an **Own only** rule for the same service contradict each other, so each is refused with `409` while the other exists. Under **Shared only** with no shared credential stored yet, calls fail with `auth_required`, `reason: "org_policy"` and a message naming the organization. An agent should not store a personal key in that case, because the rule ignores it.

## Teams and grants

With no grants, every member has full access to the organization's tools. The first grant switches the organization to deny-by-default: from then on a member can use only what a grant allows, an explicit deny wins over any allow, and a tool a member is not granted is hidden from their search results and service tool lists. A grant targets the whole organization, a role or a team. The public catalog is never allow-listed, but a deny on a catalog service or tool applies to every call made in the organization's context. See [Tool Access Policies](/organizations/policies).

Teams are created and listed under `/v1/organizations/{org_id}/teams`; members are added by profile id or email with `POST .../teams/{team_id}/members` and removed with `DELETE .../teams/{team_id}/members/{user_id}` (admin or owner; the person must already belong to the organization). Deleting a team removes its memberships and every grant that targeted it.

## Organization keys and limits

An API key can belong to the organization rather than to the person who created it: choose the organization under **Workspace** when creating a key in [Dashboard > API Keys](https://danubeai.com/dashboard/api-keys) (the list there shows the selected workspace's keys first; **All workspaces** shows every key you hold), pass `org_id` to `POST /v1/api-keys`, or run `danube login --org <id-or-slug>` so the device flow mints one (the user who authorizes the code must be a member). Calls made with an organization key run in that organization's context without a `danube-org-id` header; when both are present, a header naming an organization the caller belongs to wins. Owners and admins see every member's organization keys under the organization's tab on the API Keys page (`GET /v1/api-keys?org_id=`) and can revoke any of them; a member sees only their own. A member who leaves loses theirs.

Two limits in **Organization > Settings > Limits** apply to every call made in the organization's context, on top of any per-key caps: **calls per minute** across all keys, and a **daily spend cap** on paid calls since midnight UTC. A call over either limit is refused with `usage_limit_reached` (a `Retry-After` header on the per-minute one) and recorded in the audit log as a denial.

## Settings

Settings are edited with `PATCH /v1/organizations/{org_id}/settings` (owner or admin) or from the dashboard pages named below. Unknown keys are refused with `422`; an explicit `null` removes a key. Every change is recorded as `org.settings_update` with the names of the keys that changed. Settings are returned on `GET /v1/organizations` and `GET /v1/organizations/{org_id}` for owners and admins only.

| Key | Effect | Default | Dashboard |
| - | - | - | - |
| `dataplane.store_payloads` | `false` is residency mode: the parameters and results of data-plane calls are never written to Danube, only a size and a SHA-256. | `true` | Organization > Settings |
| `execution_retention_days` | Delete the organization's execution history older than this many days, nightly, in batches. `1` to `3650`. | absent, keep indefinitely | Organization > Settings |
| `audit_retention_days` | Delete audit events older than this many days, nightly. `30` to `3650`; the 30-day floor cannot be lowered. | absent, keep forever | Audit Log |
| `rate_limit_per_minute` | Calls per minute across every key acting for the organization. `1` to `100000`. | absent, no cap | Organization > Settings |
| `daily_spend_cap_cents` | Paid-call spend since midnight UTC across the organization's keys. `0` to `100000000`. | absent, no cap | Organization > Settings |
| `llm_internal_tools` | `false` keeps internal and local-only tool definitions and results out of hosted AI prompts. | `true` | Organization > Settings |

## Hosted AI and internal tools

Hosted workflows and the workflow generator run on a hosted model. By default that model can see every tool a member may use, internal tools included. **Hosted AI can use internal tools**, under Data handling on the [Organization page](https://danubeai.com/dashboard/organization), turns that off for the organization's internal and local-only tools:

* A hosted workflow gets no function definition for a withheld tool, and a result that would be forwarded to the model is replaced by a placeholder. The step still runs and its real result is kept in the execution.
* The workflow generator never proposes a withheld tool.

Public tools and personal private tools are not affected. The setting is `llm_internal_tools` on `PATCH /v1/organizations/{org_id}/settings` (owner or admin); absent or `true` is the default behaviour.

## When a member is removed

Admins remove members; any member can leave; only an owner can remove another owner, and the last owner cannot leave. On removal the organization's API keys that member created are revoked and any personal credential rows stamped with the organization are deleted; shared credentials belong to the organization and stay. The response and the `member.remove` audit event carry `api_keys_revoked` and `credentials_deleted`. Membership caches are cleared on the spot, so the organization's internal tools disappear from the person's search results and calls at once.

## Plans

Organizations carry a plan (`free`, `team`, or `enterprise`) that is separate from an individual account's subscription. See [Plans & Billing](/billing) for what each tier includes and how to upgrade.

## Endpoints

All organization endpoints live under `/v1/organizations` and accept the same authentication as the dashboard (a session token) or an API key. A non-member gets `404` from every organization route, so the organization's existence is not revealed.

| Method | Path | Minimum role |
| - | - | - |
| `POST` | `/v1/organizations` | any signed-in user |
| `GET` | `/v1/organizations` | member (lists your organizations with your role) |
| `GET` `PATCH` `DELETE` | `/v1/organizations/{org_id}` | viewer / admin / owner |
| `PATCH` | `/v1/organizations/{org_id}/settings` | admin |
| `GET` `POST` | `/v1/organizations/{org_id}/members` | viewer / admin |
| `PATCH` `DELETE` | `/v1/organizations/{org_id}/members/{user_id}` | admin (owner to change or remove owners; any member may remove themselves) |
| `GET` `POST` | `/v1/organizations/{org_id}/teams` | viewer / admin |
| `DELETE` | `/v1/organizations/{org_id}/teams/{team_id}` | admin |
| `GET` `POST` | `/v1/organizations/{org_id}/teams/{team_id}/members` | viewer / admin |
| `DELETE` | `/v1/organizations/{org_id}/teams/{team_id}/members/{user_id}` | admin |
| `GET` `POST` | `/v1/organizations/{org_id}/services` | viewer / admin |
| `GET` | `/v1/organizations/{org_id}/credentials` | viewer |
| `PUT` `DELETE` | `/v1/organizations/{org_id}/credentials/{service_id}` | admin |
| `GET` `POST` | `/v1/organizations/{org_id}/grants` | admin |
| `DELETE` | `/v1/organizations/{org_id}/grants/{grant_id}` | admin |
| `GET` | `/v1/organizations/{org_id}/audit` | admin |
| `GET` | `/v1/organizations/{org_id}/audit/export` | admin |

Member operations take the Danube user id of the member. Adding a member takes `{"email": "...", "role": "member"}`. The full request and response shapes are in the [OpenAPI document](/api-reference/introduction).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.