
# Bloquear un usuario

`POST /v1/users/{user_id}:block` · permiso `users:write`

Bloquea un usuario con un bloqueo de cliente (`source = admin_api`); el estado pasa a `blocked`. Bloquear un usuario que ya está bloqueado se completa sin cambios. Un usuario que está pendiente de eliminación no puede bloquearse. La revocación de las sesiones del usuario se ejecuta de forma asíncrona. Envíe un encabezado `Idempotency-Key` para que los reintentos sean seguros.

## Solicitud

| Parámetro | En | Obligatorio | Descripción |
|---|---|---|---|
| `user_id` | path | sí | Id del usuario, con el prefijo `usr_`. |

Cuerpo opcional:

| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| `note` | string | no | Hasta 1000 caracteres. No escriba datos personales. |

## Respuesta

`200 OK`. El cuerpo es el objeto del usuario. El encabezado `ETag` contiene la versión del usuario.

Los datos personales se enmascaran cuando la clave no tiene el permiso `users:read_pii`: `email` pasa a ser `a***@e***.com`, `phone_number` conserva solo sus últimos 2 dígitos (`+**********67`), `name`, `given_name`, `family_name`, `middle_name` y `nickname` se convierten en iniciales (`A. L.`), `username` conserva solo su primer carácter (`a***`), `birthdate` pasa a ser `****-**-**` y `address` pasa a ser `{"redacted": true}`. `user_metadata` y `app_metadata` no se enmascaran.

```json
{
  "id": "usr_0a1b2c3d4e5f6g7h8j9k0m1n2p",
  "kind": "regular",
  "status": "active",
  "external_id": null,
  "username": null,
  "name": "Ada Lovelace",
  "email": "ada@example.com",
  "email_verified": true,
  "phone_number": null,
  "phone_verified": false,
  "user_metadata": {},
  "app_metadata": {},
  "created_via": "admin_api",
  "created_at": "2026-01-15T09:30:00Z",
  "updated_at": "2026-01-15T09:30:00Z",
  "last_sign_in_at": null,
  "deletion_requested_at": null,
  "deletion_due_at": null
}
```

## Errores

Cada error es un cuerpo `application/problem+json` con un `code` estable.

| HTTP | `code` | Cuándo |
|---|---|---|
| 400 | `malformed_request`, `unknown_field` | El cuerpo no es JSON válido o tiene un campo desconocido. |
| 409 | `conflict` | El usuario está pendiente de eliminación (`errors[].code` es `user_pending_deletion`). |
| 415 | `unsupported_media_type` | Se envió un cuerpo sin `Content-Type: application/json`. |
| 422 | `validation_failed` | `note` es demasiado largo. |
| 404 | `not_found` | El usuario no existe en este entorno (o el id tiene un formato incorrecto). |
| 401 | `unauthenticated` | La clave de API falta, no es válida o ha sido revocada. |
| 403 | `insufficient_permissions` | La clave no tiene el permiso `users:write`. |
| 429 | `rate_limited` | Se superó el límite de solicitudes; respete `Retry-After`. |
| 503 | `service_unavailable` | Una dependencia no está disponible temporalmente; reintente más tarde. |

## Ejemplo

```bash
curl -X POST https://api.eu.keenauth.com/v1/users/usr_0a1b2c3d4e5f6g7h8j9k0m1n2p:block \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"note": "Suspected account takeover"}'
```

## Datos personales

Este endpoint contiene datos personales: perfil del usuario final. [Datos personales en las API de KeenAuth](/docs/policies/personal-data) describe qué se almacena, durante cuánto tiempo se conserva y cómo se elimina. No envíe categorías especiales de datos personales (salud, datos biométricos, religión, opiniones políticas, orientación sexual) en ningún campo.
