Inicio Precios Funcionalidades Reseñas NEW Developers

Enviar OTP — Verificacion por SMS y WhatsApp

Genera y envia codigos de verificacion OTP de 6 digitos con expiracion configurable.

Como funciona

El sistema OTP (One-Time Password) de WhatsBoost genera codigos de verificacion aleatorios de 6 digitos que puedes enviar a tus usuarios por SMS o WhatsApp. Es la solucion ideal para verificar numeros de telefono, autenticacion en dos pasos (2FA) y confirmaciones de identidad.

Flujo interno del sistema OTP
1
Generacion del codigo

La API genera un numero aleatorio de 6 digitos entre 100000 y 999999, criptograficamente seguro.

2
Almacenamiento temporal

El codigo se almacena en cache con un TTL configurable (por defecto 300 segundos = 5 minutos). Cada API Key tiene su propio namespace de cache.

3
Sustitucion de variable

La variable {{otp}} dentro de tu plantilla de mensaje se reemplaza automaticamente por el codigo generado.

4
Envio del mensaje

El mensaje con el codigo se envia por SMS o WhatsApp segun el parametro type que indiques.

5
Respuesta con OTP

La API devuelve el codigo OTP en el campo data.otp de la respuesta, para que tu servidor pueda almacenarlo y verificarlo posteriormente.

6
Verificacion en tu app

El usuario recibe el codigo e introduce en tu app. Tu servidor compara el codigo recibido con el almacenado. Si coinciden y no ha expirado, la verificacion es exitosa.


Enviar OTP

POST /api/send/otp

Genera un codigo OTP de 6 digitos y lo envia al destinatario por SMS o WhatsApp. El codigo generado se devuelve en la respuesta para que puedas almacenarlo en tu servidor y verificarlo posteriormente.

Parametros generales
ParametroTipoEstadoDescripcion
secret string Obligatorio Tu API Key. Obtenla en Dashboard > API Keys.
type string Obligatorio Canal de envio: "sms" o "whatsapp".
message string Obligatorio Plantilla del mensaje. Debe contener la variable {{otp}} que sera reemplazada por el codigo de 6 digitos generado. Ejemplo: Tu codigo de verificacion es: {{otp}}
phone string Obligatorio Numero de telefono del destinatario en formato E.164 (ej: +34612345678).
expire integer Opcional Tiempo de vida del codigo en segundos. Valor por defecto: 300 (5 minutos). Valor minimo: 1. El codigo expira automaticamente pasado este tiempo.

Parametros adicionales cuando type="sms"

Si envias el OTP por SMS, debes indicar los mismos parametros de envio que en el endpoint Enviar SMS:

ParametroTipoEstadoDescripcion
mode string Obligatorio Modo de envio: "devices" (dispositivo Android) o "credits" (pasarela SMS).
device string Condicional ID del dispositivo Android. Obligatorio si mode="devices".
gateway integer|string Condicional ID de la pasarela SMS. Obligatorio si mode="credits".
sim integer Opcional Ranura SIM: 1 o 2. Valor por defecto: 1. Solo aplica si mode="devices".

Parametros adicionales cuando type="whatsapp"

Si envias el OTP por WhatsApp, necesitas los parametros especificos del canal de WhatsApp:

ParametroTipoEstadoDescripcion
account string Obligatorio Identificador unico de la cuenta de WhatsApp vinculada. Obtenlo desde el Dashboard o via GET /api/get/wa.accounts.
priority integer Opcional Prioridad de envio: 1 = alta (inmediato), 2 = normal (cola). Se recomienda 1 para OTP ya que la entrega debe ser inmediata.

Respuesta

Cuando el OTP se genera y envia correctamente, la API devuelve un codigo 200 con toda la informacion necesaria para la verificacion:

{
  "status": 200,
  "message": "OTP has been sent!",
  "data": {
    "phone": "+34612345678",
    "message": "Tu codigo de verificacion WhatsBoost es: 847291. Expira en 5 minutos.",
    "messageId": 49123,
    "otp": 847291
  }
}
Campos de respuesta
CampoTipoDescripcion
status integer Codigo HTTP de estado. 200 indica exito.
message string Mensaje descriptivo del resultado.
data.phone string Numero de telefono al que se envio el OTP.
data.message string Texto completo del mensaje enviado, con la variable {{otp}} ya reemplazada.
data.messageId integer ID interno del mensaje en el sistema de WhatsBoost.
data.otp integer El codigo OTP de 6 digitos generado. Almacena este valor en tu servidor (sesion, base de datos o Redis) para compararlo con el codigo que introduzca el usuario.
Respuesta con error
{
  "status": 400,
  "message": "OTP message must contain {{otp}} variable!",
  "data": false
}

