Enviar Código de Verificación (OTP)
channel: el mismo código sale por el canal nuevo y cubres los números que no reciben SMS. La respuesta siempre te dice qué hizo (action) y qué sigue (next)./v2/otpPara probar, basta con phone_number, country_code y company — el código llega por SMS en segundos. Con code_show: 1 la respuesta incluye el código y puedes automatizar la prueba sin leer el teléfono.
Cuerpo de la petición
application/json
52.Canal de entrega del código:
sms(default): mensaje de texto.whatsapp: mensaje de WhatsApp oficial con plantilla fija (ignoramessageycompany). No requiere cuenta de WhatsApp Business ni verificación de Meta: sale por la integración oficial de SMS Masivos (remitenteAuthenticate).voice: llamada que dicta el código dígito por dígito.
En un reenvío puedes cambiar de canal: el mismo código pendiente sale por el canal nuevo (fallback).
channel: sms y voice (requisito de operadores); se ignora con whatsapp.Texto propio del mensaje (opcional, solo sms y voice). Debe incluir los placeholders {{code}} y {{company}}, usar solo caracteres GSM-7 (sin emojis ni acentos raros) y no exceder 160 caracteres ya con el código y la empresa sustituidos.
Si no lo envías se usa el texto default: {{code}} es tu codigo de verificacion de {{company}}. No lo compartas.
Formato del código generado:
numeric(default): solo números.alphanumeric: letras y números.letters: solo letras.
true descarta el código vigente y genera uno nuevo (nueva ronda con 7 intentos). Sin él, un código vigente se reenvía tal cual. El cooldown de 30s aplica igual.Devuelve el código generado en el campo code de la respuesta:
0(default): no devolver.1: devolver (pruebas/automatización del lado del servidor).
YYYY-MM-DD HH:mm:ss (futura). Por defecto 24 horas; máximo 3 días (si envías más, se ajusta al máximo).Respuesta
action: resent) o rotado sobre una ronda en curso (action: restarted)pending: hay un código activo esperando verificación.Qué hizo la API con tu solicitud:
created: primera verificación para el número (o la anterior ya había expirado). HTTP201.resent: reenvió el mismo código vigente. HTTP200.restarted: generó un código nuevo e inició otra ronda (concode_rotate: true, o tras una verificación completada). HTTP200o201.
YYYY-MM-DD HH:mm:ss, hora del centro de México).message/company con channel: whatsapp (se ignoran, la plantilla de WhatsApp es fija).code_show: 1 (pruebas/automatización).pending: hay un código activo esperando verificación.Qué hizo la API con tu solicitud:
created: primera verificación para el número (o la anterior ya había expirado). HTTP201.resent: reenvió el mismo código vigente. HTTP200.restarted: generó un código nuevo e inició otra ronda (concode_rotate: true, o tras una verificación completada). HTTP200o201.
YYYY-MM-DD HH:mm:ss, hora del centro de México).message/company con channel: whatsapp (se ignoran, la plantilla de WhatsApp es fija).code_show: 1 (pruebas/automatización).otp_missing_param, otp_invalid_param, otp_invalid_channel, otp_message_invalid)Slug estable del error, para manejo programático:
| Slug | HTTP | Significado |
|---|---|---|
otp_missing_param |
400 |
Falta un parámetro obligatorio. |
otp_invalid_param |
400 |
Un parámetro es inválido o no aplica a este endpoint. |
otp_invalid_channel |
400 |
channel debe ser sms, whatsapp o voice. |
otp_message_invalid |
400 |
El message personalizado no cumple las reglas (placeholders, GSM-7, 160). |
otp_incorrect_code |
401 |
El código no coincide. |
otp_insufficient_credits |
402 |
Saldo insuficiente para enviar. |
otp_not_found |
404 |
No hay verificación activa para el número. |
otp_already_verified |
409 |
El número ya está verificado. |
otp_code_expired |
410 |
El código expiró. |
otp_throttled |
429 |
Cooldown de reenvío activo (espera resend_available_in). |
otp_max_attempts |
429 |
Se agotaron los 7 intentos de verificación de la ronda. |
otp_internal |
500 |
Error inesperado. |
otp_send_failed |
502 |
El mensaje no pudo enviarse. |
otp_throttled).otp_insufficient_credits: siempre sms_07, el código estándar de saldo insuficiente de toda la API.Slug estable del error, para manejo programático:
| Slug | HTTP | Significado |
|---|---|---|
otp_missing_param |
400 |
Falta un parámetro obligatorio. |
otp_invalid_param |
400 |
Un parámetro es inválido o no aplica a este endpoint. |
otp_invalid_channel |
400 |
channel debe ser sms, whatsapp o voice. |
otp_message_invalid |
400 |
El message personalizado no cumple las reglas (placeholders, GSM-7, 160). |
otp_incorrect_code |
401 |
El código no coincide. |
otp_insufficient_credits |
402 |
Saldo insuficiente para enviar. |
otp_not_found |
404 |
No hay verificación activa para el número. |
otp_already_verified |
409 |
El número ya está verificado. |
otp_code_expired |
410 |
El código expiró. |
otp_throttled |
429 |
Cooldown de reenvío activo (espera resend_available_in). |
otp_max_attempts |
429 |
Se agotaron los 7 intentos de verificación de la ronda. |
otp_internal |
500 |
Error inesperado. |
otp_send_failed |
502 |
El mensaje no pudo enviarse. |
otp_throttled).otp_insufficient_credits: siempre sms_07, el código estándar de saldo insuficiente de toda la API.otp_throttled) o intentos de verificación agotados sin code_rotate (otp_max_attempts). Incluye header Retry-After.Slug estable del error, para manejo programático:
| Slug | HTTP | Significado |
|---|---|---|
otp_missing_param |
400 |
Falta un parámetro obligatorio. |
otp_invalid_param |
400 |
Un parámetro es inválido o no aplica a este endpoint. |
otp_invalid_channel |
400 |
channel debe ser sms, whatsapp o voice. |
otp_message_invalid |
400 |
El message personalizado no cumple las reglas (placeholders, GSM-7, 160). |
otp_incorrect_code |
401 |
El código no coincide. |
otp_insufficient_credits |
402 |
Saldo insuficiente para enviar. |
otp_not_found |
404 |
No hay verificación activa para el número. |
otp_already_verified |
409 |
El número ya está verificado. |
otp_code_expired |
410 |
El código expiró. |
otp_throttled |
429 |
Cooldown de reenvío activo (espera resend_available_in). |
otp_max_attempts |
429 |
Se agotaron los 7 intentos de verificación de la ronda. |
otp_internal |
500 |
Error inesperado. |
otp_send_failed |
502 |
El mensaje no pudo enviarse. |
otp_throttled).otp_insufficient_credits: siempre sms_07, el código estándar de saldo insuficiente de toda la API.Slug estable del error, para manejo programático:
| Slug | HTTP | Significado |
|---|---|---|
otp_missing_param |
400 |
Falta un parámetro obligatorio. |
otp_invalid_param |
400 |
Un parámetro es inválido o no aplica a este endpoint. |
otp_invalid_channel |
400 |
channel debe ser sms, whatsapp o voice. |
otp_message_invalid |
400 |
El message personalizado no cumple las reglas (placeholders, GSM-7, 160). |
otp_incorrect_code |
401 |
El código no coincide. |
otp_insufficient_credits |
402 |
Saldo insuficiente para enviar. |
otp_not_found |
404 |
No hay verificación activa para el número. |
otp_already_verified |
409 |
El número ya está verificado. |
otp_code_expired |
410 |
El código expiró. |
otp_throttled |
429 |
Cooldown de reenvío activo (espera resend_available_in). |
otp_max_attempts |
429 |
Se agotaron los 7 intentos de verificación de la ronda. |
otp_internal |
500 |
Error inesperado. |
otp_send_failed |
502 |
El mensaje no pudo enviarse. |
otp_throttled).otp_insufficient_credits: siempre sms_07, el código estándar de saldo insuficiente de toda la API.Slug estable del error, para manejo programático:
| Slug | HTTP | Significado |
|---|---|---|
otp_missing_param |
400 |
Falta un parámetro obligatorio. |
otp_invalid_param |
400 |
Un parámetro es inválido o no aplica a este endpoint. |
otp_invalid_channel |
400 |
channel debe ser sms, whatsapp o voice. |
otp_message_invalid |
400 |
El message personalizado no cumple las reglas (placeholders, GSM-7, 160). |
otp_incorrect_code |
401 |
El código no coincide. |
otp_insufficient_credits |
402 |
Saldo insuficiente para enviar. |
otp_not_found |
404 |
No hay verificación activa para el número. |
otp_already_verified |
409 |
El número ya está verificado. |
otp_code_expired |
410 |
El código expiró. |
otp_throttled |
429 |
Cooldown de reenvío activo (espera resend_available_in). |
otp_max_attempts |
429 |
Se agotaron los 7 intentos de verificación de la ronda. |
otp_internal |
500 |
Error inesperado. |
otp_send_failed |
502 |
El mensaje no pudo enviarse. |
otp_throttled).otp_insufficient_credits: siempre sms_07, el código estándar de saldo insuficiente de toda la API.Qué hace cada llamada
El endpoint decide según el estado del número — tú solo repites el POST:
| Estado del número | Qué hace | HTTP | action |
|---|---|---|---|
| Sin verificación activa (o expirada) | Crea y envía un código nuevo. | 201 | created |
| Código vigente | Reenvía el mismo código. | 200 | resent |
Código vigente + code_rotate: true | Descarta el anterior y genera uno nuevo (7 intentos frescos). | 200 | restarted |
| Ya verificado | Inicia un ciclo nuevo. | 201 | restarted |
Entre envíos aplica un cooldown de 30 segundos (con o sin code_rotate); si no esperas, recibes 429 otp_throttled con el tiempo restante.
Dependencias entre parámetros
channel: smsyvoicerequierencompany;whatsappla ignora (plantilla oficial fija) y responde conwarning.messagesolo aplica asmsyvoice, y debe incluir{{code}}y{{company}}.
code_show: 1 está pensado para pruebas y automatización del lado del servidor. Nunca reenvíes esa respuesta al navegador o a la app del usuario: si el código regresa al mismo cliente que lo va a capturar, el flujo deja de probar la posesión del teléfono.
Cómo leer los errores
Cada error llega con su status HTTP real, un slug estable en error, una sugerencia accionable en hint y los endpoints sugeridos en next:
| HTTP | error | Cuándo ocurre | Qué hacer |
|---|---|---|---|
400 | otp_missing_param / otp_invalid_param | Falta un parámetro, es inválido, o enviaste uno de la API anterior (voice, whatsapp, template). | El hint indica el parámetro exacto. |
400 | otp_invalid_channel | channel no es sms, whatsapp ni voice. | Corrige el valor. |
400 | otp_message_invalid | message sin {{code}}/{{company}}, con caracteres fuera de GSM-7, o que excede 160 caracteres ya expandido. | El hint detalla la regla incumplida. |
402 | otp_insufficient_credits | Sin saldo para enviar (incluye code: sms_07). | Recarga saldo. |
429 | otp_throttled | Cooldown de reenvío activo. | Espera resend_available_in segundos (también en el header Retry-After). |
429 | otp_max_attempts | La ronda está bloqueada por intentos agotados y no enviaste code_rotate. | Rota el código con code_rotate: true. |
502 | otp_send_failed | El canal no pudo entregar el mensaje. | Reintenta; si persiste, contacta a soporte con el request_id. |
Los errores de autenticación (auth_*) vienen de la capa común de la API y llegan con HTTP 200 y el detalle en el body — consulta Errores y límites.