Skip to main content
CBPay puede exigir un código de verificación de un solo uso (OTP) antes de las acciones sensibles: iniciar sesión, crear un payout, retirar crypto, revelar una tarjeta, emitir una API key… El código llega por SMS o WhatsApp al teléfono de la cuenta, y tu operador decide qué acciones lo exigen y por qué canal — por cuenta o para toda la organización.
El OTP aplica solo a sesiones de usuario (login con JWT). Las API keys pk_ están exentas: son integraciones server-to-server y no hay un humano con teléfono al otro lado. Si toda tu operación usa API keys, esta página no cambia nada de tu integración.
Esta página cubre el flujo OTP por acción que tu integración debe manejar (otp_required → challenge → verify). Todo lo que el usuario final gestiona sobre sus propios factores — activar el 2FA, canales (SMS/WhatsApp/email), la app autenticadora (TOTP), códigos de recuperación y passkeys — vive en Perfil y seguridad.

Cómo funciona

El otp_token es de un solo uso, está ligado a tu usuario y a la acción para la que se emitió, y expira junto con el desafío (10 minutos desde el envío del código).

1. Consulta tu política

GET /v1/otp/settings te dice si el OTP está activo y qué acciones lo exigen:

2. Pide el código

Respuesta 201 — el código ya viaja al teléfono de la cuenta:
Si la cuenta no tiene teléfono: 409 phone_required (cárgalo con PATCH /v1/me). Hay límites de envío por hora — si te pasas, 429 too_many_attempts.

3. Verifica el código

Código incorrecto → 401 invalid_code (tienes 5 intentos por desafío).

4. Ejecuta la acción con el token

El token se consume al usarlo, incluso si la acción falla después (por ejemplo por saldo insuficiente): para reintentar necesitas verificar un desafío nuevo. Tu idempotency_key sigue siendo la protección contra duplicados — el OTP no la reemplaza.

Login en dos pasos

Si tu política exige OTP en login, POST /v1/auth/login deja de devolver la sesión directamente:
El pending_token no sirve para llamar a la API: solo se canjea, junto con el código, por la sesión real:

El teléfono de la cuenta

  • Formato E.164 (+56912345678), se define en el registro, con PATCH /v1/me o por tu operador.
  • phone_verified pasa a true la primera vez que verificas un desafío: demuestra que el titular tiene el teléfono en mano.
  • Cambiar el teléfono (acción phone_change) valida el código contra el número anterior — así nadie puede redirigir tus códigos sin tener tu teléfono actual.
  • Si el teléfono se enlaza por primera vez (o se cambia sin verificación), los desafíos por SMS/WhatsApp quedan bloqueados por 24 horas: es la ventana anti-secuestro de sesión. Durante el cooldown, si tienes la app autenticadora enrolada o tu email verificado, el desafío se emite automáticamente por ese factor más fuerte (el canal llega en la respuesta del desafío); solo si no tienes ninguna alternativa recibes 403 phone_binding_cooldown. El teléfono cargado por tu operador no tiene cooldown.
  • El login en dos pasos respeta la misma regla: con 2FA de login por SMS/WhatsApp y el teléfono en cooldown, el código del login se emite por la app autenticadora o tu email de login (el channel efectivo llega en la respuesta del login) — jamás viaja a un número recién enlazado sin verificar. Sin factor alternativo el login responde 403 phone_binding_cooldown hasta que venza el cooldown.

Errores

FAQ

No. Las API keys pk_ están exentas por diseño: la automatización no pasa por OTP. Protege tus keys como corresponde — emitir una key nueva sí puede exigir OTP (acción api_key_create).
El canal lo configura tu operador por acción (por cuenta o para toda la organización). Lo ves en GET /v1/otp/settings.
El código y el desafío duran 10 minutos. Tienes 5 verificaciones por desafío y un límite de envíos por hora. El otp_token resultante es de un solo uso.
No: el token queda ligado a la acción exacta para la que pediste el desafío (un token de payout no sirve para transfer) y se consume al primer uso.
No. El token consumido solo te obliga a verificar un desafío nuevo; la idempotency_key de la operación sigue garantizando que no haya duplicados.
Última modificación el 24 de julio de 2026