Enviar Código de Verificación (OTP)

Genera y envía un código de verificación por SMS, WhatsApp o llamada de voz. Este único endpoint maneja todo el ciclo: la primera llamada crea el código, y el botón "No recibí el código" de tu app se resuelve repitiendo la misma llamada — incluso con otro 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).
post/v2/otp

Para 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.

Autorización

apikeystringheaderrequerido

Cuerpo de la petición

application/json

phone_numberstringrequerido
Número de teléfono a verificar (hasta 10 dígitos, sin código de país). En México siempre son 10 dígitos.
country_codestringrequerido
Código de país, numérico. Para México envía 52.
channelenum

Canal de entrega del código:

  • sms (default): mensaje de texto.
  • whatsapp: mensaje de WhatsApp oficial con plantilla fija (ignora message y company). No requiere cuenta de WhatsApp Business ni verificación de Meta: sale por la integración oficial de SMS Masivos (remitente Authenticate).
  • 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).

enum:smswhatsappvoice
companystring
Nombre de tu empresa o app, mostrado al usuario en el mensaje. Obligatorio con channel: sms y voice (requisito de operadores); se ignora con whatsapp.
messagestring

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.

code_formatenum

Formato del código generado:

  • numeric (default): solo números.
  • alphanumeric: letras y números.
  • letters: solo letras.
enum:numericalphanumericletters
code_lengthinteger
Longitud del código (4 a 10 caracteres). Por defecto 6.
code_rotateboolean
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.
code_showenum

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).
enum:01
expiration_datestring
Fecha de expiración del código, formato 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

200Código reenviado (action: resent) o rotado sobre una ronda en curso (action: restarted)
successbooleanrequerido
stateenumrequerido
Estado de la verificación después del envío. Siempre pending: hay un código activo esperando verificación.
enum:pending
actionenumrequerido

Qué hizo la API con tu solicitud:

  • created: primera verificación para el número (o la anterior ya había expirado). HTTP 201.
  • resent: reenvió el mismo código vigente. HTTP 200.
  • restarted: generó un código nuevo e inició otra ronda (con code_rotate: true, o tras una verificación completada). HTTP 200 o 201.
enum:createdresentrestarted
messagestring
Descripción del resultado en español.
hintstring
Sugerencia accionable sobre el siguiente paso.
nextarray<string>
Endpoints sugeridos como siguiente paso del flujo.
expires_atstring
Fecha de expiración del código (YYYY-MM-DD HH:mm:ss, hora del centro de México).
attempts_remaininginteger
Intentos de verificación disponibles para este código (máximo 7 por ronda).
resend_available_ininteger
Segundos que deben pasar antes de poder reenviar o rotar el código (cooldown de 30s).
warningstring
Solo cuando aplica: aviso no bloqueante, por ejemplo al enviar message/company con channel: whatsapp (se ignoran, la plantilla de WhatsApp es fija).
codestring
El código generado. Solo cuando envías code_show: 1 (pruebas/automatización).
request_idstring
UUID para seguimiento de la petición.
201Código creado y enviado (primera verificación, o la anterior ya había expirado o completado)
successbooleanrequerido
stateenumrequerido
Estado de la verificación después del envío. Siempre pending: hay un código activo esperando verificación.
enum:pending
actionenumrequerido

Qué hizo la API con tu solicitud:

  • created: primera verificación para el número (o la anterior ya había expirado). HTTP 201.
  • resent: reenvió el mismo código vigente. HTTP 200.
  • restarted: generó un código nuevo e inició otra ronda (con code_rotate: true, o tras una verificación completada). HTTP 200 o 201.
