How to Fan Out One Webhook to Multiple Destinations
To fan a single webhook out to multiple destinations, add more than one relay rule to the same CanHook endpoint. Each rule gets its own destination URL, transform, headers, and retry count, and they run independently, so one failing destination never blocks or delays delivery to the others.
A single incoming webhook often needs to land in more than one place: your own application, a Slack channel for visibility, and an analytics pipeline that tracks the event separately. CanHook handles this by letting one endpoint carry more than one relay rule, each with its own destination, transform, and retry policy. You wire the source once, then fan the same captured request out to as many downstream services as your plan allows.
Why One Webhook Often Needs More Than One Destination
Take a typical Stripe checkout.session.completed event. Your application needs it to mark an order paid. Your team wants a Slack notification so someone notices a sale in real time. Your analytics pipeline wants the order total and currency, nothing else. Most providers only let you register a single URL per event type, so you cannot simply hand Stripe three separate webhook URLs and call it done.
The usual workaround is to make your primary handler responsible for calling the other two services itself, which couples their uptime and latency to your main request path, or to stand up a message queue just to broadcast one event. Both are more infrastructure than the problem needs when the fan-out itself is the only thing missing.
How Fan-Out Works: One Endpoint, Multiple Relay Rules
A CanHook endpoint is the single catch URL you hand to the sender. Underneath that one URL, you can add more than one relay rule: Pro plans allow up to five rules per endpoint, Business allows an unlimited number, and Free has none (relaying is a paid feature). Every request captured at the endpoint is queued against all of that endpoint's active rules at once:
- The inbound request lands at your catch URL and is stored as usual.
- CanHook creates one pending delivery row per active relay rule on that endpoint.
- Each delivery is attempted independently, on its own schedule, against its own destination.
Because each rule's delivery is its own row, the delivery log shows exactly which destination succeeded, which is retrying, and which has failed outright, per request. That per-rule visibility is what makes fan-out debuggable: instead of one combined success or failure for the whole webhook, you get one entry per destination, each with its own HTTP status, response snippet, and duration. See relay forwarding for the full rule configuration reference.
Give Each Destination Its Own Shape and Headers
Fan-out is only useful if each destination can receive the shape it actually expects. Every relay rule has an independent transform_mode, so the same captured request can go out three different ways at once: unchanged to a system that already speaks the sender's format, reshaped into a short message for a chat webhook, or trimmed down to a handful of fields for analytics. A rule can also carry its own custom headers, so a destination that needs a bearer token or a shared secret gets one without exposing it to the other destinations.
{
"text": "New order {{id}}: {{amount_total}} {{currency}}"
}That template config, attached to one relay rule in template mode, turns a full Stripe-shaped payload into a one-line message for a chat destination, while a second rule on the same endpoint forwards the untouched original to your application in passthrough mode. For the difference between template and filter mode in more depth, see transforming a webhook payload before forwarding.
What Happens When One Destination Is Down
Each relay rule carries its own retry_count, and a failed attempt backs off on a fixed schedule of roughly 60 seconds, 5 minutes, 25 minutes, then 2 hours before it is marked failed for good (Business-tier deliveries get priority in the retry queue). Because the three deliveries for one captured request are separate rows, a Slack webhook that is temporarily rate-limited retries and eventually resolves or fails entirely on its own timeline, while the passthrough delivery to your main application and the filtered delivery to analytics can both succeed on the first attempt in the meantime. One destination going down does not pause, cancel, or delay any of the others.
Keeping the Sender's Response Fast While Fan-Out Runs
None of this relay work happens before the original sender gets a response. CanHook stores the request, returns the endpoint's configured mock response immediately, and only then closes the connection back to the sender and begins dispatching relay rules. Fanning a request out to three destinations, one of which is slow, adds no latency to the response the sender sees, because that response was already sent and the connection already closed before any relay attempt starts. If the underlying server process cannot finish the response early for some reason, deliveries are queued instead and picked up by a background worker that runs every minute, so a slow environment degrades to slightly delayed delivery rather than a slow response to the sender.
A Worked Example: One Stripe Event, Three Destinations
Simulating the inbound event against a CanHook catch URL looks like any other webhook call:
curl -X POST https://canhook.com/h/abc123def456 \
-H "Content-Type: application/json" \
-d '{"id": "cs_test_1", "amount_total": 4999, "currency": "usd"}'On that one endpoint you add three relay rules: a passthrough rule pointed at your application's order-completion URL with an Authorization header your app checks, a template rule pointed at a chat webhook that renders the one-line message shown earlier, and a filter rule pointed at an analytics ingestion URL that keeps only amount_total and currency. Stripe still only knows about a single URL. CanHook is the layer that turns that one delivery into three, each shaped and authenticated for the service receiving it.
Fan-out this way is not a separate feature bolted onto relaying, it is simply what happens when an endpoint has more than one active relay rule. Adding a fourth destination later, or removing one that is no longer needed, does not touch the other rules or the source integration at all, since each rule is configured, retried, and logged on its own.
The same independence applies however many rules you add. A destination you add today does not need to know about the ones you added last month, and a destination you remove does not need any cleanup on the others, because nothing about a relay rule references its siblings on the same endpoint. That is what keeps fan-out from turning into the same tangle of point-to-point integrations it is meant to replace.
Frequently asked questions
How many relay rules can one CanHook endpoint have?
Free endpoints have no relay rules at all. Pro endpoints can have up to 5 relay rules each, and Business endpoints can have an unlimited number, so a single catch URL can fan out to as many downstream services as the plan allows.
Do all relay rules on an endpoint deliver at the same time?
Each active relay rule gets its own pending delivery as soon as a request is captured, and CanHook attempts them independently right after the sender's response is returned, so they run effectively in parallel rather than waiting on each other.
What happens if one relay rule's destination is unreachable?
That rule's delivery retries on its own exponential backoff schedule and is eventually marked failed if it never succeeds. The other relay rules on the same endpoint are unaffected and keep delivering on their own schedules.
Can each relay rule send a different payload shape to its destination?
Yes. Every relay rule has its own transform mode, so one rule can forward the original body untouched while another rebuilds it from a template and a third filters it down to a handful of fields, all from the same captured request.
Does adding more relay rules slow down the response to the original sender?
No. CanHook stores the request and returns the endpoint's configured response before any relay rule is dispatched, so the sender's response time does not depend on how many destinations the request fans out to afterward.
Can I use a different authentication header for each fan-out destination?
Yes. Custom headers are set per relay rule, so one destination can require a bearer token, another a shared secret header, and a third no authentication at all, without any of them being exposed to the other destinations.