
# Crear un trabajo masivo de restablecimiento de contraseña

`POST /v1/jobs/password-resets` · permiso `user-credentials:write`

Exige a muchos usuarios que elijan una contraseña nueva en un único trabajo asíncrono, por ejemplo tras una posible filtración o para sacar a los usuarios de formatos de hash importados y débiles. La respuesta devuelve el trabajo de inmediato; los usuarios se marcan en segundo plano. Dé seguimiento al trabajo con [Obtener un trabajo masivo de restablecimiento de contraseña](/docs/api/management/jobs/get-password-reset). Para un solo usuario, use [Forzar un restablecimiento de contraseña](/docs/api/management/users/force-password-reset).

Seleccione los usuarios de una de estas dos formas (no de ambas):

- `user_ids`: hasta 100.000 ids de usuario; los ids repetidos cuentan una vez. Los ids que no corresponden a usuarios de este entorno, y los usuarios sin contraseña, se cuentan como `not_found`.
- `hash_algos`: todos los usuarios cuya contraseña esté guardada con uno de estos algoritmos y cuyo último cambio sea anterior a la creación del trabajo (por ejemplo, `["md5", "phpass"]`). Una contraseña establecida después de crear el trabajo no se selecciona.

El filtro `connection_id` todavía no está disponible; una solicitud que lo envíe se rechaza con `422 validation_failed` (`not_supported` en `/connection_id`).

Elija el `mode`:

- `on_login`: cada usuario seleccionado debe establecer una contraseña nueva tras su siguiente inicio de sesión correcto con contraseña.
- `lazy_then_bulk_reset`: lo mismo hasta la fecha límite (`deadline_days`, de 1 a 365, por defecto 30). En la fecha límite, se elimina el hash de contraseña de cada usuario seleccionado que aún no haya cambiado su contraseña, y se envía un correo de restablecimiento de contraseña a su correo principal verificado (los usuarios sin uno pueden solicitar un restablecimiento por sí mismos). `deadline_days` solo se acepta en este modo.

`Idempotency-Key` es obligatorio. La misma credencial, la misma clave y la misma solicitud devuelven el mismo trabajo (con `Idempotent-Replayed: true`); la misma clave con una solicitud distinta se rechaza con `422 idempotency_key_reuse`. Un entorno puede tener como máximo 20 trabajos que no estén completados; un trabajo diferido permanece abierto hasta su fecha límite. La creación del trabajo se escribe en el registro de auditoría de administración (`password_reset_job.created`) y emite el evento `password_reset.scheduled`.

## Solicitud

| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| `mode` | string | sí | `on_login` o `lazy_then_bulk_reset`. |
| `user_ids` | string[] | una de las dos | De 1 a 100.000 ids de usuario (`usr_…`). |
| `hash_algos` | string[] | una de las dos | Algoritmos de hash almacenados: `argon2id`, `argon2i`, `bcrypt`, `scrypt`, `firebase_scrypt`, `pbkdf2_sha1`, `pbkdf2_sha256`, `pbkdf2_sha512`, `django_pbkdf2_sha256`, `django_bcrypt_sha256`, `phpass`, `ldap_ssha`, `ldap_ssha256`, `sha512_crypt`, `hmac_sha256`, `salted_sha256`, `salted_sha512`, `md5`. |
| `deadline_days` | integer | no | Solo para `lazy_then_bulk_reset`: de 1 a 365, por defecto 30. |

## Respuesta

`202 Accepted` con el trabajo.

```json
{
  "id": "job_01h455vb4pex5vsknk084sn02q",
  "mode": "lazy_then_bulk_reset",
  "filter": "hash_algo",
  "hash_algos": ["md5", "phpass"],
  "status": "marking",
  "deadline_at": "2026-02-14T09:30:00Z",
  "total": 0,
  "marked": 0,
  "not_found": 0,
  "passwords_deleted": 0,
  "emailed": 0,
  "created_at": "2026-01-15T09:30:00Z"
}
```

## Errores

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

| HTTP | `code` | Cuándo |
|---|---|---|
| 400 | `malformed_request`, `unknown_field` | Falta el encabezado `Idempotency-Key` o está mal formado, el cuerpo no es JSON válido o tiene un campo desconocido. |
| 401 | `unauthenticated` | La clave de API falta, no es válida o fue revocada. |
| 403 | `insufficient_permissions` | La clave no tiene el permiso `user-credentials:write`. |
| 409 | `conflict` | El entorno ya tiene 20 trabajos que no están completados. |
| 413 | `payload_too_large` | El cuerpo supera los 4 MiB. |
| 422 | `validation_failed` | Falta un campo o no es válido; `errors[].pointer` lo indica. |
| 422 | `idempotency_key_reuse` | La clave `Idempotency-Key` se usó con una solicitud distinta. |
| 429 | `rate_limited` | Se superó el límite de tasa; respete `Retry-After`. |
| 503 | `service_unavailable` | Una dependencia no está disponible temporalmente; vuelva a intentarlo más tarde. |

## Ejemplo

```bash
curl -X POST https://api.eu.keenauth.com/v1/jobs/password-resets \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"mode": "lazy_then_bulk_reset", "hash_algos": ["md5", "phpass"], "deadline_days": 30}'
```

CLI: `keenauth jobs password-resets create --mode lazy_then_bulk_reset --hash-algos md5,phpass --deadline-days 30 --yes`
