Skip to content

The team's conversations with its clients

GET
/api/inbox/
curl --request GET \
--url http://localhost:8000/api/inbox/ \
--header 'Authorization: Bearer <token>'

Every card of the active team with a message, pinned first, then the newest; unread rows are not floated. ?archived=true lists the archive instead. A page at a time: limit (default 50, at most 200) and offset; next_offset is the next page’s. The counts and settings are the signed-in coach’s own.

A coach of the active team. 404 while client access is switched off; a partner API key and a client’s own account get 403; 429 past the account’s rate (chat_read, 240/min).

archived
boolean

List the archive.

limit
integer

Page size, 1-200; default 50.

offset
integer

Rows to skip; default 0.

Media typeapplication/json

GET /api/inbox/ (InboxList).

object
results
required
Array<object>

One client’s conversation in the coach inbox (InboxRow).

object
client_id
required
string format: uuid
client_name
required
string
avatar_url
required
string
last_message
required
object
text
required

A one-line preview of the words.

string
author_name
required
string
author_role
required
  • coach - Coach
  • athlete - Athlete
  • guardian - Parent or guardian
string
Allowed values: coach athlete guardian
mine
required
boolean
created_at
required
string format: date-time
deleted
required
boolean
event
required
One of:
  • result_shared - Result shared
  • client_upload - Client sent a clip
  • upload_refused - Client’s clip refused: team out of analyses
  • document_shared - Document shared
string
Allowed values: result_shared client_upload upload_refused document_shared
unread_count
required
integer
settings
required

ThreadSettings — the signed-in person’s own, for this conversation.

object
muted
required
boolean
pinned
required
boolean
archived
required
boolean
archived_count
required
integer
count
required

Conversations in this list (inbox or archive), every page.

integer
next_offset
required

?offset= of the next page; null on the last one.

integer
nullable

Examples

ExampleInbox
{
"results": [
{
"client_id": "a1f1c0a2-0000-4000-8000-0000000000aa",
"client_name": "Sofia Lebedeva",
"avatar_url": "",
"last_message": {
"text": "Thank you, she enjoyed it!",
"author_name": "Olga Lebedeva",
"author_role": "guardian",
"mine": false,
"created_at": "2026-11-02T11:02:00Z",
"deleted": false,
"event": null
},
"unread_count": 1,
"settings": {
"muted": false,
"pinned": false,
"archived": false
}
}
],
"archived_count": 0,
"count": 1,
"next_offset": null
}
Media typeapplication/json
object
detail
required

Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).

string

Example generated

{
"detail": "example"
}
Media typeapplication/json
object
detail
required

Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).

string

Examples

Example403—AClient'sOwnAccount

403 — a client's own account

{
"detail": "client_account"
}
Media typeapplication/json
object
detail
required

Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).

string

Example generated

{
"detail": "example"
}
Media typeapplication/json
object
detail
required

429 — throttled: this account’s (or address’s) rate for the route is used up; try again after wait seconds, which Retry-After repeats. A route with a limit of its own answers its own code instead, documented there.

string
wait

With throttled: whole seconds until the next request can pass.

integer
nullable

Example generated

{
"detail": "example",
"wait": 1
}