Skip to Content
API ReferenceOrganizations

Organizations API

Org-level routes. All require Authorization: Bearer <access_token> with the appropriate IdentityOrgPermission granted on the org by the caller’s role.

:orgSlug in the URL identifies the org. Slugs are stable, lowercase, URL-safe.

Create an org

POST /identity/organizations

{ name: string // 1–80 chars slug: string // [a-z0-9-]{3,30}, globally unique description?: string // up to 500 chars }

Response (201): the created Org.

Errors:

  • validation_failed — slug or name failed validation.
  • conflict — slug already exists.

Get an org

GET /identity/organizations/:orgSlug

Requires org.read (implied by every member).

Response:

interface Org { id: string name: string slug: string description?: string iconFile?: FileTracker createdBy: string stripeProductId?: string | null stripeCustomerId?: string createdAt: string updatedAt: string }

Update an org

PATCH /identity/organizations/:orgSlug — requires org.edit.

{ name?: string description?: string | null iconFile?: string | null // FileTracker id, or null to clear }

slug is not editable once set. Create a new org if you need a new slug.

Delete an org

DELETE /identity/organizations/:orgSlug — requires org.delete, owner-only.

Soft-deletes. All brands, apps, members, webhooks, and token gates under the org are disabled. The slug is reserved (cannot be reused for 90 days).

Response: 204 No Content.

List orgs

GET /identity/organizations — returns orgs the caller is a member of (or all orgs, with admin.orgs.view).

Query params:

ParamTypeDefault
limit1–10050
offsetnumber0

Response:

{ items: Org[] total: number }

Members

List members

GET /identity/organizations/:orgSlug/members

Requires org.members.view.

{ items: Array<{ userId: string user: User // full shape roles: Array<{ id: string; name: string }> joinedAt: string }> total: number }

Add role

POST /identity/organizations/:orgSlug/members/:userId/roles

Requires org.members.edit.

{ roleId: string }

Idempotent. If the role is already assigned, returns the unchanged state. Returns 201.

Remove role

DELETE /identity/organizations/:orgSlug/members/:userId/roles/:roleId

Requires org.members.edit.

Returns 204. Cannot remove the last role from a member — call DELETE /members/:userId to remove them entirely.

Remove member

DELETE /identity/organizations/:orgSlug/members/:userId

Requires org.members.edit. Removes the member from the org. Their access tokens for this org are not invalidated automatically — they expire on their own; revoke explicitly if you need immediate cutoff.

Owner cannot be removed; transfer ownership first.

Transfer ownership

POST /identity/organizations/:orgSlug/transfer-ownership

Requires org.ownership.transfer (owner-only).

{ newOwnerUserId: string }

Transitions ownership atomically. The previous owner keeps Admin role; the new owner gains the Owner role.

Roles

List roles

GET /identity/organizations/:orgSlug/roles

{ items: Array<{ id: string name: string description?: string isBuiltIn: boolean permissions: string[] // IdentityOrgPermission strings createdAt: string updatedAt: string }> }

Built-in roles (Owner, Admin, Member) cannot be edited or deleted.

Create a custom role

POST /identity/organizations/:orgSlug/roles

Requires org.members.edit.

{ name: string // 1–60 chars description?: string permissions: string[] // any subset of IdentityOrgPermission }

Response (201): the new role.

Update a custom role

PATCH /identity/organizations/:orgSlug/roles/:roleId

{ name?: string description?: string | null permissions?: string[] // replaces existing list }

Cannot edit built-in roles.

Delete a custom role

DELETE /identity/organizations/:orgSlug/roles/:roleId

Cannot delete if any member currently has this role assigned; unassign first.

Admin (system) routes

Routes under /admin/identity/organizations/... require AdminPermission.OrgsView / .OrgsEdit. They mirror the org-scoped routes above but bypass org membership checks. Used by Synq staff for support; you probably will not call these.

Rate limits

Endpoint patternLimit
GET /identity/organizations/*60/min/org
POST/PATCH/DELETE …30/min/org

Errors

Standard REST envelope. See Errors for the full catalog.

Most common:

  • forbidden — missing org permission. details.missing is the required permission.
  • conflict — slug or role name in use.
  • validation_failed — body validation; details.fields lists each.
Last updated on