Flujo completo de verificacion

A continuacion se describe paso a paso como implementar un flujo de verificacion OTP completo en tu aplicacion, desde la solicitud del usuario hasta la confirmacion final.

1
El usuario solicita verificacion

El usuario introduce su numero de telefono en tu formulario de registro, login con 2FA, o cualquier flujo que requiera verificacion de identidad. Tu aplicacion frontend envia el numero al backend.

2
Tu servidor llama a POST /api/send/otp

Tu backend realiza la llamada a la API de WhatsBoost con el numero del usuario, la plantilla del mensaje (incluyendo {{otp}}), el canal de envio (SMS o WhatsApp) y el tiempo de expiracion deseado.

3
WhatsBoost genera el OTP, envia el mensaje y responde

El sistema genera un codigo aleatorio de 6 digitos, lo almacena en cache con el TTL indicado, reemplaza {{otp}} en tu mensaje y lo envia. La respuesta incluye el codigo OTP en data.otp.

4
Tu servidor almacena el OTP

Guarda el valor de data.otp en la sesion del usuario, base de datos o cache (Redis/Memcached) junto con el timestamp de expiracion. Nunca expongas el OTP al frontend.

5
El usuario recibe el mensaje con el codigo

El usuario recibe el SMS o WhatsApp con su codigo de 6 digitos. Ejemplo: «Tu codigo de verificacion es: 847291. Expira en 5 minutos.»

6
El usuario introduce el codigo en tu app

Tu frontend muestra un campo de entrada donde el usuario escribe los 6 digitos. El codigo se envia a tu backend para la validacion.

7
Tu servidor compara los codigos

Compara el codigo introducido por el usuario con el OTP almacenado en el paso 4. Verifica tambien que no haya expirado (comprueba el timestamp).

8
Resultado de la verificacion

Si los codigos coinciden y el OTP no ha expirado, la verificacion es exitosa. Marca el telefono como verificado y continua con el flujo de tu aplicacion. Si no coinciden o ha expirado, muestra un error y permite al usuario solicitar un nuevo codigo.


Ejemplos de codigo

Implementacion completa del flujo de envio y verificacion de OTP en 4 lenguajes. Cada ejemplo incluye tanto el envio del codigo como la logica de verificacion.

Enviar codigo OTP

# Enviar OTP por WhatsApp (recomendado para mayor entrega)
curl -X POST //whatsboost.netapi/send/otp \
  -d "secret=TU_API_KEY" \
  -d "type=whatsapp" \
  -d "phone=+34612345678" \
  -d "account=WA_ACCOUNT_UNIQUE" \
  -d "priority=1" \
  -d "expire=300" \
  -d "message=Tu codigo de verificacion WhatsBoost es: {{otp}}. Expira en 5 minutos. No compartas este codigo."

# Enviar OTP por SMS (pasarela)
curl -X POST //whatsboost.netapi/send/otp \
  -d "secret=TU_API_KEY" \
  -d "type=sms" \
  -d "phone=+34612345678" \
  -d "mode=credits" \
  -d "gateway=1" \
  -d "expire=300" \
  -d "message=Tu codigo es: {{otp}}. Valido por 5 min."

# Enviar OTP por SMS (dispositivo Android)
curl -X POST //whatsboost.netapi/send/otp \
  -d "secret=TU_API_KEY" \
  -d "type=sms" \
  -d "phone=+34612345678" \
  -d "mode=devices" \
  -d "device=DEVICE_ID" \
  -d "sim=1" \
  -d "expire=600" \
  -d "message=Codigo de acceso: {{otp}}. Expira en 10 minutos."
<?php
/**
 * Enviar OTP por WhatsApp o SMS
 * Requiere: PHP 7.4+ con cURL
 */