enum:createdresentrestarted
messagestring
Descripción del resultado en español.
hintstring
Sugerencia accionable sobre el siguiente paso.
nextarray<string>
Endpoints sugeridos como siguiente paso del flujo.
expires_atstring
Fecha de expiración del código (YYYY-MM-DD HH:mm:ss, hora del centro de México).
attempts_remaininginteger
Intentos de verificación disponibles para este código (máximo 7 por ronda).
resend_available_ininteger
Segundos que deben pasar antes de poder reenviar o rotar el código (cooldown de 30s).
warningstring
Solo cuando aplica: aviso no bloqueante, por ejemplo al enviar message/company con channel: whatsapp (se ignoran, la plantilla de WhatsApp es fija).
codestring
El código generado. Solo cuando envías code_show: 1 (pruebas/automatización).
request_idstring
UUID para seguimiento de la petición.
400Parámetro faltante o inválido (otp_missing_param, otp_invalid_param, otp_invalid_channel, otp_message_invalid)
successbooleanrequerido
stateenum
Estado actual de la verificación (presente cuando es relevante para el error).
enum:nonependingverifiedexpiredlocked
errorstringrequerido

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.
messagestringrequerido
Descripción del error en español.
hintstring
Sugerencia accionable para resolverlo.
nextarray<string>
Endpoints sugeridos como siguiente paso.
expires_atstring
Expiración del código vigente, cuando aplica.
attempts_remaininginteger
Intentos de verificación restantes, cuando aplica.
resend_available_ininteger
Segundos restantes del cooldown de reenvío, cuando aplica (errores otp_throttled).
codestring
Solo en otp_insufficient_credits: siempre sms_07, el código estándar de saldo insuficiente de toda la API.
request_idstring
UUID para seguimiento de la petición.
402Saldo insuficiente para enviar el código
successbooleanrequerido
stateenum
Estado actual de la verificación (presente cuando es relevante para el error).
enum:nonependingverifiedexpiredlocked
errorstringrequerido

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.
messagestringrequerido
Descripción del error en español.
hintstring
Sugerencia accionable para resolverlo.
nextarray<string>
Endpoints sugeridos como siguiente paso.
expires_atstring
Expiración del código vigente, cuando aplica.
attempts_remaininginteger
Intentos de verificación restantes, cuando aplica.
resend_available_ininteger
Segundos restantes del cooldown de reenvío, cuando aplica (errores otp_throttled).
codestring
Solo en otp_insufficient_credits: siempre sms_07, el código estándar de saldo insuficiente de toda la API.
request_idstring
UUID para seguimiento de la petición.
429Cooldown de reenvío activo (otp_throttled) o intentos de verificación agotados sin code_rotate (otp_max_attempts). Incluye header Retry-After.
successbooleanrequerido
stateenum
Estado actual de la verificación (presente cuando es relevante para el error).
enum:nonependingverifiedexpiredlocked
errorstringrequerido

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.
messagestringrequerido
Descripción del error en español.
hintstring
Sugerencia accionable para resolverlo.
nextarray<string>
Endpoints sugeridos como siguiente paso.
expires_atstring
Expiración del código vigente, cuando aplica.
attempts_remaininginteger
Intentos de verificación restantes, cuando aplica.
resend_available_ininteger
Segundos restantes del cooldown de reenvío, cuando aplica (errores otp_throttled).
codestring
Solo en otp_insufficient_credits: siempre sms_07, el código estándar de saldo insuficiente de toda la API.
request_idstring
UUID para seguimiento de la petición.
500Error interno inesperado
successbooleanrequerido
stateenum
Estado actual de la verificación (presente cuando es relevante para el error).
enum:nonependingverifiedexpiredlocked
errorstringrequerido

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.
messagestringrequerido
Descripción del error en español.
hintstring
Sugerencia accionable para resolverlo.
nextarray<string>
Endpoints sugeridos como siguiente paso.
expires_atstring
Expiración del código vigente, cuando aplica.
attempts_remaininginteger
Intentos de verificación restantes, cuando aplica.
resend_available_ininteger
Segundos restantes del cooldown de reenvío, cuando aplica (errores otp_throttled).
codestring
Solo en otp_insufficient_credits: siempre sms_07, el código estándar de saldo insuficiente de toda la API.
request_idstring
UUID para seguimiento de la petición.
502El mensaje no pudo enviarse (falla del canal)
successbooleanrequerido
stateenum
Estado actual de la verificación (presente cuando es relevante para el error).
enum:nonependingverifiedexpiredlocked
errorstringrequerido

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.
messagestringrequerido
Descripción del error en español.
hintstring
Sugerencia accionable para resolverlo.
nextarray<string>
Endpoints sugeridos como siguiente paso.
expires_atstring
Expiración del código vigente, cuando aplica.
attempts_remaininginteger
Intentos de verificación restantes, cuando aplica.
resend_available_ininteger
Segundos restantes del cooldown de reenvío, cuando aplica (errores otp_throttled).
codestring
Solo en otp_insufficient_credits: siempre sms_07, el código estándar de saldo insuficiente de toda la API.
request_idstring
UUID para seguimiento de la petición.

Qué hace cada llamada

El endpoint decide según el estado del número — tú solo repites el POST:

Estado del númeroQué haceHTTPaction
Sin verificación activa (o expirada)Crea y envía un código nuevo.201created
Código vigenteReenvía el mismo código.200resent
Código vigente + code_rotate: trueDescarta el anterior y genera uno nuevo (7 intentos frescos).200restarted
Ya verificadoInicia un ciclo nuevo.201restarted

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: sms y voice requieren company; whatsapp la ignora (plantilla oficial fija) y responde con warning.
  • message solo aplica a sms y voice, 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:

HTTPerrorCuándo ocurreQué hacer
400otp_missing_param / otp_invalid_paramFalta un parámetro, es inválido, o enviaste uno de la API anterior (voice, whatsapp, template).El hint indica el parámetro exacto.
400otp_invalid_channelchannel no es sms, whatsapp ni voice.Corrige el valor.
400otp_message_invalidmessage sin {{code}}/{{company}}, con caracteres fuera de GSM-7, o que excede 160 caracteres ya expandido.El hint detalla la regla incumplida.
402otp_insufficient_creditsSin saldo para enviar (incluye code: sms_07).Recarga saldo.
429otp_throttledCooldown de reenvío activo.Espera resend_available_in segundos (también en el header Retry-After).
429otp_max_attemptsLa ronda está bloqueada por intentos agotados y no enviaste code_rotate.Rota el código con code_rotate: true.
502otp_send_failedEl 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.