Referência

Webhooks

Comunique os resultados das verificações à Novauth para que os registos de sessão se mantenham exatos. Cada canal expõe um endpoint de webhook dedicado que o seu servidor chama depois de observar o resultado.

Como funciona

A Novauth não envia eventos por push para o seu servidor. Em vez disso, o seu backend observa o resultado da verificação (através do SDK móvel, da lógica da sua própria aplicação ou de uma consulta de estado) e depois faz POST do resultado para o endpoint de webhook do Connect Hub.

1
Iniciar
O seu servidor inicia uma verificação através da API do canal.
2
Ação do utilizador
O utilizador recebe o OTP e reage (chamada, SMS, mensagem na aplicação).
3
Observar o resultado
O seu SDK móvel ou a lógica da aplicação deteta o sucesso ou a falha.
4
Comunicar o resultado
O seu servidor faz POST de uuid + status para o endpoint de webhook.

Todos os endpoints de webhook requerem o mesmo cabeçalho x-api-key usado nos pedidos normais à API. Devolva HTTP 200 para confirmar.

Verify Call

Depois de o seu SDK móvel ler o ID de chamada recebido, comunique se os dígitos corresponderam ao autor da chamada esperado.

POST/api/v1/connect-hub/call/flash/webhook
uuidstring
UUID devolvido por POST /call/flash
status"Success" | "Failed" | "Incomplete" | "WrongNumber"
Resultado observado da chamada
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
Exemplo — 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

Assim que o seu servidor confirmar que o utilizador introduziu o código OTP correto, comunique o estado de entrega à Novauth.

POST/api/v1/connect-hub/sms/webhook
idstring
messageId devolvido por POST /sms
status"delivered" | "sent" | "failed" | "undelivered"
Estado de entrega do SMS a partir do DLR da operadora
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

Comunique o resultado da entrega do OTP do WhatsApp. Só há dois estados possíveis.

POST/api/v1/connect-hub/whatsapp/webhook
uuidstring
UUID devolvido por POST /whatsapp/otp
status"Success" | "Failed"
Resultado da entrega no 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 do Telegram

Comunique a entrega da mensagem do Telegram. Use POST /check-verification-status para a validação do código do lado do servidor — consulte o início rápido do OTP do Telegram para o fluxo completo.

POST/api/v1/connect-hub/telegram/webhook
idstring
UUID devolvido por POST /telegram
status"Success" | "Failed"
Resultado da entrega no 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"
  }'

Receção do Telegram Gateway

Quando passa um callback_url no seu pedido de envio do Telegram, o Gateway do Telegram fará POST dos eventos de estado da verificação diretamente para esse URL. Ao contrário dos outros canais, o recetor é você — e o Telegram assina cada pedido com HMAC-SHA256.

Cabeçalhos de assinatura
X-Request-TimestampSegundos de época Unix (inteiro). Rejeite se |agora − timestamp| > 300.
X-Request-SignatureHMAC-SHA256 codificado em hexadecimal. Verifique com comparação em tempo constante.
Algoritmo de assinatura: secret = SHA256(access_token) · data = "{timestamp}\n{rawBody}" · sig = HMAC-SHA256(secret, data)
Exemplo 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
Handler de verificação de assinatura
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 });
});

Faça sempre o parse do corpo depois da verificação da assinatura, e faça-o a partir do buffer de bytes original — não de um objeto JSON já processado. A re-serialização do JSON pode alterar a ordem dos bytes e quebrar o HMAC.