Documentation
WebhookLens est une plateforme d'infrastructure webhook open source. Recevez, inspectez, rejouez et transmettez des webhooks avec une visibilité totale. Auto-hébergez gratuitement ou utilisez le cloud géré.
-
Démarrez la stack
docker compose up -d— lance PostgreSQL, ClickHouse, Redis et WebhookLens. -
Ouvrez le tableau de bord
Accédez àhttp://localhost:3000. Inscrivez-vous pour créer votre tenant. -
Créez un endpoint et envoyez un webhook de test
Créez un endpoint dans le tableau de bord, puis :curl -X POST http://localhost:8080/wh/your-tenant/your-endpoint -H "Content-Type: application/json" -d '{"test": true}'
Prérequis
Docker (recommandé)
- Docker 20+ et Docker Compose v2+
- 1 CPU, 1 Go de RAM minimum (2 CPU, 4 Go recommandés)
Binaire unique
- Go 1.25+ (pour compiler depuis les sources)
- PostgreSQL 16+
- ClickHouse 24+
- Redis 7+
- 1 CPU, 1 Go de RAM minimum (2 CPU, 4 Go recommandés)
Installation — Docker Compose
La méthode recommandée pour exécuter WebhookLens. Un seul fichier lance toute la stack : PostgreSQL, ClickHouse, Redis et le serveur WebhookLens.
Télécharger et démarrer
# Télécharger le fichier compose communauté
curl -fsSL https://raw.githubusercontent.com/webhooklens/webhooklens/main/deploy/docker-compose.community.yml \
-o docker-compose.yml
# Démarrer la stack
docker compose up -d
Le tableau de bord est disponible sur http://localhost:3000 et le proxy webhook sur http://localhost:8080.
Fichier docker-compose.community.yml complet
# WebhookLens Community Edition — Docker Compose
# Usage: docker compose -f docker-compose.community.yml up -d
# Dashboard: http://localhost:3000
# Proxy: http://localhost:8080
version: '3.8'
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: webhooklens
POSTGRES_PASSWORD: webhooklens
POSTGRES_DB: webhooklens
volumes:
- pg_data:/var/lib/postgresql/data
- ./migrations/postgres:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U webhooklens"]
interval: 5s
retries: 5
clickhouse:
image: clickhouse/clickhouse-server:24-alpine
volumes:
- ch_data:/var/lib/clickhouse
- ./migrations/clickhouse:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD", "clickhouse-client", "--query", "SELECT 1"]
interval: 5s
retries: 5
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
retries: 5
webhooklens:
image: webhooklens/webhooklens:latest
ports:
- "3000:3000"
- "8080:8080"
environment:
WHL_DATABASE__POSTGRES_URL: postgres://webhooklens:webhooklens@postgres:5432/webhooklens?sslmode=disable
WHL_DATABASE__CLICKHOUSE_URL: clickhouse://clickhouse:9000/webhooklens
WHL_DATABASE__REDIS_URL: redis://redis:6379
WHL_AUTH__JWT_SECRET: change-me-in-production-use-64-chars-minimum
depends_on:
postgres: { condition: service_healthy }
clickhouse: { condition: service_healthy }
redis: { condition: service_healthy }
restart: unless-stopped
volumes:
pg_data:
ch_data:
redis_data:
WHL_AUTH__JWT_SECRET par une chaîne aléatoire d'au moins 32 caractères en production.
Installation — Binaire unique
Téléchargez un binaire précompilé ou compilez depuis les sources. Nécessite PostgreSQL, ClickHouse et Redis exécutés séparément.
Binaire précompilé
# Télécharger la dernière version
curl -fsSL https://github.com/webhooklens/webhooklens/releases/latest/download/webhooklens-linux-amd64 \
-o webhooklens
chmod +x webhooklens
# Lancer avec un fichier de configuration
./webhooklens --config config.yaml
Compiler depuis les sources
git clone https://github.com/webhooklens/webhooklens.git
cd webhooklens
go build -o webhooklens ./cmd/server
./webhooklens --config config.yaml
Configuration
WebhookLens peut être configuré via un fichier YAML ou des variables d'environnement. Les variables d'environnement utilisent le préfixe WHL_ avec des doubles underscores pour l'imbrication.
Serveur
| Clé de config | Variable d'env | Défaut | Description |
|---|---|---|---|
server.proxy_port | WHL_SERVER__PROXY_PORT | 8080 | Port pour l'ingestion des webhooks |
server.api_port | WHL_SERVER__API_PORT | 3000 | Port pour le tableau de bord et l'API |
server.debug | WHL_SERVER__DEBUG | false | Activer les logs de débogage |
server.cloud_domain | WHL_SERVER__CLOUD_DOMAIN | "" | Domaine cloud (SaaS multi-tenant) |
Base de données
| Clé de config | Variable d'env | Défaut | Description |
|---|---|---|---|
database.postgres_url | WHL_DATABASE__POSTGRES_URL | — | Chaîne de connexion PostgreSQL |
database.clickhouse_url | WHL_DATABASE__CLICKHOUSE_URL | — | Chaîne de connexion ClickHouse |
database.redis_url | WHL_DATABASE__REDIS_URL | — | Chaîne de connexion Redis |
Authentification
| Clé de config | Variable d'env | Défaut | Description |
|---|---|---|---|
auth.jwt_secret | WHL_AUTH__JWT_SECRET | — | Clé secrète JWT (32 caractères minimum) |
auth.github_client_id | WHL_AUTH__GITHUB_CLIENT_ID | "" | Client ID OAuth GitHub |
auth.github_secret | WHL_AUTH__GITHUB_SECRET | "" | Secret OAuth GitHub |
retention.events_days | WHL_RETENTION__EVENTS_DAYS | 30 | Suppression automatique des événements après N jours |
Limitation de débit
| Clé de config | Variable d'env | Défaut | Description |
|---|---|---|---|
rate_limit.api_per_tenant | WHL_RATE_LIMIT__API_PER_TENANT | 100 | Requêtes API par minute par tenant |
rate_limit.auth_per_ip | WHL_RATE_LIMIT__AUTH_PER_IP | 10 | Requêtes d'authentification par minute par IP |
Facturation Stripe
Requis uniquement en mode cloud/SaaS avec des forfaits payants.
| Clé de config | Variable d'env | Défaut | Description |
|---|---|---|---|
stripe.api_key | WHL_STRIPE__API_KEY | "" | Clé secrète Stripe |
stripe.price_id | WHL_STRIPE__PRICE_ID | "" | ID de prix Stripe pour l'abonnement |
stripe.webhook_secret | WHL_STRIPE__WEBHOOK_SECRET | "" | Clé secrète de signature webhook Stripe |
stripe.base_url | WHL_STRIPE__BASE_URL | "" | URL de base pour les redirections Stripe Checkout |
Configurez la distribution d'e-mails pour les réinitialisations de mot de passe et les notifications. Utilise Resend.
| Clé de config | Variable d'env | Défaut | Description |
|---|---|---|---|
email.resend_api_key | WHL_EMAIL__RESEND_API_KEY | "" | Clé API Resend |
email.from_address | WHL_EMAIL__FROM_ADDRESS | noreply@... | Adresse expéditeur pour les e-mails sortants |
Exemple config.yaml
server:
proxy_port: 8080
api_port: 3000
debug: false
database:
postgres_url: "postgres://user:pass@localhost:5432/webhooklens?sslmode=disable"
clickhouse_url: "clickhouse://localhost:9000/webhooklens"
redis_url: "redis://localhost:6379"
auth:
jwt_secret: "votre-secret-aleatoire-32-caracteres-minimum"
retention:
events_days: 30
rate_limit:
api_per_tenant: 100
auth_per_ip: 10
Proxy Webhook
WebhookLens agit comme un proxy inverse pour vos webhooks. Pointez vos fournisseurs vers l'URL du proxy et WebhookLens reçoit, journalise, valide et transmet chaque requête vers votre endpoint réel.
Réception des webhooks
L'URL du proxy suit ce schéma :
POST https://votre-domaine:8080/wh/{tenant-slug}/{endpoint-slug}
Lorsqu'un webhook arrive, WebhookLens :
- Reçoit la requête HTTP complète (méthode, en-têtes, corps, paramètres de requête)
- Stocke l'événement dans ClickHouse pour l'analytique et PostgreSQL pour l'inspection
- Valide la signature (si un fournisseur est configuré sur l'endpoint)
- Applique les transforms (si configurés)
- Transmet la requête à l'URL cible configurée
- Enregistre le code de réponse, la latence et les éventuelles erreurs
Politique de relance
Les livraisons échouées (réponses 5xx ou timeouts) sont relancées avec un backoff exponentiel :
| Tentative | Délai |
|---|---|
| 1re relance | 1 seconde |
| 2e relance | 5 secondes |
| 3e relance | 30 secondes |
| 4e relance | 5 minutes |
| 5e relance | 30 minutes |
Après 5 échecs consécutifs, l'événement est marqué comme failed. Vous pouvez le rejouer manuellement depuis le tableau de bord ou l'API à tout moment.
Validation de signature
Lorsque vous configurez un fournisseur sur un endpoint, WebhookLens valide automatiquement la signature du webhook en utilisant l'algorithme de signature du fournisseur. En cas d'échec de validation, l'événement est signalé mais reste stocké et transmis (sauf si vous activez le mode strict).
Exemple : vérification de signature Stripe
# Lors de la création de l'endpoint, définissez le fournisseur et le secret de signature
curl -X POST http://localhost:3000/api/endpoints \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "stripe-payments",
"target_url": "https://api.example.com/webhooks/stripe",
"provider": "stripe",
"signing_secret": "whsec_..."
}'
Fournisseurs supportés
WebhookLens prend en charge la validation automatique de signature pour les fournisseurs suivants :
| Fournisseur | En-tête de signature | Algorithme |
|---|---|---|
| Stripe | Stripe-Signature | HMAC-SHA256 (timestamp + payload) |
| GitHub | X-Hub-Signature-256 | HMAC-SHA256 |
| Shopify | X-Shopify-Hmac-SHA256 | HMAC-SHA256 (Base64) |
| Slack | X-Slack-Signature | HMAC-SHA256 (timestamp + body) |
| Twilio | X-Twilio-Signature | HMAC-SHA1 |
| SendGrid | X-Twilio-Email-Event-Webhook-Signature | ECDSA |
| Paddle | Paddle-Signature | HMAC-SHA256 (timestamp + payload) |
| Linear | Linear-Signature | HMAC-SHA256 |
| Svix | svix-signature | HMAC-SHA256 (msg-id + timestamp + body) |
| Clerk | svix-signature | HMAC-SHA256 basé sur Svix |
| Intercom | X-Hub-Signature | HMAC-SHA1 |
| Typeform | Typeform-Signature | HMAC-SHA256 |
| HMAC générique | Configurable | HMAC-SHA256 |
Tableau de bord
Événements & Inspecteur
La page des événements affiche tous les webhooks entrants en temps réel avec actualisation automatique. Chaque ligne indique :
- Statut — transmis (vert), échoué (rouge), rejoué (bleu), timeout (jaune)
- Fournisseur — détecté automatiquement depuis les en-têtes (Stripe, GitHub, Shopify, etc.)
- Endpoint — quel endpoint a reçu le webhook
- Latence — temps aller-retour pour transmettre et recevoir une réponse
- Horodatage — temps relatif ("il y a 2s") avec l'horodatage ISO complet au survol
Cliquez sur un événement pour ouvrir l'inspecteur :
- Onglet Requête : en-têtes, corps (JSON/XML avec coloration syntaxique), paramètres de requête
- Onglet Réponse : code de réponse cible, en-têtes, corps
- Onglet Chronologie : chronologie complète de livraison incluant les relances
- Bouton Replay : renvoie exactement la même requête à la cible
Endpoints
Les endpoints sont l'abstraction centrale. Chaque endpoint possède :
- Un slug unique qui fait partie de l'URL du proxy
- Une URL cible vers laquelle les webhooks sont transmis
- Un fournisseur optionnel pour la validation de signature
- Des transforms optionnels pour la manipulation du payload
- Des règles de routage optionnelles pour la distribution multi-destination
Analytique
Le tableau de bord analytique fournit des métriques en temps réel propulsées par ClickHouse :
- Volume — total des événements dans le temps (1h, 24h, 7j, 30j)
- Taux de succès — pourcentage de réponses 2xx
- Latence — percentiles P50, P95, P99
- Répartition par fournisseur — volume et succès par fournisseur
- Répartition par endpoint — volume et succès par endpoint
Alertes
Configurez des alertes pour être notifié en cas de problème :
- Seuil d'échec — alerte quand le taux d'erreur dépasse N% sur une fenêtre temporelle
- Seuil de latence — alerte quand la latence P95 dépasse N ms
- Absence d'événements — alerte quand aucun événement n'est reçu pendant N minutes
Les notifications peuvent être envoyées à Slack (via webhook entrant) ou à une URL webhook personnalisée.
# Créer une alerte
curl -X POST http://localhost:3000/api/alerts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "High failure rate",
"type": "failure_rate",
"threshold": 10,
"window_minutes": 5,
"channel": "slack",
"slack_webhook_url": "https://hooks.slack.com/services/..."
}'
Transforms & Routage
Transforms de payload
Les transforms vous permettent de modifier les payloads des webhooks avant leur transmission vers la cible. Utile pour enrichir des données, supprimer des champs sensibles ou adapter les payloads à votre format d'API.
Types de transforms
| Type | Description | Exemple |
|---|---|---|
set_field | Définir ou écraser un champ JSON | Ajouter source: "stripe" au corps |
remove_field | Supprimer un champ JSON | Supprimer data.object.metadata |
rename_field | Renommer un champ JSON | Renommer id en external_id |
add_header | Ajouter un en-tête de requête | Ajouter X-Source: webhooklens |
remove_header | Supprimer un en-tête de requête | Supprimer X-Internal-Token |
Exemple : ajouter un champ et un en-tête
curl -X PATCH http://localhost:3000/api/endpoints/EP_ID \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"transforms": [
{"type": "set_field", "path": "meta.source", "value": "stripe"},
{"type": "add_header", "key": "X-Source", "value": "webhooklens"},
{"type": "remove_field", "path": "data.object.metadata.internal"}
]
}'
Test à blanc (dry-run)
Testez vos transforms sans effectuer la transmission :
curl -X POST http://localhost:3000/api/transforms/test \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"transforms": [
{"type": "set_field", "path": "enriched", "value": true}
],
"payload": {"event": "payment.completed", "amount": 4999}
}'
# Réponse :
# {"event": "payment.completed", "amount": 4999, "enriched": true}
Routage intelligent
Routez un seul webhook vers plusieurs destinations selon des conditions. Permet la distribution en éventail, le traitement conditionnel et les cibles de secours.
Conditions de routage
| Condition | Description |
|---|---|
all | Toujours transmettre vers cette cible (éventail) |
on_success | Transmettre uniquement si la cible principale a retourné 2xx |
on_failure | Transmettre uniquement si la cible principale a retourné non-2xx ou a eu un timeout |
Exemple : distribution vers 3 cibles
curl -X PATCH http://localhost:3000/api/endpoints/EP_ID \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"target_url": "https://primary.example.com/webhook",
"routes": [
{"url": "https://analytics.example.com/ingest", "condition": "all"},
{"url": "https://backup.example.com/webhook", "condition": "all"},
{"url": "https://alerts.example.com/failure", "condition": "on_failure"}
]
}'
Référence API
Tous les endpoints API sont servis sur le port API (par défaut :3000). Les endpoints authentifiés nécessitent un token Bearer obtenu lors de la connexion.
Authentification
Créer un nouveau compte et un tenant.
curl -X POST http://localhost:3000/api/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "vous@exemple.com",
"password": "motdepassesecurise",
"tenant_name": "mon-projet"
}'
# Réponse : {"token": "eyJhbG...", "tenant": {"id": "...", "slug": "mon-projet"}}
S'authentifier et recevoir un token JWT.
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "vous@exemple.com", "password": "motdepassesecurise"}'
# Réponse : {"token": "eyJhbG..."}
API Endpoints
Lister tous les endpoints du tenant courant.
curl http://localhost:3000/api/endpoints \
-H "Authorization: Bearer YOUR_TOKEN"
# Réponse : [{"id": "...", "slug": "stripe-prod", "target_url": "https://...", ...}]
Créer un nouvel endpoint.
curl -X POST http://localhost:3000/api/endpoints \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "stripe-prod",
"target_url": "https://api.example.com/webhooks/stripe",
"provider": "stripe",
"signing_secret": "whsec_..."
}'
Mettre à jour un endpoint (URL cible, fournisseur, transforms, routes).
curl -X PATCH http://localhost:3000/api/endpoints/EP_ID \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"target_url": "https://nouvelle-cible.example.com/hook"}'
API Événements
Lister les événements avec des filtres optionnels. Supporte la pagination.
# Lister les événements récents
curl "http://localhost:3000/api/events?limit=50&status=failed" \
-H "Authorization: Bearer YOUR_TOKEN"
# Filtrer par endpoint
curl "http://localhost:3000/api/events?endpoint_id=EP_ID&limit=20" \
-H "Authorization: Bearer YOUR_TOKEN"
Rejouer un événement — renvoyer la requête originale à la cible.
curl -X POST http://localhost:3000/api/events/EVT_ID/replay \
-H "Authorization: Bearer YOUR_TOKEN"
# Réponse : {"status": "replayed", "response_code": 200, "latency_ms": 142}
API Analytique
Obtenir les statistiques agrégées du tenant.
curl "http://localhost:3000/api/analytics/overview?period=24h" \
-H "Authorization: Bearer YOUR_TOKEN"
# Réponse :
# {
# "total_events": 12847,
# "success_rate": 99.2,
# "p50_ms": 45,
# "p95_ms": 210,
# "p99_ms": 890,
# "by_provider": [{"provider": "stripe", "count": 8420}, ...],
# "by_status": {"forwarded": 12744, "failed": 62, "replayed": 41}
# }
API Facturation
Disponible en mode cloud uniquement.
Obtenir l'utilisation actuelle et le quota du forfait.
curl http://localhost:3000/api/billing/quota \
-H "Authorization: Bearer YOUR_TOKEN"
# Réponse : {"plan": "starter", "events_used": 12847, "events_limit": 50000, ...}
Créer une session Stripe Checkout pour une mise à niveau.
curl -X POST http://localhost:3000/api/billing/checkout \
-H "Authorization: Bearer YOUR_TOKEN"
# Réponse : {"checkout_url": "https://checkout.stripe.com/..."}
Créer une session Stripe Billing Portal pour gérer les abonnements.
curl -X POST http://localhost:3000/api/billing/portal \
-H "Authorization: Bearer YOUR_TOKEN"
# Réponse : {"portal_url": "https://billing.stripe.com/..."}
Tester un ensemble de transforms à blanc sur un payload d'exemple.
Référence CLI
Installation
go install github.com/webhooklens/webhooklens/cmd/webhooklens-cli@latest
Commandes
Connexion
# S'authentifier auprès d'un serveur WebhookLens
webhooklens-cli login --server https://app.webhooklens.cloud
# Pour un serveur auto-hébergé
webhooklens-cli login --server http://localhost:3000
Écoute (tunnel local)
# Transmettre les webhooks vers un serveur de développement local
webhooklens-cli listen --port 4000
# Spécifier un endpoint
webhooklens-cli listen --port 4000 --endpoint stripe-prod
Événements
# Lister les événements récents
webhooklens-cli events list
# Afficher les détails d'un événement
webhooklens-cli events show EVT_ID
# Rejouer un événement vers une URL différente
webhooklens-cli events replay EVT_ID --to http://localhost:4000/webhook
| Commande | Description |
|---|---|
webhooklens-cli login | S'authentifier auprès d'un serveur |
webhooklens-cli listen | Transmettre les webhooks vers un port local (tunnel dev) |
webhooklens-cli events list | Lister les événements récents |
webhooklens-cli events show <id> | Afficher les détails complets d'un événement (en-têtes, corps, réponse) |
webhooklens-cli events replay <id> | Rejouer un événement, optionnellement vers une URL différente |
Guide d'auto-hébergement
Déploiement en production
Pour la production, nous recommandons d'utiliser Caddy pour le HTTPS automatique et le fichier Docker Compose de production.
- Définir un
WHL_AUTH__JWT_SECRETfort (64+ caractères aléatoires) - Utiliser des instances PostgreSQL, ClickHouse et Redis dédiées (ou des services gérés)
- Activer TLS via Caddy ou votre répartiteur de charge
- Configurer des sauvegardes automatisées
- Configurer la limitation de débit adaptée à votre trafic
TLS avec Caddy
Caddy provisionne et renouvelle automatiquement les certificats TLS via Let's Encrypt.
Caddyfile
# /etc/caddy/Caddyfile
webhooks.example.com {
reverse_proxy localhost:3000
}
proxy.example.com {
reverse_proxy localhost:8080
}
# Démarrer Caddy
sudo caddy run --config /etc/caddy/Caddyfile
Sauvegarde & Restauration
Sauvegardez régulièrement PostgreSQL (données primaires). Les données ClickHouse peuvent être régénérées depuis les événements si nécessaire.
Script de sauvegarde
#!/bin/bash
# backup-webhooklens.sh
BACKUP_DIR="/backups/webhooklens"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Sauvegarde PostgreSQL
docker exec webhooklens-postgres-1 \
pg_dump -U webhooklens webhooklens | \
gzip > "${BACKUP_DIR}/pg_${TIMESTAMP}.sql.gz"
# Conserver les 30 dernières sauvegardes
ls -t "${BACKUP_DIR}"/pg_*.sql.gz | tail -n +31 | xargs rm -f
echo "Backup completed: pg_${TIMESTAMP}.sql.gz"
Planification cron
# Exécuter chaque jour à 2h du matin
0 2 * * * /opt/webhooklens/backup-webhooklens.sh >> /var/log/webhooklens-backup.log 2>&1
Restauration
# Restaurer depuis une sauvegarde
gunzip -c "/backups/webhooklens/pg_20260411_020000.sql.gz" | \
docker exec -i webhooklens-postgres-1 \
psql -U webhooklens webhooklens
Supervision
WebhookLens expose un endpoint de santé pour les vérifications de disponibilité et la supervision :
curl http://localhost:3000/healthz
# Réponse (sain) :
# {"status": "ok", "postgres": "ok", "clickhouse": "ok", "redis": "ok"}
# Réponse (dégradé) :
# {"status": "degraded", "postgres": "ok", "clickhouse": "error", "redis": "ok"}
Utilisez cet endpoint avec votre système de supervision (UptimeRobot, Datadog, Prometheus blackbox exporter, etc.) pour être alerté lorsqu'un composant est défaillant.
/metrics sur le port API. Utilisez-les pour un suivi détaillé du débit, de la latence et des taux d'erreur dans Grafana.
Besoin d'aide ? Ouvrez un ticket sur GitHub ou contactez-nous à support@webhooklens.cloud.