Salta ai contenuti

Webhooks

Webhooks

Con i webhook ricevi notifiche in tempo reale quando si verificano eventi nel tuo workspace, ad esempio quando viene scansionato un codice QR.

Creare un webhook

Terminal window
POST /v1/webhooks
{
"url": "https://example.com/webhooks/qr3",
"events": ["qr.scanned", "qr.created"],
"secret": "my-secret-key-min-16-chars"
}

Risposta

{
"id": "wh_abc123",
"url": "https://example.com/webhooks/qr3",
"events": ["qr.scanned", "qr.created"],
"is_active": true,
"secret": "my-secret-key-min-16-chars",
"secret_hint": "my-s…",
"created_at": "2026-03-15T10:00:00.000Z"
}

Tipi di evento

EventoDescrizione
*Tutti gli eventi
qr.createdCodice QR creato
qr.updatedCodice QR aggiornato (URL, stato, tag)
qr.deletedCodice QR eliminato
qr.scannedCodice QR scansionato
qr.flaggedCodice QR contrassegnato come non sicuro
scan.createdEvento di scansione (alias di qr.scanned)
workspace.updatedWorkspace aggiornato
webhook.pingPing di test (tramite l’endpoint /ping)

Formato del payload

Tutti i payload dei webhook hanno questo formato:

{
"id": "evt_abc123xyz",
"type": "qr.scanned",
"created": "2026-03-15T10:00:00.000Z",
"data": {
"code_id": "qr_abc123",
"short_code": "r7f3Kx",
"scan_id": "scn_xyz",
"country": "AT",
"device_type": "mobile",
"os": "iOS"
}
}

Verifica della firma

qr3.app firma ogni richiesta webhook con HMAC-SHA256:

X-QR3-Signature: sha256=a1b2c3d4e5f6...

Implementare la verifica

import crypto from "crypto";
function verifySignature(
payload: string,
signature: string,
secret: string
): boolean {
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
const received = signature.replace("sha256=", "");
return crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(received, "hex")
);
}
// In Express:
app.post("/webhooks/qr3", (req, res) => {
const signature = req.headers["x-qr3-signature"] as string;
const valid = verifySignature(
JSON.stringify(req.body),
signature,
process.env.QR3_WEBHOOK_SECRET
);
if (!valid) return res.status(401).json({ error: "Invalid signature" });
const event = req.body;
console.log(event.type, event.data);
res.json({ received: true });
});

Logica di retry

In caso di errori (HTTP >= 300 o timeout), qr3.app riprova a inviare la notifica:

TentativoRitardo
1Immediatamente
21 minuto
35 minuti

Dopo 10 errori consecutivi, il webhook viene disattivato automaticamente.

Log di consegna

Terminal window
GET /v1/webhooks/:id/deliveries
{
"data": [
{
"id": "whd_abc123",
"event_type": "qr.scanned",
"status": "success",
"status_code": 200,
"response_time_ms": 145,
"attempt": 1,
"created_at": "2026-03-15T10:00:00.000Z"
}
]
}

Ping di test

Testa immediatamente un webhook:

Terminal window
POST /v1/webhooks/:id/ping

Questo invia un evento webhook.ping all’URL del tuo endpoint.