# Org

> The Org operations of the Kabu API: settings, feature toggles and entitlements.

Settings, feature toggles and entitlements.

Generated from the contract, version `2.0.0-draft.2` ([OpenAPI](/openapi.yaml)). Base URL `https://usekabu.com/api`. Errors are problem details, each [code](/docs/errors) with its own page.

## `GET /v2/org` · Org settings, feature toggles and entitlements

- **Auth:** an API key, or a signed-in human's token (the Kabu apps).
- **Scopes:** `org:write`.
- **Signed-in humans:** `member`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `Kabu-Org` | header | string | no | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |

| Status | Means | Body |
|---|---|---|
| `200` | OK | [Org](#schema-Org) |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl "https://usekabu.com/api/v2/org" \
  -H "Authorization: Bearer $KABU_API_KEY"
```

## `PATCH /v2/org` · Update org settings and feature toggles

- **Auth:** an API key, or a signed-in human's token (the Kabu apps).
- **Scopes:** `org:write`.
- **Signed-in humans:** `admin`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `Kabu-Org` | header | string | no | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |

**Request body**: [OrgUpdate](#schema-OrgUpdate).

| Status | Means | Body |
|---|---|---|
| `200` | OK | [Org](#schema-Org) |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl -X PATCH "https://usekabu.com/api/v2/org" \
  -H "Authorization: Bearer $KABU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

## `POST /v2/orgs` · Orgs create

- **Kabu apps only:** a signed-in human's token. Integrations use API keys.
- **Signed-in humans:** `self`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `Idempotency-Key` | header | string, at most 255 characters | no | Retry-safe key. For messages, sessions and responses it binds to the created object for its life; elsewhere for 24 h. |

**Request body**: [OrgCreate](#schema-OrgCreate).

| Status | Means | Body |
|---|---|---|
| `201` | OK | [Org](#schema-Org) |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl -X POST "https://usekabu.com/api/v2/orgs" \
  -H "Authorization: Bearer $KABU_USER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name":"…"}'
```

## `GET /v2/org/members` · Org members list

- **Kabu apps only:** a signed-in human's token. Integrations use API keys.
- **Signed-in humans:** `member`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `limit` | query | integer, from 1 to 100 | no |  |
| `after` | query | string | no | Opaque cursor from next_cursor. |
| `Kabu-Org` | header | string | no | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |

| Status | Means | Body |
|---|---|---|
| `200` | OK | [OrgMemberList](#schema-OrgMemberList) |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl "https://usekabu.com/api/v2/org/members" \
  -H "Authorization: Bearer $KABU_USER_TOKEN"
```

## `PATCH /v2/org/members/{user_id}` · Org members update

- **Kabu apps only:** a signed-in human's token. Integrations use API keys.
- **Signed-in humans:** `admin`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `user_id` | path | string | yes | Member user id. |
| `Kabu-Org` | header | string | no | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |

**Request body**: [OrgMemberUpdate](#schema-OrgMemberUpdate).

| Status | Means | Body |
|---|---|---|
| `200` | OK | [OrgMember](#schema-OrgMember) |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl -X PATCH "https://usekabu.com/api/v2/org/members/$USER_ID" \
  -H "Authorization: Bearer $KABU_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role":"admin"}'
```

## `DELETE /v2/org/members/{user_id}` · Org members remove

- **Kabu apps only:** a signed-in human's token. Integrations use API keys.
- **Signed-in humans:** `admin`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `user_id` | path | string | yes | Member user id. |
| `Kabu-Org` | header | string | no | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |

| Status | Means | Body |
|---|---|---|
| `204` | Done |  |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl -X DELETE "https://usekabu.com/api/v2/org/members/$USER_ID" \
  -H "Authorization: Bearer $KABU_USER_TOKEN"
```

## `POST /v2/org/transfer` · Org transfer

- **Kabu apps only:** a signed-in human's token. Integrations use API keys.
- **Signed-in humans:** `owner`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `Idempotency-Key` | header | string, at most 255 characters | no | Retry-safe key. For messages, sessions and responses it binds to the created object for its life; elsewhere for 24 h. |
| `Kabu-Org` | header | string | no | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |

**Request body**: [OrgTransfer](#schema-OrgTransfer).

| Status | Means | Body |
|---|---|---|
| `200` | OK | [Org](#schema-Org) |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl -X POST "https://usekabu.com/api/v2/org/transfer" \
  -H "Authorization: Bearer $KABU_USER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"user_id":"…"}'
```

## `GET /v2/org/invites` · Org invites list

- **Kabu apps only:** a signed-in human's token. Integrations use API keys.
- **Signed-in humans:** `admin`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `limit` | query | integer, from 1 to 100 | no |  |
| `after` | query | string | no | Opaque cursor from next_cursor. |
| `Kabu-Org` | header | string | no | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |

| Status | Means | Body |
|---|---|---|
| `200` | OK | [OrgInviteList](#schema-OrgInviteList) |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl "https://usekabu.com/api/v2/org/invites" \
  -H "Authorization: Bearer $KABU_USER_TOKEN"
```

## `POST /v2/org/invites` · Org invites create

Team orgs only. Single-use, expiring, hashed tokens; invites confer membership, never recipient pairing.

- **Kabu apps only:** a signed-in human's token. Integrations use API keys.
- **Signed-in humans:** `admin`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `Idempotency-Key` | header | string, at most 255 characters | no | Retry-safe key. For messages, sessions and responses it binds to the created object for its life; elsewhere for 24 h. |
| `Kabu-Org` | header | string | no | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |

**Request body**: [OrgInviteCreate](#schema-OrgInviteCreate).

| Status | Means | Body |
|---|---|---|
| `201` | OK | [OrgInviteWithToken](#schema-OrgInviteWithToken) |
| `429` | A rate, concurrency or quota limit was reached | [Problem](/docs/api/discovery#schema-Problem) |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl -X POST "https://usekabu.com/api/v2/org/invites" \
  -H "Authorization: Bearer $KABU_USER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"role":"admin"}'
```

## `DELETE /v2/org/invites/{invite_id}` · Org invites revoke

- **Kabu apps only:** a signed-in human's token. Integrations use API keys.
- **Signed-in humans:** `admin`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `invite_id` | path | string | yes | Invite id. |
| `Kabu-Org` | header | string | no | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |

| Status | Means | Body |
|---|---|---|
| `204` | Done |  |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl -X DELETE "https://usekabu.com/api/v2/org/invites/$INVITE_ID" \
  -H "Authorization: Bearer $KABU_USER_TOKEN"
```

## `GET /v2/org/invites/preview` · Preview a membership invite

- **Auth:** no credentials.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `token` | query | string | no |  |

| Status | Means | Body |
|---|---|---|
| `200` | OK | [OrgInvite](#schema-OrgInvite) |
| `429` | A rate, concurrency or quota limit was reached | [Problem](/docs/api/discovery#schema-Problem) |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl "https://usekabu.com/api/v2/org/invites/preview"
```

## `POST /v2/org/invites/accept` · Org invites accept

- **Kabu apps only:** a signed-in human's token. Integrations use API keys.
- **Signed-in humans:** `self`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `Idempotency-Key` | header | string, at most 255 characters | no | Retry-safe key. For messages, sessions and responses it binds to the created object for its life; elsewhere for 24 h. |

**Request body**: [OrgInviteAccept](#schema-OrgInviteAccept).

| Status | Means | Body |
|---|---|---|
| `200` | OK | [Membership](#schema-Membership) |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl -X POST "https://usekabu.com/api/v2/org/invites/accept" \
  -H "Authorization: Bearer $KABU_USER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"token":"…"}'
```

## `POST /v2/org/members/me/leave` · Members leave

Self-leave only: target comes from the user token, never a body. Admins/members may leave; an owner receives 409 owner_must_transfer_first and must transfer before leaving. Account deletion remains unblocked and uses succession instead.

- **Kabu apps only:** a signed-in human's token. Integrations use API keys.
- **Signed-in humans:** `member`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `Idempotency-Key` | header | string, at most 255 characters | no | Retry-safe key. For messages, sessions and responses it binds to the created object for its life; elsewhere for 24 h. |
| `Kabu-Org` | header | string | no | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |

| Status | Means | Body |
|---|---|---|
| `204` | Done |  |
| `4XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |
| `5XX` | Error | [Problem](/docs/api/discovery#schema-Problem) |

```sh
curl -X POST "https://usekabu.com/api/v2/org/members/me/leave" \
  -H "Authorization: Bearer $KABU_USER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"
```

## Schemas

### Org

| Property | Type | Required | Description |
|---|---|---|---|
| `object` | `"org"` | yes |  |
| `id` | string | yes |  |
| `name` | string | yes |  |
| `api_version` | string | yes |  |
| `settings` | [SettingsView](/docs/api/events#schema-SettingsView) | yes | Layered: org → project → agent → recipient. Unset fields inherit. |
| `features` | object | yes | Admin toggles; can disable a purchased feature, never grant one. |
| `entitlements` | [Entitlements](#schema-Entitlements) | yes | Read-only. What the org has bought. |
| `kind` | string | no |  |
| `role` | string | no |  |
| `brand` | [Brand](#schema-Brand) | no |  |

### Entitlements

Read-only. What the org has bought.

| Property | Type | Required | Description |
|---|---|---|---|
| `plan` | string | yes |  |
| `features` | array of string | yes |  |
| `limits` | object | yes |  |

### Brand

| Property | Type | Required | Description |
|---|---|---|---|
| `object` | `"brand"` | yes |  |
| `logo_media_id` | string or null | yes |  |
| `logo_url` | string (uri) or null | yes |  |
| `accent` | [Accent](/docs/api/messages#schema-Accent) or null | yes |  |
| `updated_at` | [Timestamp](/docs/api/messages#schema-Timestamp) or null | yes |  |

### OrgUpdate

| Property | Type | Required | Description |
|---|---|---|---|
| `name` | string, at most 80 characters | no |  |
| `api_version` | string, matching `^\d{4}-\d{2}-\d{2}$` | no |  |
| `settings` | [Settings](/docs/api/projects#schema-Settings) | no | Layered: org → project → agent → recipient. Unset fields inherit. |
| `features` | object | no |  |
| `brand` | [BrandUpdate](#schema-BrandUpdate) | no |  |

Unknown properties are refused.

### BrandUpdate

| Property | Type | Required | Description |
|---|---|---|---|
| `logo_media_id` | string or null | no |  |
| `accent` | [AccentKnown](/docs/api/messages#schema-AccentKnown) or null | no |  |

Unknown properties are refused.

### OrgCreate

| Property | Type | Required | Description |
|---|---|---|---|
| `name` | string, 1 to 80 characters | yes |  |

Unknown properties are refused.

### OrgMemberList

| Property | Type | Required | Description |
|---|---|---|---|
| `object` | `"list"` | yes |  |
| `data` | array of [OrgMember](#schema-OrgMember) | yes |  |
| `has_more` | boolean | yes |  |
| `next_cursor` | string or null | yes |  |

### OrgMember

| Property | Type | Required | Description |
|---|---|---|---|
| `object` | `"org_member"` | yes |  |
| `user_id` | string | yes |  |
| `name` | string or null | yes |  |
| `role` | string | yes |  |
| `joined_at` | [Timestamp](/docs/api/messages#schema-Timestamp) | yes |  |

### OrgMemberUpdate

Admins cannot alter the owner; ownership changes only through org.transfer.

| Property | Type | Required | Description |
|---|---|---|---|
| `role` | string, one of `"admin"`, `"member"` | yes |  |

Unknown properties are refused.

### OrgTransfer

Transfer a team org to an active member atomically with membership and billing ownership.

| Property | Type | Required | Description |
|---|---|---|---|
| `user_id` | string | yes |  |

Unknown properties are refused.

### OrgInviteList

| Property | Type | Required | Description |
|---|---|---|---|
| `object` | `"list"` | yes |  |
| `data` | array of [OrgInvite](#schema-OrgInvite) | yes |  |
| `has_more` | boolean | yes |  |
| `next_cursor` | string or null | yes |  |

### OrgInvite

| Property | Type | Required | Description |
|---|---|---|---|
| `object` | `"org_invite"` | yes |  |
| `id` | string | yes |  |
| `org` | string | yes |  |
| `org_name` | string | yes |  |
| `role` | string | yes |  |
| `email` | string or null | yes |  |
| `status` | string | yes |  |
| `expires_at` | [Timestamp](/docs/api/messages#schema-Timestamp) | yes |  |

### OrgInviteCreate

| Property | Type | Required | Description |
|---|---|---|---|
| `email` | string (email) | no |  |
| `role` | string, one of `"admin"`, `"member"` | yes |  |
| `expires_in` | integer, from 60 to 604800 | no |  |

Unknown properties are refused.

### OrgInviteWithToken

Type: [OrgInvite](#schema-OrgInvite) and object.

### OrgInviteAccept

| Property | Type | Required | Description |
|---|---|---|---|
| `token` | string, 1 to 256 characters | yes |  |

Unknown properties are refused.

### Membership

| Property | Type | Required | Description |
|---|---|---|---|
| `org` | string | yes |  |
| `name` | string | yes |  |
| `kind` | string | yes |  |
| `role` | string | yes |  |
| `pending_asks` | integer | yes |  |
