Manda un código de un solo uso al número por WhatsApp.
Revisado el 18 de septiembre de 2026
- Método: `POST`
- Ruta: `/v1/auth/whatsapp/start`
- Autenticación: `publica`
Primer paso del registro progresivo (ADR-009). Devuelve siempre lo mismo cuando el número tiene forma válida: no dice si ese número ya tiene cuenta. Decirlo convertiría este endpoint en un comprobador de quién está registrado en Cerca.
Un reenvío dentro de la vigencia no genera un código nuevo: reenvía el mismo. Si generara otro, quien recibió el primero vería fallar el que tiene a la vista.
Puede reenviar el mismo porque el código no se guarda, ni en claro ni como hash: se deriva del reto —un nonce por reto y el número— con una clave que vive en un secreto del Worker (`OTP_HMAC_CLAVE`, ADR-035). Reenviar lo reproduce, y quien lea el almacén `RETOS` obtiene un nonce que sin la clave no sirve para nada. Un hash sin clave de seis dígitos se invierte recorriendo el millón de valores en menos de un segundo; por eso no se guarda ninguno.
Respuestas
- `202`: Aceptado: el código va en camino. No es 200 porque la entrega depende del proveedor y todavía no ocurrió.
- `400`: El número no tiene forma de E.164.
- `403`: El ambiente exige comprobación antiabuso y el token de Turnstile falta, está vencido o no lo reconoce Cloudflare. No dice nada del número: se responde antes de mirarlo.
- `429`: Demasiados envíos al mismo número dentro de la vigencia.
- `503`: Falta algo propio de esta operación en el ambiente: el secreto `TURNSTILE_SECRET_KEY` en producción (sin él la ruta se cierra en vez de mandar mensajes que cuestan), la clave `OTP_HMAC_CLAVE` con la que se deriva el código (sin ella no hay código que mandar, y no se deriva con una clave inventada; ADR-035), el proveedor de mensajería de `packages/providers` o el KV `RETOS`. También cuando el proveedor no acepta el envío. `OTP_HMAC_CLAVE_ANTERIOR`, la clave que solo verifica durante la ventana de una rotación planificada, es opcional y su ausencia nunca es un 503.
- `default`: referencia compartida: #/components/responses/Problem
¿Te sirvió este artículo?