Proxy headers
Hookman adds a set of x-hookman-* headers to every request it forwards. These are added to the outbound request — the one your application receives. The original sender never sees them.
Added headers
| Header | Example value | Description |
|---|---|---|
x-hookman-org | acme | The org slug |
x-hookman-project | payments | The project slug |
x-hookman-routing-method | rule | How the target was resolved: rule (a routing rule matched), switch (fell through to the active deployment), or fanout (this is a mirrored fan-out copy) |
x-hookman-rule-id | rule_01hw... | The ID of the rule that matched. Present only when routing-method is rule. |
x-hookman-rule-name | checkout-branch | The human-readable name of the matched rule. Present only when a rule matched. |
x-hookman-received | 2025-03-12T14:22:58.341Z | ISO 8601 timestamp when Hookman received the original request |
x-hookman-log-id | log_01hw... | The webhook log entry ID — use this to find the log in your dashboard |
x-hookman-config-version | 7 | The route config version this delivery was routed with — useful for debugging stale config |
x-hookman-version | a1b2c3d | The proxy build (git SHA) that handled the request |
The original caller’s IP is preserved in the standard x-forwarded-for / cf-connecting-ip headers Cloudflare adds.
Replay-only headers
These are added only when the delivery is a replay (not a live webhook):
| Header | Example value | Description |
|---|---|---|
x-hookman-replay | true | Always true for replayed webhooks |
x-hookman-original-log-id | log_01hw... | Log ID of the original event being replayed |
x-hookman-truncated | true | Present and true if the stored body was truncated at 100 KB |
Detecting replays in your application
// Express / Node.jsapp.post('/api/webhooks/stripe', (req, res) => { const isReplay = req.headers['x-hookman-replay'] === 'true'
if (isReplay) { // Skip sending confirmation emails, avoid double-charging, etc. console.log('Replay of log', req.headers['x-hookman-original-log-id']) }
// ... process webhook})Original headers are preserved
All headers from the original sender are forwarded unchanged. Hookman does not remove or modify any headers the sender included (e.g. stripe-signature, x-paddle-signature).
This means your existing HMAC signature verification continues to work without any changes.
// Stripe signature verification still worksconst event = stripe.webhooks.constructEvent( rawBody, req.headers['stripe-signature'], // ← forwarded unchanged by Hookman process.env.STRIPE_WEBHOOK_SECRET)import { Aside } from ‘@astrojs/starlight/components’