Friends API
This module is not yet shipped. The shape below describes the intended endpoints once the friendship feature is implemented on the new Hono + Supabase + Drizzle stack. Expect minor adjustments when it lands.
Manage friend requests and friendships. Friendships are bidirectional — once accepted, both parties can see each other for purposes of event co-authoring and like-group formation.
See also: Friendship algorithm,
friendships table.
All endpoints require Authorization: Bearer <supabase-access-token>.
The acting user is resolved from the JWT (no userId query param).
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /friends | List friendships of the current user |
| POST | /friends/requests | Send a friend request |
| POST | /friends/requests/:id/accept | Accept a request |
| POST | /friends/requests/:id/reject | Reject a request |
| POST | /friends/:userId/block | Block another user |
| DELETE | /friends/:userId | Unfriend |
List friends
GET /friends?status=accepted
Authorization: Bearer <token>
| Query | Type | Description |
|---|---|---|
status | enum | pending | accepted | rejected | blocked |
cursor | string | Pagination cursor |
limit | number | Page size (default 20) |
{
"data": [
{
"id": "uuid",
"requesterId": "uuid",
"addresseeId": "uuid",
"status": "accepted",
"createdAt": "2026-04-01T00:00:00Z"
}
],
"nextCursor": null
}
Send friend request
POST /friends/requests
Authorization: Bearer <token>
Content-Type: application/json
{ "addresseeId": "uuid" }
| Status | Reason |
|---|---|
201 | Created |
400 | Cannot request yourself |
409 | Already friends, already pending, or you are blocked |
Accept / reject
POST /friends/requests/:id/accept
POST /friends/requests/:id/reject
Only the addressee of a pending row may call these. Returns the
updated friendship.
Block
POST /friends/:userId/block
Blocking is a unilateral action: it sets the row to blocked regardless
of who initiated it, removes any existing pending state, and prevents
future requests from the blocked user.
Unfriend
DELETE /friends/:userId
Removes the row entirely. Either side can re-request later.
Limits
| Limit | Value |
|---|---|
| Pending outgoing requests per user | 50 |
| Friends per user | No limit |
Implementation sketch
The Hono router will mirror the shipped pattern in
src/feats/profiles/:
src/feats/friends/
├── friends.router.ts # POST/GET/DELETE handlers, auth + zod middleware
├── friends.service.ts # Business rules: bidirectional check, block, etc.
├── friends.schemas.ts # Zod request/response schemas
└── friends.constants.ts # Status enum, limits
Cross-user reads run as service_role (bypass RLS) and are scoped in
code by requesterId = auth.uid() OR addresseeId = auth.uid().