Verificación Telefónica por OTP
📱 Descripción General
Este endpoint permite enviar un código de verificación de un solo uso (OTP) al número telefónico del usuario para validar su identidad como parte del proceso KYC. El código se envía simultáneamente por SMS y WhatsApp para garantizar la entrega.
🔐 Autenticación
Este endpoint requiere autenticación mediante Bearer Token de tipo API Key.
¿Cómo obtener tu API Key?
- Accede al panel de administración de JAAK
- Ve a la sección de Configuración o API Keys
- Genera una nueva API Key para tu empresa
- Guarda la API Key de forma segura (no se podrá recuperar después)
Formato de autenticación
Todas las peticiones deben incluir el header de autorización:
Authorization: Bearer sk_live_abc123def456ghi789jkl012mno345pqr
⚠️ Seguridad de API Keys
- NUNCA compartas tu API Key públicamente
- NO incluyas tu API Key en repositorios de código público
- NO la expongas en el código frontend (cliente)
- Usa variables de entorno para almacenarla
- Rota tus API Keys periódicamente
- Si sospechas que tu key fue comprometida, regénérala inmediatamente
🎯 ¿Cuándo usar este endpoint?
Utiliza este endpoint cuando necesites:
- Verificar que el usuario tiene acceso al número telefónico proporcionado
- Validar la identidad del usuario antes de continuar con el proceso KYC
- Iniciar el flujo de verificación telefónica en tu aplicación
🔗 Endpoint
POST /api/v1/kyc/phone/send-otp
Base URL: https://api.jaak.mx
📥 Parámetros de Entrada
Headers
| Header | Valor | Requerido | Descripción |
|---|---|---|---|
| Content-Type | application/json | ✅ Sí | Tipo de contenido |
| Authorization | Bearer + API Key | ✅ Sí | Token de autenticación |
Body Parameters
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| company_id | string | ✅ Sí | ID único de tu empresa en JAAK |
| country_document | string | ✅ Sí | Código ISO del país (ejemplo: MEX para México) |
| phone_number | string | ✅ Sí | Número telefónico en formato internacional con código de país |
⚠️ Consideraciones importantes
- El número telefónico debe incluir el código de país con el símbolo +
- Formato recomendado: código de país seguido del número sin espacios ni guiones
- Ejemplo válido: "+525512345678" (México)
- Ejemplo inválido: "5512345678" o "55-1234-5678"
📤 Ejemplo de Request
Request Body
{
"company_id": "5f8d0d55b54764421b7156c5",
"country_document": "MEX",
"phone_number": "+525512345678"
}cURL Example
curl -X POST "https://api.jaak.mx/api/v1/kyc/phone/send-otp" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_abc123def456ghi789jkl012mno345pqr" \
-d '{
"company_id": "5f8d0d55b54764421b7156c5",
"country_document": "MEX",
"phone_number": "+525512345678"
}'JavaScript Example
fetch('https://api.jaak.mx/api/v1/kyc/phone/send-otp', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer sk_live_abc123def456ghi789jkl012mno345pqr'
},
body: JSON.stringify({
company_id: '5f8d0d55b54764421b7156c5',
country_document: 'MEX',
phone_number: '+525512345678'
})
})
.then(response => response.json())
.then(data => console.log(data));Python Example
import requests
response = requests.post(
'https://api.jaak.mx/api/v1/kyc/phone/send-otp',
headers={
'Content-Type': 'application/json',
'Authorization': 'Bearer sk_live_abc123def456ghi789jkl012mno345pqr'
},
json={
'company_id': '5f8d0d55b54764421b7156c5',
'country_document': 'MEX',
'phone_number': '+525512345678'
}
)
print(response.json())PHP Example
<?php
$ch = curl_init('https://api.jaak.mx/api/v1/kyc/phone/send-otp');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'company_id' => '5f8d0d55b54764421b7156c5',
'country_document' => 'MEX',
'phone_number' => '+525512345678'
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer sk_live_abc123def456ghi789jkl012mno345pqr'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>📨 Respuestas Posibles
✅ 200 - Éxito
El OTP fue enviado correctamente al usuario.
{
"message": "OTP sent successfully",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"success": true
}Campos de respuesta:
- message: Mensaje de confirmación
- session_id: ID de sesión único que deberás usar para verificar el código OTP
- success: Indica si la operación fue exitosa
IMPORTANTE: Guarda el session_id ya que lo necesitarás para validar el código OTP que ingrese el usuario.
❌ 400 - Bad Request
Los datos enviados son inválidos o están incompletos.
Causas comunes:
- Falta algún campo requerido
- El formato del número telefónico es incorrecto
- El country_document no es válido
{
"error": "Invalid phone number format",
"details": "Phone number must include country code with + prefix"
}Solución: Verifica que todos los campos estén presentes y en el formato correcto.
❌ 401 - Unauthorized
El Bearer Token es inválido o no fue proporcionado.
{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}Causas comunes:
- No se incluyó el header Authorization
- La API Key es inválida o expiró
- El formato del Bearer Token es incorrecto
Solución: Verifica que estés enviando correctamente el header de autorización con una API Key válida.
❌ 403 - Forbidden
La API Key no tiene permisos para realizar esta operación.
{
"error": "Forbidden",
"message": "API key does not have permission to access this resource"
}Solución: Verifica que tu API Key tenga los permisos necesarios para el servicio de verificación telefónica.
❌ 404 - Company Not Found
El company_id proporcionado no existe en el sistema.
{
"error": "Company not found",
"company_id": "5f8d0d55b54764421b7156c5"
}Solución: Verifica que estés usando el company_id correcto proporcionado por JAAK.
❌ 429 - Too Many Requests
Has excedido el límite de solicitudes permitidas.
{
"error": "Rate limit exceeded",
"retry_after": 60,
"limit": "5 requests per 10 minutes per phone number"
}Solución: Espera el tiempo indicado en retry_after (en segundos) antes de volver a intentar.
Límites de rate limiting:
- Máximo 5 intentos por número telefónico cada 10 minutos
- Máximo 100 solicitudes por hora por company_id
- Máximo 1000 solicitudes por día por API Key
❌ 500 - Internal Server Error
Error interno del servidor.
{
"error": "Internal server error",
"request_id": "req_abc123xyz"
}Solución: Si el error persiste, contacta a soporte técnico con el request_id.
🔄 Flujo de Integración
- Usuario ingresa su número telefónico
- Tu aplicación valida el formato del número
- Tu aplicación llama a /send-otp con Bearer Token
- JAAK envía OTP por SMS y WhatsApp
- Usuario recibe código (válido por 5 minutos)
- Usuario ingresa código en tu app
- Tu aplicación verifica el código con el session_id
- Verificación completada
⚙️ Mejores Prácticas
✅ Recomendaciones de Seguridad
Almacenamiento de API Key:
- Usa variables de entorno
- Nunca expongas la key en código frontend
- Implementa rotación periódica (cada 90 días)
Validación de número telefónico:
- Verifica el formato antes de enviar la petición
- Debe incluir el código de país con el símbolo +
- Sin espacios ni caracteres especiales
Manejo de errores:
- Implementa retry logic para errores 429 y 500
- Usa backoff exponencial entre reintentos
- Registra errores sin exponer datos sensibles
✅ Recomendaciones de UX
Mensaje al usuario:
"Te enviamos un código de 6 dígitos por SMS y WhatsApp.
El código es válido por 5 minutos."
Consideraciones:
- Muestra claramente el tiempo de expiración (5 minutos)
- Guarda el session_id para verificación posterior
- Solo almacena el session_id, nunca el código OTP
- Limita los intentos de reenvío
❌ Errores comunes a evitar
- ❌ Exponer la API Key en el código frontend
- ❌ No validar el formato del número telefónico
- ❌ No guardar el session_id
- ❌ Permitir múltiples solicitudes sin límite
- ❌ No informar sobre el tiempo de expiración
- ❌ Hardcodear credenciales en el código
- ❌ No implementar logging
- ❌ No manejar rate limiting
🔒 Detalles de Seguridad
API Key
- Formato: sk_live_ o sk_test_ seguido de 40 caracteres alfanuméricos
- Almacenamiento: Variables de entorno o gestores de secretos
- Scope: Cada API Key está asociada a un company_id específico
OTP
- Código de 6 dígitos numéricos
- Válido por 5 minutos desde el envío
- Solo puede usarse una vez (single-use)
- El session_id expira después de validar el código o transcurridos 10 minutos
- Máximo 5 intentos de validación por session_id
Rate Limiting
Los límites se aplican por:
- Número telefónico: 5 solicitudes cada 10 minutos
- Company ID: 100 solicitudes por hora
- API Key: 1000 solicitudes por día
📊 Códigos de País Soportados
| País | Código ISO | Formato de Ejemplo |
|---|---|---|
| México | MEX | +525512345678 |
| Colombia | COL | +573001234567 |
| Argentina | ARG | +541123456789 |
| Chile | CHL | +56912345678 |
| Perú | PER | +51987654321 |
| Brasil | BRA | +551198765432 |
🧪 Ambiente de Pruebas
Base URL de Testing: https://api-sandbox.jaak.mx
Números de prueba:
- +525500000001 - Siempre exitoso
📞 Soporte
¿Necesitas ayuda con la integración?
- Email: [email protected]
- Documentación: https://docs.jaak.mx
- Status: https://status.jaak.mx
- Horario: Lun-Vie 9:00-18:00 (GMT-6)
Información para tickets de soporte
- Request ID (si aplica)
- Timestamp del error
- Código de status HTTP
- Payload sanitizado (sin API keys ni datos sensibles)
- Logs relevantes
📋 Checklist de Integración
Antes de ir a producción:
- API Key de producción configurada
- Bearer Token incluido en todas las peticiones
- Validación de formato de número telefónico implementada
- Manejo de todos los códigos de error
- Retry logic para errores temporales
- Almacenamiento seguro del session_id
- Rate limiting implementado
- Mensajes de error claros
- Logging implementado
- Timeout de 5 minutos mostrado
- Pruebas en sandbox completadas
- Monitoreo configurado
Updated about 3 hours ago