function enviarOTP(
    string $telefono,
    string $canal = "whatsapp",
    int $expiracion = 300
): array {
    $params = [
        "secret"  => "TU_API_KEY",
        "type"    => $canal,
        "phone"   => $telefono,
        "expire"  => $expiracion,
        "message" => "Tu codigo de verificacion es: {{otp}}. Expira en " . ($expiracion / 60) . " minutos. No compartas este codigo."
    ];

    // Parametros adicionales segun el canal
    if ($canal === "whatsapp") {
        $params["account"]  = "WA_ACCOUNT_UNIQUE";
        $params["priority"] = 1; // Inmediato para OTP
    } elseif ($canal === "sms") {
        $params["mode"]    = "credits";
        $params["gateway"] = "1";
    }

    $ch = curl_init("//whatsboost.netapi/send/otp");
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_POSTFIELDS     => $params
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $result = json_decode($response, true);

    if ($result["status"] === 200) {
        // Almacenar OTP en sesion para verificacion posterior
        $_SESSION["otp_code"]    = $result["data"]["otp"];
        $_SESSION["otp_phone"]   = $telefono;
        $_SESSION["otp_expires"] = time() + $expiracion;

        echo "OTP enviado al $telefono. Codigo: " . $result["data"]["otp"] . PHP_EOL;
    } else {
        echo "Error enviando OTP: " . $result["message"] . PHP_EOL;
    }

    return $result;
}

// Uso: enviar OTP por WhatsApp
$resultado = enviarOTP("+34612345678", "whatsapp", 300);

// Uso: enviar OTP por SMS
$resultado = enviarOTP("+34612345678", "sms", 600);
/**
 * Enviar OTP por WhatsApp o SMS
 * Compatible con Node.js y navegador (server-side recomendado)
 */

// Almacen temporal de OTPs (en produccion usa Redis o base de datos)
const otpStore = new Map();

async function enviarOTP(telefono, canal = "whatsapp", expiracion = 300) {
  const params = {
    secret: "TU_API_KEY",
    type: canal,
    phone: telefono,
    expire: expiracion.toString(),
    message: `Tu codigo de verificacion es: {{otp}}. Expira en ${ Math.floor(expiracion / 60) } minutos.`
  };

  // Parametros adicionales segun el canal
  if (canal === "whatsapp") {
    params.account = "WA_ACCOUNT_UNIQUE";
    params.priority = "1";
  } else if (canal === "sms") {
    params.mode = "credits";
    params.gateway = "1";
  }

  const response = await fetch("//whatsboost.netapi/send/otp", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams(params)
  });

  const data = await response.json();

  if (data.status === 200) {
    // Almacenar OTP para verificacion posterior
    otpStore.set(telefono, {
      code: data.data.otp,
      expiresAt: Date.now() + (expiracion * 1000)
    });

    console.log(`OTP enviado al ${ telefono }. Codigo: ${ data.data.otp }`);
  } else {
    console.error(`Error enviando OTP: ${ data.message }`);
  }

  return data;
}

// Uso
await enviarOTP("+34612345678", "whatsapp", 300);
await enviarOTP("+34612345678", "sms", 600);
import requests
import time

# Almacen temporal de OTPs (en produccion usa Redis o base de datos)
otp_store = {}

def enviar_otp(telefono: str, canal: str = "whatsapp", expiracion: int = 300) -> dict:
    """
    Enviar OTP por WhatsApp o SMS.
    Requiere: pip install requests
    """
    params = {
        "secret": "TU_API_KEY",
        "type": canal,
        "phone": telefono,
        "expire": expiracion,
        "message": f"Tu codigo de verificacion es: {{otp}}. Expira en {expiracion // 60} minutos."
    }

    # Parametros adicionales segun el canal
    if canal == "whatsapp":
        params["account"] = "WA_ACCOUNT_UNIQUE"
        params["priority"] = 1  # Inmediato para OTP
    elif canal == "sms":
        params["mode"] = "credits"
        params["gateway"] = "1"

    response = requests.post(
        "//whatsboost.netapi/send/otp",
        data=params,
        timeout=30
    )

    result = response.json()

    if result["status"] == 200:
        # Almacenar OTP para verificacion posterior
        otp_store[telefono] = {
            "code": result["data"]["otp"],
            "expires_at": time.time() + expiracion
        }
        print(f"OTP enviado al {telefono}. Codigo: {result['data']['otp']}")
    else:
        print(f"Error enviando OTP: {result['message']}")

    return result


# Uso: OTP por WhatsApp
resultado = enviar_otp("+34612345678", "whatsapp", 300)

# Uso: OTP por SMS
resultado = enviar_otp("+34612345678", "sms", 600)

Verificar codigo OTP

Una vez enviado el OTP, necesitas verificar el codigo que el usuario introduce en tu aplicacion. Esta logica se ejecuta completamente en tu servidor — no requiere ninguna llamada adicional a la API de WhatsBoost.

<?php
/**
 * Verificar codigo OTP introducido por el usuario
 */

