Koo Docs
View as Markdown

Notifications

Your notification feed, newest first

GET/notifications
Parameters
unread"true" | "false"query

Only unread when `true`.

cursorstringquery

Opaque cursor (page.nextCursor).

limitnumberquery

Page size (1–100, default 20).

Returns
200 · NotificationsPageDto
dataobject[]read-only
pageobjectread-only
cURL
GET /notifications
bash
curl https://api.koo.io/notifications \  -H "Authorization: Bearer kc_your_api_token"
Response
json
{  "data": [    {      "id": "acct_01example0000000000000000x",      "userId": "usr_01example0000000000000000x",      "accountId": "acct_01example0000000000000000x",      "kind": "example",      "title": "example",      "body": "example",      "metadata": {        "key": "example"      },      "readAt": "2026-01-01T00:00:00.000Z",      "createdAt": "2026-01-01T00:00:00.000Z"    }  ],  "page": {    "nextCursor": "example",    "hasMore": true  }}

Your unread notification count

GET/notifications/unread-count
Returns
200 · UnreadCountDto
countintegerread-only

Number of unread notifications.

cURL
GET /notifications/unread-count
bash
curl https://api.koo.io/notifications/unread-count \  -H "Authorization: Bearer kc_your_api_token"
Response
json
{  "count": 0}

Mark one notification read

POST/notifications/{id}/read
Parameters
idstringpathrequired
Returns
200 · NotificationDto404 · ErrorEnvelopeDto
idstringread-only
userIdstringread-only
accountIdstringread-only
kindstringread-only
titlestringread-only
bodystringread-only
metadataRecord<string, string>read-only
readAtstring <date-time>read-only
createdAtstring <date-time>read-only
cURL
POST /notifications/{id}/read
bash
curl https://api.koo.io/notifications/:id/read \  -X POST \  -H "Authorization: Bearer kc_your_api_token"
Response
json
{  "id": "ntf_01example0000000000000000x",  "userId": "usr_01example0000000000000000x",  "accountId": "acct_01example0000000000000000x",  "kind": "example",  "title": "example",  "body": "example",  "metadata": {    "key": "example"  },  "readAt": "2026-01-01T00:00:00.000Z",  "createdAt": "2026-01-01T00:00:00.000Z"}

Mark every notification read

POST/notifications/read-all
Returns
200 · UnreadCountDto
countintegerread-only

Number of unread notifications.

cURL
POST /notifications/read-all
bash
curl https://api.koo.io/notifications/read-all \  -X POST \  -H "Authorization: Bearer kc_your_api_token"
Response
json
{  "count": 0}

Your delivery preference for every notification kind (resolved)

GET/me/notification-prefs
Returns
200 · NotificationPrefViewDto[]
cURL
GET /me/notification-prefs
bash
curl https://api.koo.io/me/notification-prefs \  -H "Authorization: Bearer kc_your_api_token"
Response
json
[  {    "kind": "example",    "label": "example",    "category": "deletion",    "channel": "in_app",    "frequency": "immediate",    "forceEmail": true,    "overridden": true  }]

Set your delivery preference for one kind

PUT/me/notification-prefs
Request body
kindstringrequired
channel"in_app" | "email" | "both" | "off"required
frequency"immediate" | "daily" | "weekly"required
Returns
200 · NotificationPrefViewDto422 · ErrorEnvelopeDto
kindstringread-only

Catalogue kind key, e.g. `deploy.ready`.

labelstringread-only

Human label from the catalogue.

category"deletion" | "billing" | "member" | "deploy" | "social"read-only
channel"in_app" | "email" | "both" | "off"read-only
frequency"immediate" | "daily" | "weekly"read-only
forceEmailbooleanread-only

Forced kinds (security/billing/deletion) are ALWAYS emailed regardless of the channel pref — the UI renders them locked.

overriddenbooleanread-only

Whether the user stored an override for this kind.

cURL
PUT /me/notification-prefs
bash
curl https://api.koo.io/me/notification-prefs \  -X PUT \  -H "Authorization: Bearer kc_your_api_token" \  -H "Content-Type: application/json" \  -d '{      "kind": "example",      "channel": "in_app",      "frequency": "immediate"    }'
Response
json
{  "kind": "example",  "label": "example",  "category": "deletion",  "channel": "in_app",  "frequency": "immediate",  "forceEmail": true,  "overridden": true}