Super People Docs
API Reference

Profiles & Directory

Your own profile and avatar, the people directory with its filters, the org chart, skills and the contributor leaderboard.

Your own profile and avatar, the people directory with its filters, the org chart, skills and the contributor leaderboard.

Generated from the OpenAPI spec by npm run docs:api -w api. Do not edit this page — change the decorators in apps/api/src/ and regenerate.

Conventions

  • Auth — a session on every route: the cookie on web, the bearer token on mobile. See Authentication.
  • Errors — every non-2xx response has the body described in Errors.
  • Types — a ? after a field name means it is optional; | null means it is present but may be null.

Endpoints

GET /api/v1/users/me/profile — The signed-in person’s profile

Call this straight after sign-in: it is the cheapest confirmation that the stored token is still good, and it carries role, which decides whether the admin screens and the announcement composer are shown at all.

Returns 200 → ProfileResponse

ErrorWhen
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.

PATCH /api/v1/users/me/profile — Edit your own profile

A partial update — send only the fields that changed. joinedOn is dropped here rather than rejected: it is an HR record, writable only by a super admin through PATCH /people/{userId}/profile. Sending projects replaces the whole timeline, so send the full list including the entries that did not change.

Body — UpdateProfileDto

Returns 200 → ProfileResponse

ErrorWhen
400The request was rejected. message is an array of field errors when validation failed.
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.

POST /api/v1/users/me/avatar — Replace your avatar

JPG, PNG or WebP, up to 2MB. Returns the whole profile with image already updated, so there is nothing to re-fetch afterwards. Upload the photo at any size: it is cropped square and re-encoded to a 256px WebP before it is stored, so do not resize it yourself.

Body — multipart/form-data, one part named file.

Returns 201 → ProfileResponse

ErrorWhen
400The request was rejected. message is an array of field errors when validation failed.
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.
413The file is larger than 2MB.

PATCH /api/v1/people/{userId}/profile — Edit somebody else’s profile

Super admins only. Same fields as the self-serve route, plus joinedOn.

Path parameterTypeNotes
userIdstring

Body — UpdateProfileDto

Returns 200 → ProfileResponse

ErrorWhen
400The request was rejected. message is an array of field errors when validation failed.
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.
404No such person.

POST /api/v1/people/{userId}/avatar — Replace somebody else’s avatar

Super admins only. Same limits as your own.

Path parameterTypeNotes
userIdstring

Body — multipart/form-data, one part named file.

Returns 201 → ProfileResponse

ErrorWhen
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.
413The file is larger than 2MB.

GET /api/v1/org-chart — The reporting tree, flat

Everybody in one array. Build the hierarchy on the client by matching managerId to id; a node with managerId: null is a root.

Returns 200 → OrgNodeResponse[]

ErrorWhen
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.

GET /api/v1/people/skills — Every skill anyone has listed

For the skill picker’s suggestions. Plain strings.

Returns 200 → string[]

ErrorWhen
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.

GET /api/v1/people/facets — The directory’s filter options

Built from the people actually listed, so a filter can never offer a choice that returns nobody. Fetch once and hold it for the session.

Returns 200 → DirectoryFacetsResponse

ErrorWhen
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.

GET /api/v1/people/contributors — Top contributors

Super-admin picks first (isFeatured), then the most active people to fill the rest of the list.

QueryTypeRequiredNotes
limitnumbernoRows per page. Defaults to 20, capped at 50.

Returns 200 → ContributorResponse[]

ErrorWhen
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.

GET /api/v1/people/leaderboard — Engagement leaderboard

People ranked by the reactions, comments and shares their posts received from other people in the period — dislikes and self-engagement excluded. Only people with a score above zero are listed. period defaults to all.

QueryTypeRequiredNotes
periodweek | month | allno
limitnumbernoRows per page. Defaults to 20, capped at 50.

Returns 200 → LeaderboardEntryResponse[]

ErrorWhen
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.

