Projects
Repos, services or environments; the unit of key binding and retention.
Generated from the contract, version 2.0.0-draft.2 (OpenAPI). Base URL https://usekabu.com/api. Errors are problem details, each code with its own page.
List projects
GET/v2/projects- Auth: an API key, or a signed-in human’s token (the Kabu apps).
- Scopes:
messages:read. - Signed-in humans:
member.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
limit |
query | integer, from 1 to 100 | Optional | |
after |
query | string | Optional | Opaque cursor from next_cursor. |
include_counts |
query | boolean | Optional | Give each project its message_count, the messages projects.delete would remove. Off by default: it costs a count. |
Kabu-Org |
header | string | Optional | 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 | ProjectList |
4XX |
Error | Problem |
5XX |
Error | Problem |
curl "https://usekabu.com/api/v2/projects" \
-H "Authorization: Bearer $KABU_API_KEY"Create a project
POST/v2/projects- Auth: an API key, or a signed-in human’s token (the Kabu apps).
- Scopes:
projects:write. - Signed-in humans:
admin.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key |
header | string, at most 255 characters | Optional | 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 | Optional | 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: ProjectWrite.
curl -X POST "https://usekabu.com/api/v2/projects" \
-H "Authorization: Bearer $KABU_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{}'Get a project
GET/v2/projects/{project}- Auth: an API key, or a signed-in human’s token (the Kabu apps).
- Scopes:
messages:read. - Signed-in humans:
member.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project |
path | string | Required | An id or slug. |
Kabu-Org |
header | string | Optional | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |
curl "https://usekabu.com/api/v2/projects/$PROJECT" \
-H "Authorization: Bearer $KABU_API_KEY"Update a project
PATCH/v2/projects/{project}- Auth: an API key, or a signed-in human’s token (the Kabu apps).
- Scopes:
projects:write. - Signed-in humans:
admin.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project |
path | string | Required | An id or slug. |
Kabu-Org |
header | string | Optional | 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: ProjectWrite.
curl -X PATCH "https://usekabu.com/api/v2/projects/$PROJECT" \
-H "Authorization: Bearer $KABU_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'Delete a project and everything in it
DELETE/v2/projects/{project}Deletes the project and all that is only its: its messages (with their content, answers and delivery records), sessions, aliases, agents, webhook endpoints and steering claims, the media stored in it, and any project merged into it. It cannot be undone. Its pending asks are cancelled first, as any cancel, so the org’s open asks, their sessions and each person’s backlog are freed. Its stored bytes are deleted shortly after, retried until they are gone, and its Live Activities are ended. An attachment uploaded with an unbound key is stored in default, where any message may share it, so it stays until default‘s retention purges it. Nothing remembers the slug: the next message that names it creates a fresh project, as any first use does, and a message naming one of its sessions is accepted without the session. Other projects’ deliveries are untouched. Only the project’s prj_… id or its exact slug is accepted; an alias or a normalised match answers 404, so a merged slug never deletes its merge target. While an API key that is neither revoked nor expired is bound to the project or one of its agents, it answers 409 project_in_use naming the keys: revoke them first. The project default resolves to, which takes every message that names no project, cannot be deleted (400 invalid_request). A project that no longer exists answers 404, so repeating a delete is harmless.
- Auth: an API key, or a signed-in human’s token (the Kabu apps).
- Scopes:
projects:write. - Signed-in humans:
admin.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project |
path | string | Required | An id or slug. |
Kabu-Org |
header | string | Optional | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |
curl -X DELETE "https://usekabu.com/api/v2/projects/$PROJECT" \
-H "Authorization: Bearer $KABU_API_KEY"Schemas
ProjectList
| Property | Type | Required | Description |
|---|---|---|---|
object |
"list" |
Required | |
data |
array of Project | Required | |
has_more |
boolean | Required | |
next_cursor |
string or null | Required |
Project
| Property | Type | Required | Description |
|---|---|---|---|
object |
"project" |
Required | |
id |
string | Required | |
slug |
string | Required | |
name |
string or null | Required | |
normalized_key |
string | Optional | |
aliases |
array of string | Optional | |
color |
Accent | Optional | Open enum. Known values are AccentKnown; accept and ignore unknown values. |
icon |
string | Optional | A med_… avatar media id (or SF Symbol fallback when not med_…). |
symbol |
string | Optional | An avatar glyph: sf:NAME, emoji:CHAR or art:ID (a bare SF Symbol name is also read). |
retention_days |
integer | Required | |
settings |
SettingsView | Required | Layered: org → project → agent → recipient. Unset fields inherit. |
metadata |
Metadata | Required | Your own key/value pairs (≤ 50 keys, values ≤ 500 chars), returned verbatim on every object and event. |
created_at |
Timestamp | Required | |
message_count |
integer, ≥ 0 | Optional | How many messages the project holds, all of which projects.delete removes. Only with projects.list include_counts=true. |
ProjectWrite
| Property | Type | Required | Description |
|---|---|---|---|
slug |
string, matching ^[a-z0-9][a-z0-9._-]{0,63}$ |
Optional | |
name |
string, at most 80 characters | Optional | |
color |
AccentKnown | Optional | A palette token (rendered with each platform’s accessible colours), never a raw colour. |
icon |
string, at most 64 characters | Optional | A med_… avatar media id (or SF Symbol fallback when not med_…). |
symbol |
string, at most 64 characters | Optional | An avatar glyph: sf:NAME, emoji:CHAR or art:ID (a bare SF Symbol name is also read). |
merge_into |
string, 1 to 64 characters | Optional | Deprecated; will be removed in a later build. Delete the project instead (projects.delete). Target project id, slug or normalised key to merge this project into as an alias: its messages move to the target, and every later message that names this project’s slug lands in the target too. It cannot be undone. Deprecated. |
retention_days |
integer, from 1 to 365 | Optional | |
settings |
Settings | Optional | Layered: org → project → agent → recipient. Unset fields inherit. |
metadata |
Metadata | Optional | Your own key/value pairs (≤ 50 keys, values ≤ 500 chars), returned verbatim on every object and event. |
Unknown properties are refused.
Settings
Layered: org → project → agent → recipient. Unset fields inherit.
| Property | Type | Required | Description |
|---|---|---|---|
appearance |
Appearance | Optional | Cosmetics only. Resolved org → project → agent → recipient, then this override; recipient restrictions always win. |
delivery |
DeliverySettings | Optional | |
extensions |
Extensions | Optional | Reverse-domain namespaced extension data (e.g. com.example.ticket), ≤ 8 KiB total. Cannot change core semantics. |
Unknown properties are refused.
DeliverySettings
| Property | Type | Required | Description |
|---|---|---|---|
quiet_hours |
object | Optional | |
quiet_hours.start |
string, matching ^[0-2][0-9]:[0-5][0-9]$ |
Optional | |
quiet_hours.end |
string, matching ^[0-2][0-9]:[0-5][0-9]$ |
Optional | |
quiet_hours.time_zone |
string | Optional | |
digest_notify_after |
integer, from 1 to 200 | Optional | Notifies per 10 min before FYIs are digested. |
remind_every |
integer, from 0 to 86400 | Optional | Seconds between reminders of a pending ask: 0 turns them off, otherwise 300 (5 min) to 86400 (24 h). Unset inherits: the recipient’s, then the org’s, then 600 (10 min). An ask is reminded at most 3 times and never within 2 min of its expiry. One whose life (expiry minus its first push) is under this plus 2 min is reminded once, at the midpoint of its life, if it lives at least 3 min (a 300 s ask at 150 s). Set by recipients and orgs, not agents. |
Unknown properties are refused.