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émarrage rapide Opérationnel en moins de 60 secondes avec Docker Compose. Aucune carte bancaire requise pour l'essai cloud.
  1. Démarrez la stack
    docker compose up -d — lance PostgreSQL, ClickHouse, Redis et WebhookLens.
  2. Ouvrez le tableau de bord
    Accédez à http://localhost:3000. Inscrivez-vous pour créer votre tenant.
  3. 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é)

Binaire unique


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:
Important Remplacez 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 configVariable d'envDéfautDescription
server.proxy_portWHL_SERVER__PROXY_PORT8080Port pour l'ingestion des webhooks
server.api_portWHL_SERVER__API_PORT3000Port pour le tableau de bord et l'API
server.debugWHL_SERVER__DEBUGfalseActiver les logs de débogage
server.cloud_domainWHL_SERVER__CLOUD_DOMAIN""Domaine cloud (SaaS multi-tenant)

Base de données

Clé de configVariable d'envDéfautDescription
database.postgres_urlWHL_DATABASE__POSTGRES_URLChaîne de connexion PostgreSQL
database.clickhouse_urlWHL_DATABASE__CLICKHOUSE_URLChaîne de connexion ClickHouse
database.redis_urlWHL_DATABASE__REDIS_URLChaîne de connexion Redis

Authentification

Clé de configVariable d'envDéfautDescription
auth.jwt_secretWHL_AUTH__JWT_SECRETClé secrète JWT (32 caractères minimum)
auth.github_client_idWHL_AUTH__GITHUB_CLIENT_ID""Client ID OAuth GitHub
auth.github_secretWHL_AUTH__GITHUB_SECRET""Secret OAuth GitHub
retention.events_daysWHL_RETENTION__EVENTS_DAYS30Suppression automatique des événements après N jours

Limitation de débit

Clé de configVariable d'envDéfautDescription
rate_limit.api_per_tenantWHL_RATE_LIMIT__API_PER_TENANT100Requêtes API par minute par tenant
rate_limit.auth_per_ipWHL_RATE_LIMIT__AUTH_PER_IP10Requêtes d'authentification par minute par IP

Facturation Stripe

Requis uniquement en mode cloud/SaaS avec des forfaits payants.

Clé de configVariable d'envDéfautDescription
stripe.api_keyWHL_STRIPE__API_KEY""Clé secrète Stripe
stripe.price_idWHL_STRIPE__PRICE_ID""ID de prix Stripe pour l'abonnement
stripe.webhook_secretWHL_STRIPE__WEBHOOK_SECRET""Clé secrète de signature webhook Stripe
stripe.base_urlWHL_STRIPE__BASE_URL""URL de base pour les redirections Stripe Checkout

Email

Configurez la distribution d'e-mails pour les réinitialisations de mot de passe et les notifications. Utilise Resend.

Clé de configVariable d'envDéfautDescription
email.resend_api_keyWHL_EMAIL__RESEND_API_KEY""Clé API Resend
email.from_addressWHL_EMAIL__FROM_ADDRESSnoreply@...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 :

  1. Reçoit la requête HTTP complète (méthode, en-têtes, corps, paramètres de requête)
  2. Stocke l'événement dans ClickHouse pour l'analytique et PostgreSQL pour l'inspection
  3. Valide la signature (si un fournisseur est configuré sur l'endpoint)
  4. Applique les transforms (si configurés)
  5. Transmet la requête à l'URL cible configurée
  6. 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 :

TentativeDélai
1re relance1 seconde
2e relance5 secondes
3e relance30 secondes
4e relance5 minutes
5e relance30 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 :

FournisseurEn-tête de signatureAlgorithme
StripeStripe-SignatureHMAC-SHA256 (timestamp + payload)
GitHubX-Hub-Signature-256HMAC-SHA256
ShopifyX-Shopify-Hmac-SHA256HMAC-SHA256 (Base64)
SlackX-Slack-SignatureHMAC-SHA256 (timestamp + body)
TwilioX-Twilio-SignatureHMAC-SHA1
SendGridX-Twilio-Email-Event-Webhook-SignatureECDSA
PaddlePaddle-SignatureHMAC-SHA256 (timestamp + payload)
LinearLinear-SignatureHMAC-SHA256
Svixsvix-signatureHMAC-SHA256 (msg-id + timestamp + body)
Clerksvix-signatureHMAC-SHA256 basé sur Svix
IntercomX-Hub-SignatureHMAC-SHA1
TypeformTypeform-SignatureHMAC-SHA256
HMAC génériqueConfigurableHMAC-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 :

Cliquez sur un événement pour ouvrir l'inspecteur :

Endpoints

Les endpoints sont l'abstraction centrale. Chaque endpoint possède :

Analytique

Le tableau de bord analytique fournit des métriques en temps réel propulsées par ClickHouse :

Alertes

Configurez des alertes pour être notifié en cas de problème :

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

TypeDescriptionExemple
set_fieldDéfinir ou écraser un champ JSONAjouter source: "stripe" au corps
remove_fieldSupprimer un champ JSONSupprimer data.object.metadata
rename_fieldRenommer un champ JSONRenommer id en external_id
add_headerAjouter un en-tête de requêteAjouter X-Source: webhooklens
remove_headerSupprimer un en-tête de requêteSupprimer 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

ConditionDescription
allToujours transmettre vers cette cible (éventail)
on_successTransmettre uniquement si la cible principale a retourné 2xx
on_failureTransmettre 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

POST /api/auth/signup

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"}}
POST /api/auth/login

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

GET /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://...", ...}]
POST /api/endpoints

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_..."
  }'
PATCH /api/endpoints/:id

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

GET /api/events

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"
POST /api/events/:id/replay

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

GET /api/analytics/overview

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.

GET /api/billing/quota

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, ...}
POST /api/billing/checkout

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/..."}
POST /api/billing/portal

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/..."}
POST /api/transforms/test

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
CommandeDescription
webhooklens-cli loginS'authentifier auprès d'un serveur
webhooklens-cli listenTransmettre les webhooks vers un port local (tunnel dev)
webhooklens-cli events listLister 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.

Liste de vérification Avant de passer en production, assurez-vous de :

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.

Métriques Prometheus WebhookLens expose également des métriques compatibles Prometheus sur /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.