GET /api/v1/people — The people directory

Cursor-paged. Every filter is optional and they combine with AND. Take the skill, role and location values from GET /people/facets rather than inventing them.

QueryTypeRequiredNotes
qstringnoFree text over name, title and bio.
skillstringno
rolestringnoA job title, not an access level.
locationstringno
teamstringnoA team id from GET /teams.
statusactive | pendingno
sortname | recent | postsnoDefaults to name.
cursorstringnoThe nextCursor from the previous page. Omit for the first.
limitnumbernoRows per page. Defaults to 20, capped at 50.

Returns 200 → Page<DirectoryEntryResponse> — see Paging

ErrorWhen
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.

GET /api/v1/people/{userId} — One person’s full profile

Path parameterTypeNotes
userIdstring

Returns 200 → ProfileResponse

ErrorWhen
401No valid session. Clear the stored token and sign in again.
403Signed in, but not allowed to do this.
404No such person.

Data models

ProfileResponse

FieldTypeNotes
idstring
namestring
emailstring
rolemember | super_admin
imagestring | nullA path under /api/v1/files/avatars/... — resolve against the API origin.
titlestring
locationstring
biostring
currentWorkstringWhat they are working on right now.
department"" | engineering | product | design | hr | business_development | digital_marketing | finance | operations | support | legal'' when they have not picked a team yet.
teamProfileTeamResponse | null
skillsstring[]
learningInterestsstring[]
projectsProjectResponse[]
instagramstring
linkedinstring
githubstring
xstringX, formerly Twitter.
youtubestring
portfoliostringA personal site.
hobbiesstring[]
interestsstring[]
favoriteMusicstring
favoriteMoviestring
favoriteFoodstring
funFactstring
dreamDestinationstring
superpowerstring
drinkstringWhatever they actually drink — not a fixed set.
joinedAtstring ISO 8601When the login was provisioned — not when the person joined.
joinedOnstring | nullEmployment start date, YYYY-MM-DD, set by a super admin. Prefer it over joinedAt wherever a joining date is shown; null until one is set.
dateOfBirthstring | nullDate of birth, YYYY-MM-DD. Returned only to the person themselves and to super admins — null for everyone else, and until it is set.
statusactive | pending | deactivated
presenceactive | away | offlineWhether they are here right now, computed from heartbeats — unrelated to status, which is about the account. Everyone never seen is offline.
lastSeenAtstring ISO 8601 | nullWhen a client of theirs was last open. Null if never.
postCountnumber
managerManagerResponse | null
reportCountnumberHow many people report to them.
isCompletebooleanWhether the profile has enough filled in to stop nagging about it.

ProfileTeamResponse

FieldTypeNotes
idstring
namestring
colorblue | emerald | violet | amber | rose | cyan | orange | slateA palette token, not a CSS colour — map it to your own styles.

ProjectResponse

FieldTypeNotes
idstring
namestring
descriptionstringEmpty string when unset, never null.
contributionstringSuperseded by contributions; still filled for older rows.
rolestring
startedAtstring | null
endedAtstring | nullnull while the work is still running — show it as "Present".
statusin_progress | completed | on_hold
tagsstring[]
contributionsstring[]The "Key Contributions" bullets.
linkstringEmpty string when unset, never null.

ManagerResponse

FieldTypeNotes
idstring
namestring
imagestring | null

UpdateProfileDto

