Skip to content

The cards the signed-in person can open

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

Every client card the account holds an active grant on, oldest first — the portal’s card switcher. A card whose team’s plan ended or whose athlete is now a minor is listed too: opening it answers 403 access_ended with the reason. Avatars and logos are signed for two hours. 404 while client access is switched off; a partner API key gets 403; 429 past the account’s rate (client_portal, 120/min).

Media typeapplication/json

GET /api/portal/cards/.

object
results
required
Array<object>

One card the person can open in the portal (PortalCard).

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

The athlete’s photo, signed for two hours; empty when there is none.

string
team_name
required
string
team_logo_url
required

The team’s own logo for the portal header (S5), signed for two hours; null when the team set none — the deployment’s brand shows instead.

string
nullable
relation
required
  • athlete - Athlete
  • guardian - Parent or guardian
string
Allowed values: athlete guardian
level
required
  • view - View
  • contribute - Contribute
string
Allowed values: view contribute
unread_count
required

The person’s unread messages on the card’s conversation.

integer
active
required

Whether the card opens now. False: opening it answers the inactive_reason page. /api/portal/cards/ lists the active cards first. A revoked grant is not listed at all.

boolean
inactive_reason
required
One of:
string
Allowed values: team_plan minor consent_required

Examples

ExampleOneCard

One card

{
"results": [
{
"client_id": "a1f1c0a2-0000-4000-8000-0000000000aa",
"client_name": "Sofia Lebedeva",
"avatar_url": "",
"team_name": "North Track Academy",
"team_logo_url": null,
"relation": "guardian",
"level": "view",
"unread_count": 0,
"active": true,
"inactive_reason": 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

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

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
}