Block a User
Add a target user to the caller's block list. Self-block is rejected; double-block is a 409. Audit-logged for moderation review.
POST /api/v1/users/block/:userId โ ๐ Bearer ยท Rate limit: 10 req / hour
Adds the target user to the caller's BlockList. Self-block is rejected โ ownerId === blockedId throws 400 user.block.self. Double-block is a 409 โ calling twice for the same target throws user.block.already_blocked. The mutation is audit-logged at warn level for moderation review.
Block is directional โ a blocks b is independent from b blocks a. Server-side feed/messaging filters use the union of both directions, but the underlying row is one-way.
Blocked users are not notified. Don't surface "you have been blocked" UI on the blocked side โ that's a deliberate design choice across the platform.
Request
Path parameters
| Param | Type | Validation | Notes |
|---|---|---|---|
userId | string (UUID) | ParseUUIDPipe | The user to block |
No body.
| Header | Required | Notes |
|---|---|---|
Authorization: Bearer <accessToken> | โ | JWT from POST /auth/login |
Response
200 OK โ SuccessOnlyResponseDto
{
"success": true
}| Field | Type | Notes |
|---|---|---|
success | boolean | Always true on 200 |
Errors
| HTTP | code / i18nKey | Reason |
|---|---|---|
400 | user.block.self | userId path param equals the bearer's subject |
400 | (validation) | userId not a valid UUID |
401 | (guard) | Missing / invalid bearer token |
409 | user.block.already_blocked | A BlockList row already exists for this owner/blocked pair |
429 | (throttle) | Rate limit exceeded (10 req/hour) |
Side effects
- Reject self-block (
ownerId === blockedId) โuser.block.self. prisma.blockList.findFirst({ where: { ownerId, blockedId } }). If found โalready_blocked.prisma.blockList.create({ data: { id: randomUUID(), ownerId, blockedId } }).- Audit log (warn level):
[block] AUDIT: User {ownerId} blocked {blockedId}.
Code samples
curl -X POST https://api.bio.re/api/v1/users/block/f0e1d2c3-b4a5-6789-0123-456789abcdef \
-H "Authorization: Bearer $ACCESS_TOKEN"async function blockUser(accessToken: string, blockedUserId: string): Promise<void> {
const res = await fetch(`https://api.bio.re/api/v1/users/block/${blockedUserId}`, {
method: 'POST',
headers: { Authorization: `Bearer ${accessToken}` },
});
const json = await res.json();
if (!res.ok || !json.success) {
throw Object.assign(new Error(json?.error?.message ?? 'Block failed'), {
code: json?.error?.code,
});
}
}import { useMutation, useQueryClient } from '@tanstack/react-query';
export function useBlockUser() {
const qc = useQueryClient();
return useMutation({
mutationFn: async (blockedUserId: string) => {
const res = await fetch(`/api/v1/users/block/${blockedUserId}`, { method: 'POST' });
const json = await res.json();
if (!res.ok || !json.success) {
throw Object.assign(new Error(json?.error?.message ?? 'Block failed'), {
code: json?.error?.code,
i18nKey: json?.error?.i18nKey,
});
}
},
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['users', 'blocked'] });
},
});
}Try it
Authorization
bearer In: header
Path Parameters
Response Body
application/json
application/json
application/json
application/json
curl -X POST "https://loading/api/v1/users/block/string"{
"success": true
}{
"success": false,
"error": {
"code": "AUTH_UNAUTHORIZED",
"message": "Invalid credentials",
"i18nKey": "auth.login.invalid_credentials",
"i18nVars": {
"field": "email"
},
"details": [
{
"message": "email must be an email"
}
],
"correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}{
"success": false,
"error": {
"code": "AUTH_UNAUTHORIZED",
"message": "Invalid credentials",
"i18nKey": "auth.login.invalid_credentials",
"i18nVars": {
"field": "email"
},
"details": [
{
"message": "email must be an email"
}
],
"correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}{
"success": false,
"error": {
"code": "AUTH_UNAUTHORIZED",
"message": "Invalid credentials",
"i18nKey": "auth.login.invalid_credentials",
"i18nVars": {
"field": "email"
},
"details": [
{
"message": "email must be an email"
}
],
"correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}Source
| Source | Path | Lines |
|---|---|---|
| Controller | apps/api-core/src/modules/user/user.controller.ts | 286โ296 (blockUser) |
| DTO (response) | apps/api-core/src/common/dto/common-response.dto.ts | SuccessOnlyResponseDto |
| Service | apps/api-core/src/modules/user/user.service.ts | 767โ777 (blockUser) |
| Prisma model | packages/prisma/prisma/schema.prisma | BlockList |