Documentation

WebhookLens is EU-hosted webhook observability. Receive, inspect, replay, and forward webhooks with full visibility.

Quick Start Get running in under 60 seconds. No infrastructure to manage — create an account, add an endpoint, and point your provider's webhook at the generated URL.
  1. Create a free account
    Sign up at app.webhooklens.cloud — no credit card required to start.
  2. Add an endpoint
    In the dashboard, create an endpoint with the target URL where your webhooks should be forwarded. WebhookLens generates a unique proxy URL.
  3. Point your provider and send a test webhook
    Configure your provider to send to the generated URL, then: curl -X POST https://proxy.webhooklens.cloud/wh/your-tenant/your-endpoint -H "Content-Type: application/json" -d '{"test": true}'

Webhook Proxy

WebhookLens acts as a reverse proxy for your webhooks. Point your providers to the proxy URL and WebhookLens receives, logs, validates, and forwards every request to your actual endpoint.

Receiving Webhooks

The proxy URL follows this pattern:

POST https://proxy.webhooklens.cloud/wh/{tenant-slug}/{endpoint-slug}

When a webhook arrives, WebhookLens:

  1. Receives the full HTTP request (method, headers, body, query params)
  2. Stores the event in ClickHouse for analytics and PostgreSQL for inspection
  3. Validates the signature (if a provider is configured on the endpoint)
  4. Applies transforms (if any are configured)
  5. Forwards the request to the configured target URL
  6. Records the response status, latency, and any errors

Retry policy

Failed deliveries (5xx responses or timeouts) are retried with exponential backoff:

AttemptDelay
1st retry1 second
2nd retry5 seconds
3rd retry30 seconds
4th retry5 minutes
5th retry30 minutes

After 5 failed retries the event is marked as failed. You can manually replay it from the dashboard or API at any time.

Signature Validation

When you configure a provider on an endpoint, WebhookLens can cryptographically verify the webhook signature using the provider's signing algorithm. Signature verification (checking the HMAC against your signing secret) is currently supported for Stripe and GitHub. If verification fails, the event is flagged but still stored and forwarded (unless you enable strict mode).

For 9 more providers, WebhookLens auto-detects and labels the source by inspecting well-known signature headers — no secret required. This lets you filter and inspect events by provider even without full cryptographic verification.

Example: Stripe signature verification

# When creating the endpoint, set the provider and signing secret
curl -X POST https://app.webhooklens.cloud/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_..."
  }'

Supported Providers

ProviderSignature HeaderAlgorithmSupport
StripeStripe-SignatureHMAC-SHA256 (timestamp + payload)Verification
GitHubX-Hub-Signature-256HMAC-SHA256Verification
ShopifyX-Shopify-Hmac-SHA256HMAC-SHA256 (Base64)Auto-detection
SlackX-Slack-SignatureHMAC-SHA256 (timestamp + body)Auto-detection
TwilioX-Twilio-SignatureHMAC-SHA1Auto-detection
SendGridX-Twilio-Email-Event-Webhook-SignatureECDSAAuto-detection
PayPalPAYPAL-TRANSMISSION-SIGHMAC-SHA256Auto-detection
PaddlePaddle-SignatureHMAC-SHA256 (timestamp + payload)Auto-detection
LinearLinear-SignatureHMAC-SHA256Auto-detection
AtlassianX-Hub-SignatureHMAC-SHA256Auto-detection
DiscordX-Signature-Ed25519Ed25519Auto-detection

Dashboard

Events & Inspector

The events page shows all incoming webhooks in real-time with auto-refresh. Each row shows:

Click any event to open the inspector:

Endpoints

Endpoints are the core abstraction. Each endpoint has:

Analytics

The analytics dashboard provides real-time metrics powered by ClickHouse:

Alerts

Configure alerts to be notified when something goes wrong:

Notifications can be sent to Slack (via incoming webhook) or to a custom webhook URL.

# Create an alert
curl -X POST https://app.webhooklens.cloud/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 & Routing

Payload Transforms

Transforms let you modify webhook payloads before they are forwarded to the target. This is useful for enriching data, removing sensitive fields, or adapting payloads to your API format.

Transform types

TypeDescriptionExample
set_fieldSet or overwrite a JSON fieldAdd source: "stripe" to the body
remove_fieldRemove a JSON fieldStrip data.object.metadata
rename_fieldRename a JSON fieldRename id to external_id
add_headerAdd a request headerAdd X-Source: webhooklens
remove_headerRemove a request headerStrip X-Internal-Token

Example: add a field and a header

curl -X PATCH https://app.webhooklens.cloud/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"}
    ]
  }'

Dry-run test

Test your transforms without actually forwarding:

curl -X POST https://app.webhooklens.cloud/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}
  }'

# Response:
# {"event": "payment.completed", "amount": 4999, "enriched": true}

Smart Routing

Route a single webhook to multiple destinations based on conditions. This enables fan-out, conditional processing, and fallback targets.

Routing conditions

