Referencia

Webhooks

Reporta los resultados de verificación a Novauth para que los registros de sesión se mantengan actualizados. Cada canal expone un endpoint de webhook dedicado al que tu servidor llama después de observar el resultado.

Cómo funciona

Novauth no envía eventos a tu servidor. En cambio, tu backend observa el resultado de la verificación (a través del SDK móvil, tu propia lógica de aplicación o una encuesta de comprobación de estado) y luego envía el resultado al endpoint de webhook de Connect Hub mediante POST.

1
Iniciar
Tu servidor inicia una verificación a través de la API del canal.
2
Acción del usuario
El usuario recibe el OTP y actúa en consecuencia (llamada, SMS, mensaje de la aplicación).
3
Observar resultado
Tu SDK móvil o la lógica de tu aplicación detecta el éxito o el fallo.
4
Reportar resultado
Tu servidor envía uuid + estado al endpoint de webhook mediante POST.

Todos los endpoints de webhook requieren el mismo encabezado x-api-key utilizado para las solicitudes de API habituales. Devuelve HTTP 200 para confirmar la recepción.

Verify Call

Después de que tu SDK móvil lea el ID de llamada entrante, reporta si los dígitos coincidieron con el llamante esperado.

POST/api/v1/connect-hub/call/flash/webhook
uuidstring
UUID devuelto por POST /call/flash
status"Success" | "Failed" | "Incomplete" | "WrongNumber"
Resultado observado de la llamada
Payload
json
{
  "uuid": "01J8K2M3N4P5Q6R7S8T9U0V1W2",
  "status": "Success"
}

// Possible status values:
// "Success"      — caller ID matched, user verified
// "Failed"       — call was not answered or no match
// "Incomplete"   — call dropped before matching
// "WrongNumber"  — mismatch detected
Ejemplo — enviar resultado
bash
# After initiating a flash call, POST the result back to Novauth:
curl -X POST https://api.novauth.com/api/v1/connect-hub/call/flash/webhook \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "uuid": "01J8K2M3N4P5Q6R7S8T9U0V1W2",
    "status": "Success"
  }'

SMS

Una vez que tu servidor confirma que el usuario introdujo el código OTP correcto, reporta el estado de entrega de vuelta a Novauth.

POST/api/v1/connect-hub/sms/webhook
idstring
messageId devuelto por POST /sms
status"delivered" | "sent" | "failed" | "undelivered"
Estado de entrega del SMS según el DLR del operador
Payload
json
{
  "id": "msg_01J8K2M3N4P5Q6R7S8T9",
  "status": "delivered"
}

// Possible status values (from carrier):
// "delivered"    — confirmed delivery to handset
// "sent"         — dispatched to carrier, awaiting DLR
// "failed"       — delivery failed (invalid number, blocked, etc.)
// "undelivered"  — carrier accepted but delivery not confirmed
bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/sms/webhook \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "msg_01J8K2M3N4P5Q6R7S8T9",
    "status": "delivered"
  }'

WhatsApp

Reporta el resultado de entrega del OTP de WhatsApp. Solo son posibles dos estados.

POST/api/v1/connect-hub/whatsapp/webhook
uuidstring
UUID devuelto por POST /whatsapp/otp
status"Success" | "Failed"
Resultado de entrega de WhatsApp
json
{
  "uuid": "01J8K2M3N4P5Q6R7S8T9U0V1W2",
  "status": "Success"
}

// Only two status values:
// "Success"  — WhatsApp OTP delivered to user
// "Failed"   — delivery failed (user not on WhatsApp, etc.)
bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/whatsapp/webhook \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "uuid": "01J8K2M3N4P5Q6R7S8T9U0V1W2",
    "status": "Success"
  }'

OTP de Telegram

Reporta la entrega del mensaje de Telegram. Usa POST /check-verification-status para la validación del código del lado del servidor; consulta el inicio rápido de OTP de Telegram para el flujo completo.

POST/api/v1/connect-hub/telegram/webhook
idstring
UUID devuelto por POST /telegram
status"Success" | "Failed"
Resultado de entrega de Telegram
json
{
  "id": "01J8K2M3N4P5Q6R7S8T9U0V1W2",
  "status": "Success"
}

// Only two status values:
// "Success"  — Telegram message delivered
// "Failed"   — delivery failed (user blocked bot, etc.)
bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/telegram/webhook \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "01J8K2M3N4P5Q6R7S8T9U0V1W2",
    "status": "Success"
  }'

Entrada de Telegram Gateway

Cuando pasas un callback_url en tu solicitud de envío de Telegram, Telegram Gateway enviará eventos de estado de verificación directamente a esa URL mediante POST. A diferencia de los otros canales, eres el receptor, y Telegram firma cada solicitud con HMAC-SHA256.

Encabezados de firma
X-Request-TimestampSegundos de época Unix (entero). Rechaza si |ahora − timestamp| > 300.
X-Request-SignatureHMAC-SHA256 codificado en hexadecimal. Verifica con comparación de tiempo constante.
Algoritmo de firma: secret = SHA256(access_token) · data = "{timestamp}\n{rawBody}" · sig = HMAC-SHA256(secret, data)
Ejemplo de payload de evento
json
// Telegram Gateway sends status updates to your callback_url
// when you provided it in the original send request.
// Payload (example):
{
  "request_id": "tg_req_abc123",
  "phone_number": "+14155552671",
  "status": "code_valid",
  "verification_status": {
    "status": "code_valid",
    "updated_at": 1713350400
  }
}

// status values:
// "code_valid"                  — user entered correct code
// "code_invalid"                — wrong code entered
// "code_max_attempts_exceeded"  — too many attempts
// "expired"                     — TTL elapsed before entry
Manejador de verificación de firma
javascript
import { createHmac, timingSafeEqual } from 'node:crypto';

app.post('/telegram/gateway-callback', express.raw({ type: '*/*' }), (req, res) => {
  const timestamp = req.headers['x-request-timestamp'];
  const signature = req.headers['x-request-signature'];
  const rawBody   = req.body;            // must be raw Buffer

  // 1. Replay-attack guard — reject requests older than 5 minutes
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
    return res.status(401).json({ error: 'Request expired' });
  }

  // 2. Derive signing secret: SHA256 of your Telegram Gateway access token
  const secret = createHmac('sha256', '')
    .update(process.env.TELEGRAM_GATEWAY_TOKEN)
    .digest();

  // 3. Compute expected signature
  const data     = `${timestamp}\n${rawBody}`;
  const expected = createHmac('sha256', secret).update(data).digest('hex');

  // 4. Timing-safe comparison
  const sigBuf = Buffer.from(signature ?? '', 'hex');
  const expBuf = Buffer.from(expected, 'hex');

  if (sigBuf.length !== expBuf.length || !timingSafeEqual(sigBuf, expBuf)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const payload = JSON.parse(rawBody.toString());
  console.log('Telegram Gateway event:', payload.status);

  res.status(200).json({ ok: true });
});

Analiza siempre el cuerpo después de verificar la firma, y hazlo desde el búfer de bytes en bruto, no desde un objeto JSON ya analizado. La re-serialización de JSON puede alterar el orden de los bytes y romper el HMAC.