function verificarOTP(string $telefono, int $codigoUsuario): array
{
    // Verificar que existe un OTP pendiente para este telefono
    if (!isset($_SESSION["otp_code"]) || $_SESSION["otp_phone"] !== $telefono) {
        return [
            "success" => false,
            "error"   => "No se encontro un codigo OTP pendiente para este numero."
        ];
    }

    // Verificar que el OTP no ha expirado
    if (time() > $_SESSION["otp_expires"]) {
        // Limpiar OTP expirado
        unset($_SESSION["otp_code"], $_SESSION["otp_phone"], $_SESSION["otp_expires"]);

        return [
            "success" => false,
            "error"   => "El codigo OTP ha expirado. Solicita uno nuevo."
        ];
    }

    // Comparar codigos (comparacion estricta)
    if ((int) $codigoUsuario !== (int) $_SESSION["otp_code"]) {
        // Incrementar contador de intentos fallidos
        $_SESSION["otp_attempts"] = ($_SESSION["otp_attempts"] ?? 0) + 1;

        // Bloquear tras 5 intentos fallidos
        if ($_SESSION["otp_attempts"] >= 5) {
            unset($_SESSION["otp_code"], $_SESSION["otp_phone"], $_SESSION["otp_expires"]);
            return [
                "success" => false,
                "error"   => "Demasiados intentos fallidos. Solicita un nuevo codigo."
            ];
        }

        return [
            "success"           => false,
            "error"             => "Codigo incorrecto.",
            "attempts_remaining" => 5 - $_SESSION["otp_attempts"]
        ];
    }

    // Verificacion exitosa: limpiar sesion
    unset($_SESSION["otp_code"], $_SESSION["otp_phone"], $_SESSION["otp_expires"], $_SESSION["otp_attempts"]);

    return [
        "success" => true,
        "message" => "Telefono verificado correctamente."
    ];
}

// Uso: verificar el codigo que el usuario introdujo
$resultado = verificarOTP("+34612345678", 847291);

if ($resultado["success"]) {
    echo "Verificacion exitosa!";
    // Continuar con el flujo: registro, login, etc.
} else {
    echo "Error: " . $resultado["error"];
}
/**
 * Verificar codigo OTP introducido por el usuario
 * Utiliza el otpStore definido en el ejemplo de envio
 */

function verificarOTP(telefono, codigoUsuario) {
  const otpData = otpStore.get(telefono);

  // Verificar que existe un OTP pendiente
  if (!otpData) {
    return {
      success: false,
      error: "No se encontro un codigo OTP pendiente para este numero."
    };
  }

  // Verificar que no ha expirado
  if (Date.now() > otpData.expiresAt) {
    otpStore.delete(telefono);
    return {
      success: false,
      error: "El codigo OTP ha expirado. Solicita uno nuevo."
    };
  }

  // Incrementar intentos
  otpData.attempts = (otpData.attempts || 0) + 1;

  // Bloquear tras 5 intentos fallidos
  if (otpData.attempts > 5) {
    otpStore.delete(telefono);
    return {
      success: false,
      error: "Demasiados intentos fallidos. Solicita un nuevo codigo."
    };
  }

  // Comparar codigos
  if (parseInt(codigoUsuario) !== otpData.code) {
    return {
      success: false,
      error: "Codigo incorrecto.",
      attemptsRemaining: 5 - otpData.attempts
    };
  }

  // Verificacion exitosa: limpiar datos
  otpStore.delete(telefono);

  return {
    success: true,
    message: "Telefono verificado correctamente."
  };
}

// Uso: verificar el codigo
const resultado = verificarOTP("+34612345678", 847291);

if (resultado.success) {
  console.log("Verificacion exitosa!");
  // Continuar con el flujo
} else {
  console.error("Error:", resultado.error);
}
import time

def verificar_otp(telefono: str, codigo_usuario: int) -> dict:
    """
    Verificar codigo OTP introducido por el usuario.
    Utiliza el otp_store definido en el ejemplo de envio.
    """
    # Verificar que existe un OTP pendiente
    if telefono not in otp_store:
        return {
            "success": False,
            "error": "No se encontro un codigo OTP pendiente para este numero."
        }

    otp_data = otp_store[telefono]

    # Verificar que no ha expirado
    if time.time() > otp_data["expires_at"]:
        del otp_store[telefono]
        return {
            "success": False,
            "error": "El codigo OTP ha expirado. Solicita uno nuevo."
        }

    # Incrementar intentos
    otp_data["attempts"] = otp_data.get("attempts", 0) + 1

    # Bloquear tras 5 intentos fallidos
    if otp_data["attempts"] > 5:
        del otp_store[telefono]
        return {
            "success": False,
            "error": "Demasiados intentos fallidos. Solicita un nuevo codigo."
        }

    # Comparar codigos
    if int(codigo_usuario) != otp_data["code"]:
        return {
            "success": False,
            "error": "Codigo incorrecto.",
            "attempts_remaining": 5 - otp_data["attempts"]
        }

    # Verificacion exitosa: limpiar datos
    del otp_store[telefono]

    return {
        "success": True,
        "message": "Telefono verificado correctamente."
    }


