Webhooks outbound — eventos Tokia no seu backend
Configure URL HTTPS pra Tokia disparar HTTP POST quando eventos acontecem (saldo baixo, top-up confirmado, key suspensa). HMAC SHA-256.
Em vez de fazer polling em /usage toda hora, configure webhooks outbound:
Tokia faz HTTP POST pro seu endpoint sempre que evento importante acontece.
Eventos suportados (6 hoje)
| Evento | Quando dispara | Use case |
|---|---|---|
| balance.low | Saldo cruza threshold (default R$ 20). 1x/dia | Notifica Slack admin |
| balance.topped_up | PIX/cartão confirmado | Atualiza dashboard interno |
| key.created | Nova API key criada | Auditoria |
| key.suspended | Saldo zerou ou admin suspendeu | Avisa user / trocar pra key backup |
| payment.failed | Auto-topup falhou (cartão recusado) | Email user atualizar cartão |
| key.budget_warning | Key cruzou 80% do budget em 24h | Antecipa upgrade de plan |
Passo 1 — Cria endpoint no seu backend
Endpoint deve:
- Aceitar
POSTcom body JSON - Validar HMAC SHA-256 header (anti-spoofing)
- Responder 2xx em até 30s (Tokia desiste depois)
- Idempotente (retries acontecem em falha)
Exemplo Node.js / Express:
import express from "express";
import crypto from "node:crypto";
const SIGNING_SECRET = process.env.TOKIA_WEBHOOK_SECRET!;
app.post(
"/tokia-webhook",
express.raw({ type: "application/json" }),
(req, res) => {
const signature = req.header("tokia-signature-sha-256");
const expected = crypto
.createHmac("sha256", SIGNING_SECRET)
.update(req.body)
.digest("hex");
if (
!signature ||
signature.length !== expected.length ||
!crypto.timingSafeEqual(
Buffer.from(signature, "hex"),
Buffer.from(expected, "hex")
)
) {
return res.status(401).end();
}
const payload = JSON.parse(req.body.toString());
console.log(payload.event, payload.data);
// Faz alguma ação (notifica Slack, atualiza DB, etc)
res.status(200).end();
}
);
Equivalente Python / FastAPI:
import hmac, hashlib, os
from fastapi import FastAPI, Request, HTTPException
SIGNING_SECRET = os.environ["TOKIA_WEBHOOK_SECRET"].encode()
app = FastAPI()
@app.post("/tokia-webhook")
async def tokia_webhook(request: Request):
body = await request.body()
signature = request.headers.get("tokia-signature-sha-256", "")
expected = hmac.new(SIGNING_SECRET, body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(signature, expected):
raise HTTPException(401, "invalid signature")
payload = await request.json()
# ... handle payload.event ...
return {"ok": True}
Passo 2 — Cadastra webhook em /dashboard/webhooks

Clica "Cadastrar webhook":
- URL do seu endpoint: HTTPS (HTTP rejeita em prod). Ex:
https://api.minhasaas.com.br/tokia-webhook - Eventos: marca os que interessam (todos 6 default)
Clica "Criar webhook". Modal retorna signing_secret — copia agora,
aparece UMA vez. Guarda no .env do seu backend:
TOKIA_WEBHOOK_SECRET=ws_abc123...
Passo 3 — Teste com "Ping"
No card do webhook recém-criado, botão "Ping" dispara evento test
webhook.ping na hora. Seu backend recebe + você confere logs.
Pra teste rápido sem backend próprio, usa webhook.site:
- Abre
https://webhook.site, copia URL única - Cadastra essa URL em /dashboard/webhooks
- Clica "Ping"
- Vê o POST chegar na UI do webhook.site
Retry com backoff exponencial
Se seu endpoint retornar >=400 ou timeout, Tokia tenta de novo:
| Tentativa | Quando | |---|---| | 1 | imediato | | 2 | +1 minuto | | 3 | +5 minutos | | 4 | +30 minutos | | 5 | +4 horas | | ❌ Dead letter | após 5 falhas |
Eventos dead-letter aparecem em /dashboard/webhooks → card webhook → tab
"Tentativas" com status dead_letter. Você pode clicar "Reativar"
pra retentar manualmente.
Anatomia do payload
Todo evento tem essa estrutura:
{
"event": "balance.topped_up",
"delivery_id": "del_01HQ...",
"delivered_at": "2026-05-13T14:32:00Z",
"data": {
"amount_brl": 50.00,
"new_balance_brl": 87.50,
"method": "pix"
}
}
Headers HTTP do POST:
Content-Type: application/jsonUser-Agent: Tokia-Webhook/1.0tokia-signature-sha-256: <hex hmac>tokia-event: <event_name>tokia-delivery-id: <delivery_id>(idempotência)
Limites
- Máximo 5 webhooks ativos por conta Tokia
- 30s timeout por request
- 5 tentativas antes de dead letter
- HMAC SHA-256 obrigatório
- HTTPS only em produção
Webhook entrante (Asaas) é coisa diferente
Tokia também recebe webhooks (do Asaas, quando PIX confirma). Esse caminho é interno — você não precisa configurar nada, já vem pronto pra contas Tokia.
Próximo passo
Volta pro /docs pra ver guias técnicos mais profundos sobre cada API.