Forwarding
Forwarding lets CatchHook automatically deliver every incoming event — webhook or email — to your own server in real time. Events are still stored for inspection; forwarding happens in addition to storage, not instead of it.
Requires Pro or Business plan.
Setting up a forwarding target
- Open an endpoint and go to the Forwarding panel (labeled JSON Forwarding on email endpoints).
- Click Add forwarding target.
- Configure the target:
- URL (required) — the destination where events should be forwarded (e.g.,
https://api.example.com/webhooks). - Name (optional) — a label for this target.
- Enabled — toggle forwarding on or off without deleting the target.
- URL (required) — the destination where events should be forwarded (e.g.,
- Save.
Every new event that arrives at this endpoint will now be forwarded to your target URL.
Webhook endpoints
Webhook events are forwarded with the original HTTP method, headers, and body.
Email endpoints
Email events are forwarded as a normalized JSON POST. The payload includes:
{
"event": "email.received",
"id": "eml_abc123",
"endpoint_id": "ep_xyz789",
"received_at": "2026-05-28T12:00:00Z",
"from": "sender@example.com",
"to": "your-address@in.catchhook.app",
"subject": "Order Confirmation",
"text": "Plain text body...",
"html": "<html>...</html>",
"headers": { "From": "sender@example.com", ... },
"attachments": [{ "filename": "receipt.pdf", "content_type": "application/pdf", "size": 12345 }],
"message_id": "<abc@example.com>",
"provider": "sendgrid",
"authentication": { "spf": "PASS", "dkim": "PASS", "dmarc": "PASS" }
}
SES transport headers (e.g., x-ses-*, return-path, received) are filtered out before forwarding.
Optional path/query append (webhook only)
Each forwarding target can optionally:
- Append original path — forwards the inbound webhook path onto the target URL path.
- Append original query — merges inbound query parameters into the target URL query string.
Both options are off by default for backward compatibility.
Multiple targets
| Plan | Targets per endpoint |
|---|---|
| Pro | 1 |
| Business | Unlimited |
Business accounts can forward the same webhook to multiple destinations simultaneously — useful for sending to both production and a logging service.
Retries and timeouts
If a forwarding attempt fails (non-2xx response or timeout), CatchHook retries automatically. You can see the delivery status, response code, and response time for each attempt on the forwarding target's detail view.
For webhook endpoints, forwarding normalizes Rack-style headers (for example HTTP_X_HUB_SIGNATURE_256 -> X-Hub-Signature-256) before delivery so downstream signature verification works consistently.
Circuit breaker
To protect your downstream services, CatchHook uses a circuit breaker pattern:
- If a target fails repeatedly, it is automatically disabled.
- After a 30-minute cooldown, the target is re-enabled and delivery resumes.
- You'll be notified when a target is disabled so you can investigate.
Forwarding health
On the forwarding target detail view, you can see:
- Success rate — percentage of successful deliveries.
- Response time — average response time from your server.
- Last delivery — timestamp and result of the most recent attempt.
Conditional forwarding rules (Business)
By default, all incoming requests are forwarded to every enabled target. With forwarding rules, you can control which requests go where — routing specific event types to specific targets.
Adding rules
- Edit a forwarding target.
- Under Forwarding Rules, click Add rule.
- Configure the condition:
- Match field — what to check:
header,method,path,content_type, orbody_json_path. - Operator — how to compare:
equals,not_equals,contains,not_contains,matches(regex),exists. - Match value — the value to compare against.
- Match field — what to check:
Match value format
| Field | Format | Example |
|---|---|---|
header |
Header-Name:expected-value |
X-Event-Type:payment.completed |
method |
HTTP method | POST |
path |
Path string | /webhooks/stripe |
content_type |
Content type string | application/json |
body_json_path |
$.path.to.key:expected-value |
$.event.type:invoice.paid |
Rule evaluation
- All rules on a target must match for the request to be forwarded (AND logic).
- If a target has no rules, it receives everything (backward compatible).
- Rules are evaluated in order by position.
Example: route by event type
Forward Stripe payment events to your billing service and all other events to your logging service:
- Billing target: Rule → header
X-Event-Typecontainspayment - Logging target: No rules (receives everything)
Manual replay vs. automatic forwarding
| Feature | Replay | Forwarding |
|---|---|---|
| Trigger | Manual (click per event) | Automatic (every incoming event) |
| Destination | Any URL you enter | Pre-configured target(s) |
| Modifications | Edit body, headers, query params before sending (with payment method) | No modification — sends as received |
| Identity & signature | Regenerate IDs, re-sign payloads (webhook only) | Passes through as-is |
| Email format | Normalized JSON POST | Normalized JSON POST |
| Plan required | Any (modifications require payment method) | Pro or Business |
Both replay and forwarding send webhook events with the original method, headers, and body by default. Email events are always sent as a normalized JSON POST. Replay additionally supports a Modify mode that lets you edit the event before sending — see Replaying an event.