FieldTypeNotes
skills?string[]At most 20, 40 characters each. Replaces the whole list.
learningInterests?string[]At most 10. Replaces the whole list. · 40 chars each
projects?ProjectDto[]The whole work timeline, at most 10 entries. Sending this REPLACES every entry, so include the ones that did not change.
hobbies?string[]At most 12. Replaces the whole list. · 40 chars each
interests?string[]At most 12. Replaces the whole list. · 40 chars each
name?string≤ 120 chars
title?string≤ 120 chars
location?string≤ 120 chars
department?"" | engineering | product | design | hr | business_development | digital_marketing | finance | operations | support | legal'' clears it back to "not set"; anything else must be a known team.
teamId?string | nullnull unassigns them; omitting the key leaves the team untouched.
bio?string≤ 500 chars
currentWork?string≤ 1000 chars
managerId?string | nullnull clears the reporting line; omitting the key leaves it untouched.
joinedOn?string | nullEmployment start date, YYYY-MM-DD. Super admins only — the self-serve route strips it (see ProfilesController), because it is an HR record rather than something you state about yourself. null or '' clears it; omitting the key leaves it untouched.
dateOfBirth?string | nullDate of birth, YYYY-MM-DD. Editable by the person themselves; shown to nobody else. null or '' clears it; omitting the key leaves it alone.
instagram?stringInstagram — a handle or a full URL. '' clears it. · ≤ 200 chars
linkedin?stringLinkedIn — a handle or a full URL. '' clears it. · ≤ 200 chars
github?stringGitHub — a handle or a full URL. '' clears it. · ≤ 200 chars
x?stringX — a handle or a full URL. '' clears it. · ≤ 200 chars
youtube?stringYouTube — a handle or a full URL. '' clears it. · ≤ 200 chars
portfolio?stringPortfolio — a handle or a full URL. '' clears it. · ≤ 200 chars
favoriteMusic?stringFavourite music. · ≤ 200 chars
favoriteMovie?stringFavourite movie. · ≤ 200 chars
favoriteFood?stringFavourite food. · ≤ 200 chars
funFact?stringFun fact. · ≤ 200 chars
dreamDestination?stringDream destination. · ≤ 200 chars
superpower?stringSuperpower. · ≤ 200 chars
drink?stringCoffee or tea. · ≤ 200 chars

ProjectDto

FieldTypeNotes
link?stringAn http(s) URL. Empty string clears it. · ≤ 500 chars
tags?string[]Tech stack, channels, workstreams — whatever the department labels with. · ≤ 10 items, 40 chars each
contributions?string[]The "Key Contributions" bullets. At most 8. · 200 chars each
namestring≤ 120 chars
description?string≤ 500 chars
contribution?string≤ 500 chars
role?stringWhat the person did on it — "Full-stack Developer", "Recruitment Lead". · ≤ 120 chars
startedAt?string | nullMonth precision in the UI, a full date on the wire. null on endedAt is what the timeline shows as "Present".
endedAt?string | null
status?in_progress | completed | on_hold

OrgNodeResponse

FieldTypeNotes
idstring
namestring
imagestring | null
titlestring
currentWorkstring
statusactive | pending | deactivated
managerIdstring | nullnull for the root of the tree.

DirectoryFacetsResponse

FieldTypeNotes
skillsstring[]
titlesstring[]
locationsstring[]

ContributorResponse

FieldTypeNotes
idstring
namestring
imagestring | null
titlestring
notestringWhy a super admin pinned them; empty for the automatic tail.
isFeaturedboolean
postCountnumber

LeaderboardEntryResponse

FieldTypeNotes
ranknumberShared by people on the same score.
idstring
namestring
imagestring | null
titlestring
postCountnumberPosts written in the period. Not scored.
reactionCountnumberReactions from other people, dislikes excluded.
commentCountnumberComments and replies from other people.
shareCountnumberShares by other people.
scorenumberReactions, comments and shares received, weighted.

DirectoryEntryResponse

FieldTypeNotes
idstring
namestring
imagestring | null
titlestring
locationstring
biostring
currentWorkstring
skillsstring[]
teamProfileTeamResponse | null
joinedAtstring ISO 8601
statusactive | pending | deactivated
presenceactive | away | offlineWhether they are here right now, computed from heartbeats — unrelated to status, which is about the account. Everyone never seen is offline.
lastSeenAtstring ISO 8601 | nullWhen a client of theirs was last open. Null if never.
postCountnumber

On this page