BIO.RE
User

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

ParamTypeValidationNotes
userIdstring (UUID)ParseUUIDPipeThe user to block

No body.

HeaderRequiredNotes
Authorization: Bearer <accessToken>โœ“JWT from POST /auth/login

Response

200 OK โ€” SuccessOnlyResponseDto

{
  "success": true
}
FieldTypeNotes
successbooleanAlways true on 200

Errors

HTTPcode / i18nKeyReason
400user.block.selfuserId path param equals the bearer's subject
400(validation)userId not a valid UUID
401(guard)Missing / invalid bearer token
409user.block.already_blockedA BlockList row already exists for this owner/blocked pair
429(throttle)Rate limit exceeded (10 req/hour)

Side effects

  1. Reject self-block (ownerId === blockedId) โ†’ user.block.self.
  2. prisma.blockList.findFirst({ where: { ownerId, blockedId } }). If found โ†’ already_blocked.
  3. prisma.blockList.create({ data: { id: randomUUID(), ownerId, blockedId } }).
  4. 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

POST
/api/v1/users/block/{userId}
AuthorizationBearer <token>

In: header

Path Parameters

userId*string

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

SourcePathLines
Controllerapps/api-core/src/modules/user/user.controller.ts286โ€“296 (blockUser)
DTO (response)apps/api-core/src/common/dto/common-response.dto.tsSuccessOnlyResponseDto
Serviceapps/api-core/src/modules/user/user.service.ts767โ€“777 (blockUser)
Prisma modelpackages/prisma/prisma/schema.prismaBlockList

On this page