Skip to main content

People API

People is the profile-discovery and mutual-interest surface. It is separate from friendships: a mutual like creates a match and a direct chat, but does not create a friendship.

All endpoints require Authorization: Bearer <supabase-access-token>.

Endpoints​

MethodPathDescription
GET/peopleDiscover completed, visible profiles
PATCH/people/locationSet location sharing mode and position
GET/people/searchSearch by partial username
GET/people/:profileIdView a public profile
PUT/people/:profileId/interactionSave a like or dislike
DELETE/people/:profileId/interactionRemove the current interaction
GET/people/interactionsList active interactions
GET/people/incoming-likesList incoming likes
GET/people/matchesList mutual likes and their chats
POST/people/:userId/blockBlock a user
DELETE/people/:userId/blockUnblock a user
POST/people/:userId/reportReport a user

Discovery feed​

GET /people?sex=female&ageMin=21&ageMax=35&language=en,ru&limit=12
Authorization: Bearer <token>

The response is { data, nextCursor }. The default page size is 12 and the maximum is 50. Multi-value filters accept a comma-separated value or repeated query parameters. Unknown enum values are rejected.

QueryDescription
ageMin, ageMaxAge, 19..120
heightMin, heightMaxHeight in cm, 55..272
sexall, male, female
datingPurpose, education, language, religionOne or more values
alcohol, smoking, bodyType, familyPlan, wealth, zodiacOne or more values
distanceMin, distanceMaxDistance in km
isMapSelectionOnly profiles visible on the map
cursor, limitKeyset pagination

The feed excludes the caller, incomplete or hidden profiles, and blocked users. Public locations are coarsened to approximately a 500 m grid. When isMapSelection=true, a fresh live point may be returned instead; live points older than five minutes are treated as stale.

Location sharing​

PATCH /people/location
{ "locationSharingMode": "live", "latitude": 43.238, "longitude": 76.945, "city": "Almaty" }

locationSharingMode is disabled, static, or live. Coordinates are required for the latter two modes. The response contains the mode and locationUpdatedAt. Map visibility is controlled separately by isVisibleOnMap on the profile.

Search and profile detail​

GET /people/search?q=yakov&limit=20 performs a case-insensitive partial username search. The @ is optional. Results omit the caller, existing friends, and blocked users, and include friendshipStatus (none, pending_outgoing, pending_incoming, or rejected).

GET /people/:profileId returns the public profile shape, including photos, education, languages, and privacy-filtered dating purpose/zodiac. The path parameter is a profile ID, not a user ID.

Likes, dislikes, and matches​

PUT /people/:profileId/interaction
{ "type": "like" }

Interactions expire after seven days. like and dislike can be removed with DELETE. A mutual like creates one canonical match and ensures one direct chat; the response includes isMatch, matchId, and chatId when relevant. Use /people/incoming-likes and /people/matches with cursor and limit (default 20, maximum 100) for the corresponding paginated lists.

Reports​

The people-specific report endpoint accepts fake_profile, unacceptable_content, toxic_behavior, incorrect_age, behavior_outside_social_network, or other, plus an optional description of 250 characters. General user/event/chat reports are documented in Reports.