ConditionDescription
allAlways forward to this target (fan-out)
on_successForward only if the primary target returned 2xx
on_failureForward only if the primary target returned non-2xx or timed out

Example: fan-out to 3 targets

curl -X PATCH https://app.webhooklens.cloud/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"}
    ]
  }'

API Reference

The API base URL is https://app.webhooklens.cloud. Authenticated endpoints require a Bearer token — either a JWT obtained from login, or an API key created in Settings → API Keys (passed as Authorization: Bearer whl_<key>).

Authentication

POST /api/auth/signup

Create a new account and tenant.

curl -X POST https://app.webhooklens.cloud/api/auth/signup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "you@example.com",
    "password": "securepassword",
    "tenant_name": "my-project"
  }'

# Response: {"token": "eyJhbG...", "tenant": {"id": "...", "slug": "my-project"}}
POST /api/auth/login

Authenticate and receive a JWT token.

curl -X POST https://app.webhooklens.cloud/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "password": "securepassword"}'

# Response: {"token": "eyJhbG..."}

Endpoints API

GET /api/endpoints

List all endpoints for the current tenant.

curl https://app.webhooklens.cloud/api/endpoints \
  -H "Authorization: Bearer YOUR_TOKEN"

# Response: [{"id": "...", "slug": "stripe-prod", "target_url": "https://...", ...}]
POST /api/endpoints

Create a new endpoint.

curl -X POST https://app.webhooklens.cloud/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

Update an endpoint (target URL, provider, transforms, routes).

curl -X PATCH https://app.webhooklens.cloud/api/endpoints/EP_ID \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"target_url": "https://new-target.example.com/hook"}'

Events API

GET /api/events

List events with optional filters. Supports pagination.

# List recent events
curl "https://app.webhooklens.cloud/api/events?limit=50&status=failed" \
  -H "Authorization: Bearer YOUR_TOKEN"

# Filter by endpoint
curl "https://app.webhooklens.cloud/api/events?endpoint_id=EP_ID&limit=20" \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/events/:id/replay

Replay an event — re-send the original request to the target.

curl -X POST https://app.webhooklens.cloud/api/events/EVT_ID/replay \
  -H "Authorization: Bearer YOUR_TOKEN"

# Response: {"status": "replayed", "response_code": 200, "latency_ms": 142}

Analytics API

GET /api/analytics/overview

Get aggregate analytics for the tenant.

curl "https://app.webhooklens.cloud/api/analytics/overview?period=24h" \
  -H "Authorization: Bearer YOUR_TOKEN"

# Response:
# {
#   "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}
# }

Billing API

Available in cloud mode only.

GET /api/billing/quota

Get current usage and plan quota.

curl https://app.webhooklens.cloud/api/billing/quota \
  -H "Authorization: Bearer YOUR_TOKEN"

# Response: {"plan": "starter", "events_used": 12847, "events_limit": 100000, ...}
POST /api/billing/checkout

Create a Stripe Checkout session for upgrading.

curl -X POST https://app.webhooklens.cloud/api/billing/checkout \
  -H "Authorization: Bearer YOUR_TOKEN"

# Response: {"checkout_url": "https://checkout.stripe.com/..."}
POST /api/billing/portal

Create a Stripe Billing Portal session for managing subscriptions.

curl -X POST https://app.webhooklens.cloud/api/billing/portal \
  -H "Authorization: Bearer YOUR_TOKEN"

# Response: {"portal_url": "https://billing.stripe.com/..."}
POST /api/transforms/test

Dry-run a set of transforms against a sample payload.


MCP Server

WebhookLens exposes a Model Context Protocol server so you can query your webhook data straight from AI assistants like Claude. Ask in plain language — "what failed in the last hour?", "show me the last Stripe event", "replay event EVT_123" — and the assistant calls WebhookLens for you. Every tool is scoped to your workspace, so an assistant only ever sees your own data.

Connecting

The server lives at https://app.webhooklens.cloud/mcp and authenticates with OAuth. There is no API key to copy — you sign in with your normal WebhookLens account and approve access once.

Claude Code (CLI)

claude mcp add --transport http webhooklens https://app.webhooklens.cloud/mcp

On first use your browser opens to sign in to WebhookLens (password or GitHub) and approve access. After that, the assistant can call the tools below.

Claude.ai (web)

Add a custom connector with the URL https://app.webhooklens.cloud/mcp and complete the same sign-in. The web connector is OAuth-only.

Available Tools

ToolDescription
list_endpointsList all webhook endpoints in your workspace
list_eventsList recent events (summaries) — filter by endpoint, status, provider, type, search, or time range
get_eventFetch one event in full: request body, headers, response, and last error
analytics_overviewDelivery stats over a window: totals, success/failure rate, latency percentiles
analytics_errorsTop recurring delivery errors, grouped by endpoint and message
list_retriesEvents currently queued for automatic retry
replay_eventRe-deliver a stored event to its endpoint's own target URL (audit-logged)

replay_event is the only tool that writes anything; the other six are read-only.


Need help? Reach out at support@webhooklens.cloud.