Skip to main content
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.

Set up an organization

1

Create the organization

Go to Dashboard > Organization and click Create organization. Give it a name; the URL slug is derived from the name unless you set one.
2

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 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.
3

Create teams (optional)

Teams group members inside an organization so that access 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.
4

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.

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 or a workflow moves as it is (same id and link, you keep editing it, Make private moves it back), and a context document 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. 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 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 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 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. 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. Dashboard: Dashboard > Tools > Create Tools. 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 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.
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:
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, 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 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: 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. 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 (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.

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, 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 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. 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.