Amba

Organizations

Parent→child organizations as the ownership + payment boundary, plus the idempotent app-factory provisioning call.

An organization is the ownership and payment boundary that sits above projects. Every developer gets a personal org at signup; teams and app factories create additional orgs and nest them. Ownership is the authoritative boundary — a member of a parent org manages every descendant org and project — while developer_id is retained on each project as creator/contact.

Billing stays per project (tier, usage, the project's own subscription are unchanged). The org is only the payment entity: it holds the Stripe customer Amba charges and the Connect account Amba pays. A per-org payment_source toggle — 'self' (the org uses its own card) or 'parent' (defer up the tree to the nearest self-paying ancestor) — is the "bill the parent agency vs. bill the child directly" switch.

Endpoints

MethodPathDescription
POST/v1/admin/orgsCreate an org (optionally under a parent_org_id).
GET/v1/admin/orgsList orgs you own or manage, plus their descendants.
GET/v1/admin/orgs/:orgIdGet one org + your effective role.
PATCH/v1/admin/orgs/:orgIdUpdate name / slug / payment_source.
DELETE/v1/admin/orgs/:orgIdDelete an empty org (409 ORG_NOT_EMPTY otherwise).
GET/v1/admin/orgs/:orgId/membersList members (owner/admin only — emails are PII).
POST/v1/admin/orgs/:orgId/invitesInvite a developer by email (owner/admin).
POST/v1/admin/orgs/:orgId/transfer-ownershipTransfer ownership (owner only).
POST/v1/admin/orgs/:orgId/detachDetach a child org to a root (graduation; owner only).
POST/v1/admin/provisionIdempotent app-factory: org + project + keys in one call.
GET/v1/admin/projects/:projectId/provisioning-statusPoll provisioning state for a freshly-created project.

Org-invite acceptance is a separate router mounted at /v1/admin/org-invites (the acceptor doesn't know the org until they accept).

Access model

authorizedForOrg / authorizedForProject resolve the caller's effective role by walking the org tree upward (depth-bounded) and taking the strongest grant across: the retained project creator, the owner of the project's org or any ancestor, organization_members on the org or an ancestor, and per-project project_members. A parent-org manager therefore manages all descendants; a child member never gains access upward or sideways. Mutations and PII reads require manage-level (owner or admin).

POST /v1/admin/orgs

FieldTypeRequiredDescription
namestringyesDisplay name.
parent_org_idstringnoNest under a parent (you must manage the parent). Omit for a root.
slugstringnoUnique slug when set.
payment_sourcestringno'self' (default) or 'parent'.

POST /v1/admin/provision (app factory)

One idempotent call that provisions a child org + project and returns its keys — built for an app factory standing up hundreds of generated apps under one root-org PAT.

FieldTypeRequiredDescription
parent_org_idstringyesThe root/agency org to provision under (you must manage it).
external_refstringyesYour stable id for this customer/app. The idempotency anchor.
org_namestringyesName for the child org.
project_namestringnoName for the project (defaults from org_name).
bundle_idstringnoApp bundle id passed through to provisioning.

One-time-key contract. The first call returns plaintext api_keys (client + server) and idempotent: false. A retry with the same (parent_org_id, external_ref) returns the same org/project ids, idempotent: true, keys_already_issued: true, and no plaintext — keys are sha256-hashed and unrecoverable. Lost keys are re-issued via the project's api-keys endpoint. Concurrent double-POSTs collapse to a single org/project (FOR UPDATE on the parent). The same external_ref under two different parents yields two orgs.

After a fresh insert, provisioning runs asynchronously; poll GET /v1/admin/projects/:projectId/provisioning-status until active.

Graduation (agency → direct)

A child that outgrows the factory graduates without moving any project or database:

  1. POST .../transfer-ownership — hand the org to the customer's developer (optionally removing the previous owner).
  2. PATCH .../:orgId with payment_source: 'self' — the org now bills its own card.
  3. POST .../detach — promote the child to a root (refused while payment_source = 'parent').

MCP tools

amba_orgs_create, amba_orgs_list, amba_orgs_get, amba_orgs_update, amba_orgs_invite_member, amba_orgs_transfer_owner, and the dedicated amba_provision_app for the app-factory call.

On this page