Workbenches is an open standard. Read why
Docs Organizations

API reference

Organizations

Every user has a personal organization, created at first sign-in. It is an ordinary organization with ordinary membership rules, except that it cannot be deleted. Organizations are called publishers in some error messages.

The organization object#

Field Type Meaning
id UUID
slug string, 2 to 48 characters Lowercase words joined by -.
name string, 1 to 80 characters
description string or null Up to 500 characters.
website URL or null
logo_url URL or null
accent #rrggbb or null
verified boolean
personal boolean A user's personal organization.
created_at, updated_at date-time

List organizations#

GET /v1/organizations

Open. With mine=true, session only.

Query Type Meaning
slug slug Only this organization.
mine true The caller's organizations, each with a role (owner, admin, or member).

Response 200 { "organizations": [ ... ] }.

Create an organization#

POST /v1/organizations

Session only. The creator becomes owner.

Field Type Meaning
slug slug, 2 to 48 characters Required.
name string, 1 to 80 characters Required.
description string, 1 to 500 characters
website URL
accent #rrggbb

Response 201: the organization.

Get an organization#

GET /v1/organizations/:id

Open. Response 200: the organization.

Update an organization#

PATCH /v1/organizations/:id

Key org:admin with manager creator, or session: manager.

Field Type
name string, 1 to 80 characters
description string up to 500 characters, or null
website URL or null
accent #rrggbb or null

Response 200: the organization.

Delete an organization#

DELETE /v1/organizations/:id

Session: owner only, from the dashboard. A key can never delete its own organization. Deletes the organization's members, keys, Workbenches, versions, submissions, and images, and is audited. 409 for a personal organization. Response 200 { "deleted": true }.

Members#

List members#

GET /v1/memberships?organization_id=<uuid>

Session: member. Response 200:

{
    "members": [
        {
            "id": "uuid",
            "name": "Ada Lovelace",
            "email": "ada@example.com",
            "image": null,
            "role": "owner",
            "current": true,
            "created_at": "..."
        }
    ]
}

current marks the caller.

Remove a member#

DELETE /v1/memberships/:id

Session: member. Response 200 { "deleted": true }. Removing a member, or a member leaving, revokes every key that person created in the organization.

Invitations#

List invitations#

GET /v1/invitations?organization_id=<uuid>

Session: member. Response 200 { "invitations": [ { "id", "email", "status", "expires_at", "created_at" } ] }. status is pending, accepted, revoked, or expired.

Invite#

POST /v1/invitations

Session: member.

Field Type
organization_id UUID
email email address

Response 201:

Field Meaning
invitation The invitation.
delivery sent, preview, or failed.
acceptance_url The link to accept, or null.

Refused with 402 plan_limit when members and live pending invitations are at the plan's member cap.

Revoke an invitation#

DELETE /v1/invitations/:id

Session: member. Response 200 { "deleted": true }.

Accept an invitation#

POST /v1/acceptances with { "token": "..." } (32 to 256 characters)

Session only. The signed-in email must match the invited email. Response 201: the organization. Refused when the organization's joined members are at the cap.

Logos#

:id is the organization's ID.

Method Path Auth Result
GET /v1/logos/:id Open The logo bytes. Supports If-None-Match.
PUT /v1/logos/:id Key org:admin with manager creator, or session: manager Upload a logo: the raw image as the body, with its content-type. Returns the organization.
DELETE /v1/logos/:id Key org:admin with manager creator, or session: manager Remove the logo. Returns the organization.

Analytics#

POST /v1/analytics with { "organization_id": "uuid" }

Key catalog:read, or session: member. Save and run counts for the organization's Workbenches, as the CLI reports them:

{
    "totals": { "saves": 12, "runs": 40, "workbenches": 3 },
    "series": [{ "day": "2026-10-28", "saves": 1, "runs": 4 }]
}

series holds up to 30 days.