# Uso: verificar el codigo
resultado = verificar_otp("+34612345678", 847291)

if resultado["success"]:
    print("Verificacion exitosa!")
    # Continuar con el flujo: registro, login, etc.
else:
    print(f"Error: {resultado['error']}")

Seguridad OTP — Buenas practicas

Implementar correctamente la verificacion OTP requiere seguir buenas practicas de seguridad para evitar abusos, ataques de fuerza bruta y exposicion de codigos sensibles.

Limitar intentos de verificacion

Permite un maximo de 3 a 5 intentos de verificacion por cada OTP generado. Tras agotar los intentos, invalida el codigo y obliga al usuario a solicitar uno nuevo. Esto previene ataques de fuerza bruta.

No reenviar el mismo OTP

Cuando el usuario solicita un reenvio, genera siempre un codigo nuevo. Nunca reenvies el mismo codigo anterior. Invalida el codigo previo antes de generar el nuevo para evitar que ambos sean validos simultaneamente.

Expiracion razonable

Usa un tiempo de expiracion de 300 a 600 segundos (5 a 10 minutos). Tiempos mas largos aumentan la ventana de ataque. Tiempos mas cortos pueden frustar a usuarios lentos. Para operaciones criticas (transferencias), usa 120 segundos.

No exponer en cliente

El codigo OTP nunca debe aparecer en el frontend, en logs de consola del navegador, en URLs ni en respuestas de API publicas. Toda la logica de almacenamiento y comparacion debe ejecutarse exclusivamente en el servidor.

Rate limiting por telefono

Implementa un limite de 3 a 5 solicitudes OTP por numero cada 15 minutos. Esto previene el abuso del servicio (SMS bombing) y reduce costes. Usa un cooldown de 60 segundos entre reenvios.

Registrar intentos fallidos

Registra (log) cada intento de verificacion fallido con la IP del cliente, el timestamp y el numero de telefono. Esto facilita la deteccion de patrones sospechosos y posibles ataques. Considera bloquear IPs con mas de 10 intentos fallidos en una hora.


Prompt para IA — Verificacion OTP

Copia este prompt en ChatGPT, Claude, Gemini o cualquier asistente de IA para que genere integraciones de verificacion OTP con la API de WhatsBoost de forma autonoma.

Eres un desarrollador backend experto en autenticacion y verificacion.
Tienes acceso a la API de WhatsBoost para enviar codigos OTP.

ENDPOINT: POST //whatsboost.netapi/send/otp
AUTH: Parametro "secret" con la API Key

PARAMETROS GENERALES:
- secret (obligatorio): API Key
- type (obligatorio): "sms" o "whatsapp"
- phone (obligatorio): numero E.164 (+34612345678)
- message (obligatorio): texto con variable {{otp}}
- expire (opcional): segundos de vida, default 300

SI type="sms":
- mode: "devices" o "credits"
- device: ID dispositivo (si mode=devices)
- gateway: ID pasarela (si mode=credits)
- sim: 1 o 2 (opcional, default 1)

SI type="whatsapp":
- account: unique ID de cuenta WA vinculada
- priority: 1 (inmediato, recomendado para OTP) o 2 (cola)

RESPUESTA EXITOSA:
{"status": 200, "data": {"phone": "...", "messageId": 123, "otp": 847291}}

El campo data.otp contiene el codigo de 6 digitos generado.
Almacenalo en tu servidor y comparalo con el que introduzca el usuario.

SEGURIDAD:
- Limitar 3-5 intentos de verificacion por codigo
- No reenviar mismo codigo, generar nuevo
- Expiracion 300-600 segundos
- No exponer OTP en frontend
- Rate limit: 3-5 OTPs por telefono cada 15 min

Genera codigo limpio, con manejo de errores y comentarios en espanol.
Incluye tanto el envio como la verificacion del OTP.