Skip to content

Organizations

An organization is the top-level tenant boundary. A user belongs to one or more organizations via memberships; every project, environment, flag, and audit row lives under exactly one organization.

The Organization object:

json
{
  "id": "9f7a32b5-1234-4abc-9def-…",
  "slug": "acme",
  "name": "Acme",
  "defaultTargetIdField": "userId",
  "createdAt": "2026-04-12T10:00:00Z",
  "updatedAt": "2026-04-29T14:33:00Z"
}

slug is the URL-stable identifier used in path parameters; id is the UUID. defaultTargetIdField is the context key used for percentage-rollout stickiness in projects that haven't overridden it (default userId).


List organizations

http
GET /api/v1/orgs

Lists organizations the calling user (or token) is a member of.

Response: 200 → Organization[]

Create an organization

http
POST /api/v1/orgs
Cookie: actuator_session=…
Content-Type: application/json

{
  "name": "Acme",
  "slug": "acme",
  "defaultTargetIdField": "userId"
}

Session-authenticated only — bearer tokens cannot create orgs. The caller becomes the org's owner. slug must match ^[a-z0-9][a-z0-9._-]{0,127}$ and is unique across the platform.

Response: 201 → OrganizationErrors: 400 invalid_request, 401 unauthorized, 409 slug_unavailable.

Get an organization

http
GET /api/v1/orgs/{slug}

Response: 200 → Organization | 404 not_found

Update an organization

http
PATCH /api/v1/orgs/{slug}
Content-Type: application/json

{
  "name": "Acme Inc.",
  "defaultTargetIdField": "userId"
}

Session role: admin or owner. Bearer scope: write action.

Changing defaultTargetIdField cascades a re-materialize across every environment in every project that hasn't overridden the field — percentage-rollout stickiness is recomputed against the new attribute.

Response: 200 → OrganizationErrors: 400 invalid_request, 403 insufficient_role, 404 not_found.

Delete an organization

http
DELETE /api/v1/orgs/{slug}
Cookie: actuator_session=…
Content-Type: application/json

{ "confirm": "acme" }

Session-authenticated owner only — bearer tokens cannot delete orgs (irreversible action that must not be automatable). The confirm field must equal the org slug exactly, mirroring GitHub's "type the repo name to delete" pattern.

Hard-deletes everything: projects, environments, flags, configs, segments, memberships, API tokens, invitations, version sequences. The audit log survives (no foreign key) but org-scoped audit queries return 404 once the org is gone.

Response: 204 No ContentErrors: 400 invalid_confirmation, 401 unauthorized, 403 insufficient_role, 404 not_found.