Auto-forwarding sends a copy of every captured webhook to a URL you configure, while HookDeploy still stores the full request for inspection.
How it works
When an endpoint has a forward_url set, the ingestion flow becomes:
- Webhook arrives at
https://hookdeploy.dev/h/{slug} - HookDeploy validates the endpoint, checks limits, stores metadata and body in R2
- HookDeploy returns
200 {"request_id":"..."}to the sender - Asynchronously, HookDeploy POSTs (or uses the original method) to your
forward_urlwith the original headers, query string, and body - Forward results are written to the request record
Steps 3 and 4 are independent. Your webhook sender never waits for your server, and your server being down doesn’t cause the sender to retry.
Configuring a forward URL
Set it when creating or editing an endpoint:
Dashboard — Endpoint settings → Forward URL
API:
curl -s -X PATCH "https://api.hookdeploy.dev/v1/endpoints/ENDPOINT_ID" \
-H "Authorization: Bearer hd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"forward_url": "https://api.example.com/webhooks/stripe"}'
Requirements:
- Must use
https://— plain HTTP is rejected at validation - Can be any publicly reachable URL, including ngrok tunnels, staging servers, or Cloudflare Workers
- Set to
nullto disable forwarding without removing the endpoint
What gets forwarded
HookDeploy forwards the original HTTP request:
- Same method (POST, PUT, etc.)
- Same headers, minus stripped proxy headers (
cf-ray,cf-connecting-ip, etc.) - Same query string
- Same body bytes
HookDeploy does not add signature headers from the original provider. If your handler verifies Stripe signatures, you’ll need to either:
- Point Stripe directly at your server for signed events, and use HookDeploy for debugging separately, or
- Disable signature verification in development when testing via forward
For replay (manual re-send), HookDeploy adds x-hookdeploy-replay and x-hookdeploy-original-request-id headers. Auto-forward adds x-hookdeploy-forward: 1 (always, and it cannot be overridden). See Header injection below for custom injected headers.
Header injection
When forwarding webhooks to your server, HookDeploy can automatically inject custom headers into every forwarded request. This is useful when your server requires authentication that the original webhook sender doesn’t provide.
Common use cases:
- Adding
Authorization: Bearer <token>when your server requires auth - Adding
X-Tenant-IDfor multi-tenant applications - Adding
X-Source: hookdeployfor request tracing
How it works:
Injected headers are merged with the original webhook headers before forwarding. If the original webhook contains a header with the same name, the injected value takes precedence.
The x-hookdeploy-forward: 1 header is always added and cannot be overridden.
Configuration:
Set injected headers in your endpoint’s Settings tab under Inject headers on forward.
Note: Header injection is available on Starter, Team, and Enterprise plans. Upgrade your plan to enable it.
Security:
Injected header values are stored securely in our database. They are never logged or exposed in the HookDeploy dashboard after saving — only the header names are shown.
Forward status
Each request records the forward attempt:
{
"forward_url": "https://api.example.com/webhooks/stripe",
"forward_attempted_at": "2025-05-23T12:00:01Z",
"forward_status_code": 200,
"forward_response_time_ms": 87,
"forward_error": null
}
If the forward fails (timeout, DNS error, connection refused):
{
"forward_status_code": null,
"forward_response_time_ms": null,
"forward_error": "Connection timed out after 10000ms"
}
Check forward status in the request inspector under Overview, or via GET /v1/endpoints/:id/requests/:requestId.
Latency implications
From the sender’s perspective, forwarding adds zero latency. HookDeploy responds to the sender before initiating the forward.
Your server sees a slight delay — typically 50–200ms after the sender received 200. Factors:
- R2 write latency (~10–30ms)
- Forward HTTP round trip to your server
- Your server’s processing time (not included in
forward_response_time_ms— that’s HookDeploy-to-your-server only)
HookDeploy does not retry failed forwards. If your server was down, the webhook is still captured — use Replay to re-send it later.
Common patterns
Staging proxy
Point a provider’s webhook at HookDeploy, set forward URL to your staging server. You get a full audit log in HookDeploy plus live processing on staging.
Stripe → hookdeploy.dev/h/abc123 → staging.example.com/webhooks
↓
Dashboard inspector
Capture-only (no forward)
Leave forward_url empty. Use HookDeploy purely for inspection and manual replay to localhost when needed.
Switching targets
Update forward_url anytime. The next incoming webhook forwards to the new URL. Previously captured requests are not re-forwarded.
Forwarding vs replay
| Auto-forward | Replay | |
|---|---|---|
| Trigger | Every incoming webhook | Manual, per request |
| Target | Fixed forward_url on endpoint | Any HTTPS URL you choose |
| Timing | Automatic, ~100ms after capture | On demand |
| Headers added | None | x-hookdeploy-replay, x-hookdeploy-original-request-id |
| Recorded in | Request forward fields | replays table |