HookDeploy

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:

  1. Webhook arrives at https://hookdeploy.dev/h/{slug}
  2. HookDeploy validates the endpoint, checks limits, stores metadata and body in R2
  3. HookDeploy returns 200 {"request_id":"..."} to the sender
  4. Asynchronously, HookDeploy POSTs (or uses the original method) to your forward_url with the original headers, query string, and body
  5. 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 null to 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-ID for multi-tenant applications
  • Adding X-Source: hookdeploy for 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-forwardReplay
TriggerEvery incoming webhookManual, per request
TargetFixed forward_url on endpointAny HTTPS URL you choose
TimingAutomatic, ~100ms after captureOn demand
Headers addedNonex-hookdeploy-replay, x-hookdeploy-original-request-id
Recorded inRequest forward fieldsreplays table

Next steps

  • Replay — Manual re-send to any URL
  • Requests — Forward metadata fields
  • Endpoints — Configure forward URL on an endpoint