Webhooks
Recevez des notifications en temps reel pour les événements Adlibo. Integrez avec vos outils internes, Slack, ou tout autre service.
Fonctionnalites Cles
10 Types d'Evenements
Détections, DLP, auth, billing, et plus.
Signatures HMAC-SHA256
Vérifiez l'authenticite de chaque webhook.
Retry Automatique
5 tentatives avec backoff exponentiel.
Delivery Logs
Historique complet des delivrances.
Creer un Webhook
Via Dashboard
Dashboard → Settings → Webhooks → Add Webhook
Via API
// POST /api/webhooks
{
"url": "https://your-server.com/webhooks/adlibo",
"events": [
"détection.created",
"détection.high_severity",
"dlp.violation",
"api_key.created",
"api_key.revoked"
],
"secret": "whsec_your_secret_key", // Optionnel - génère si non fourni
"enabled": true,
"metadata": {
"environment": "production",
"team": "security"
}
}
// Response
{
"id": "wh_abc123",
"url": "https://your-server.com/webhooks/adlibo",
"events": ["détection.created", "détection.high_severity", "dlp.violation", ...],
"secret": "whsec_abc123def456...",
"enabled": true,
"createdAt": "2026-01-02T10:00:00Z"
}Types d'Evenements
| Événement | Description | Plan |
|---|---|---|
| détection.created | Nouvelle détection de prompt injection | All |
| détection.high_severity | Détection HIGH ou CRITICAL | All |
| dlp.violation | Donnee sensible détectée | PRO+ |
| dlp.blocked | Requete bloquée par DLP | PRO+ |
| api_key.created | Nouvelle cle API créée | All |
| api_key.revoked | Cle API révoquée | All |
| quota.warning | Quota proche de la limité (80%) | All |
| quota.exceeded | Quota depasse | All |
| user.joined | Nouvel utilisateur dans l'organisation | PRO+ |
| user.removed | Utilisateur retire de l'organisation | PRO+ |
Format du Payload
// Exemple: détection.high_severity
{
"id": "evt_xyz789",
"type": "détection.high_severity",
"created": "2026-01-02T12:00:00Z",
"data": {
"id": "det_abc123",
"riskScore": 92,
"severity": "CRITICAL",
"category": "DAN_JAILBREAK",
"patterns": [
{
"type": "DAN_JAILBREAK",
"match": "you are now DAN",
"score": 90
}
],
"action": "BLOCKED",
"blocked": true,
"inputLength": 245,
"inputPreview": "From now on, you are going to act as DAN...",
"endpoint": "/api/chat",
"sourceIp": "192.168.1.100",
"userId": "usr_123",
"apiKeyId": "key_456",
"processingTimeMs": 3
},
"organization": {
"id": "org_abc",
"name": "Acme Corp"
}
}Exemple: dlp.violation
{
"id": "evt_dlp123",
"type": "dlp.violation",
"created": "2026-01-02T12:05:00Z",
"data": {
"domain": "FINANCIAL",
"type": "CREDIT_CARD",
"severity": "CRITICAL",
"action": "REDACTED",
"findingsCount": 2,
"redactedPreview": "Mon numéro de carte est 4532-****-****-9012",
"sourceIp": "10.0.0.50",
"userId": "usr_789"
}
}Vérification des Signatures
Chaque webhook inclut un header X-Adlibo-Signature pour vérifier son authenticite.
Headers
X-Adlibo-Signature: sha256=abc123def456...
X-Adlibo-Timestamp: 1735819200
X-Adlibo-Event-Id: evt_xyz789
X-Adlibo-Event-Type: détection.high_severityJavaScript/Node.js
import crypto from 'crypto';
function verifyWebhookSignature(payload, signature, timestamp, secret) {
// Vérifier que le timestamp n'est pas trop vieux (5 min)
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - parseInt(timestamp)) > 300) {
throw new Error('Timestamp too old');
}
// Calculer la signature attendue
const signedPayload = `${timestamp}.${JSON.stringify(payload)}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
// Comparer les signatures
const receivedSig = signature.replace('sha256=', '');
if (!crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(receivedSig)
)) {
throw new Error('Invalid signature');
}
return true;
}
// Usage dans Express
app.post('/webhooks/adlibo', express.json(), (req, res) => {
try {
verifyWebhookSignature(
req.body,
req.headers['x-adlibo-signature'],
req.headers['x-adlibo-timestamp'],
process.env.ADLIBO_WEBHOOK_SECRET
);
// Traiter l'événement
const event = req.body;
switch (event.type) {
case 'détection.high_severity':
handleHighSeverityDetection(event.data);
break;
case 'dlp.violation':
handleDlpViolation(event.data);
break;
}
res.status(200).send('OK');
} catch (err) {
res.status(401).send('Invalid signature');
}
});Python
import hmac
import hashlib
import time
def verify_webhook_signature(payload, signature, timestamp, secret):
# Vérifier le timestamp
now = int(time.time())
if abs(now - int(timestamp)) > 300:
raise ValueError("Timestamp too old")
# Calculer la signature
signed_payload = f"{timestamp}.{payload}"
expected_sig = hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
# Comparer
received_sig = signature.replace("sha256=", "")
if not hmac.compare_digest(expected_sig, received_sig):
raise ValueError("Invalid signature")
return True
# Flask example
@app.route('/webhooks/adlibo', methods=['POST'])
def handle_webhook():
try:
verify_webhook_signature(
request.data.decode(),
request.headers.get('X-Adlibo-Signature'),
request.headers.get('X-Adlibo-Timestamp'),
os.environ['ADLIBO_WEBHOOK_SECRET']
)
event = request.json
# Process event...
return 'OK', 200
except ValueError as e:
return str(e), 401Politique de Retry
Si votre endpoint retourne un code d'erreur (non-2xx), Adlibo reessaie automatiquement avec backoff exponentiel.
| Tentative | Délai |
|---|---|
| 1 | Immediat |
| 2 | 1 seconde |
| 3 | 5 secondes |
| 4 | 30 secondes |
| 5 | 2 minutes |
Timeout
Votre endpoint doit répondre en moins de 10 secondes. Au-dela, la requete est consideree comme echouee.
Tester vos Webhooks
// POST /api/webhooks/{webhook_id}/test
{
"eventType": "détection.high_severity"
}
// Envoie un événement de test a votre endpoint
// Response
{
"success": true,
"deliveryId": "del_xyz123",
"responseCode": 200,
"responseTimeMs": 145
}Logs de Delivrance
// GET /api/webhooks/{webhook_id}/deliveries
{
"deliveries": [
{
"id": "del_abc123",
"eventId": "evt_xyz789",
"eventType": "détection.high_severity",
"status": "delivered",
"responseCode": 200,
"responseTimeMs": 89,
"attempts": 1,
"deliveredAt": "2026-01-02T12:00:00Z"
},
{
"id": "del_def456",
"eventId": "evt_abc123",
"eventType": "dlp.violation",
"status": "failed",
"responseCode": 500,
"attempts": 5,
"lastAttemptAt": "2026-01-02T12:05:00Z",
"nextRetryAt": null,
"error": "Internal Server Error"
}
],
"pagination": {
"total": 1247,
"page": 1,
"perPage": 20
}
}Bonnes Pratiques
Toujours vérifier la signature
Ne traitez jamais un webhook sans avoir vérifié sa signature pour éviter les attaques par injection.
Répondre rapidement (200 OK)
Retournez un 200 OK immédiatement, puis traitez l'événement en arriere-plan si nécessaire.
Gérer l'idempotence
Utilisez le X-Adlibo-Event-Id pour éviter de traiter le meme événement deux fois.
Documentation Associee
Besoin d'aide ?
Notre équipe peut vous aider a configurer vos webhooks.