ProxyHook
Integrations
Pricing Try Free
Log in →

Footer

ProxyHook Logo

Support

  • Pricing
  • Documentation

Company

  • Blog

Legal

  • Contact
  • Privacy
  • Terms

features

Filtering Noise Out Before It Reaches Your Destinations

August 3, 2026

Glowing event packets being sorted, with a portion diverted away from the main stream

Every Stripe account fires webhooks in test mode and live mode from the same endpoint. Every public form fires webhooks from real users and from bots that found the URL. Every source you connect to ProxyHook eventually sends you events you did not want in your warehouse, your Slack channel, or your analytics table. The event still needs to reach ProxyHook so you can see it in Logs, but it should not reach Postgres, Datadog, or wherever you actually act on the data.

That is what Filters are for. A filter is a rule that matches a portion of your traffic and stops it from continuing. It does not reject the request at the source, and it does not change what a Log shows you. It just keeps matched events from reaching the automation steps and destinations downstream of it.

What you can actually filter on

ProxyHook ships twelve filter types, and they fall into three groups:

Request and network filters: IP, Host, User Agent, Referer, Cookies, Request Method, Request URL. These look at the HTTP request itself, not the payload, so they work identically whether the source is a webhook you built or a pre-built integration like Stripe or HubSpot.

Geographic filters: City, State, Country, Postal / Zip Code. These are resolved from the request, useful when a source is exposed to the public internet and you only care about traffic from a specific region.

Payload filter: Payload Contents, which matches on key values inside the event body itself, whatever shape that body happens to be. A Stripe event, a Jotform submission, and a generic webhook POST all have different payloads, and Payload Contents is the one filter type that reaches into all of them.

The important detail across all twelve: a filter excludes what it matches. If a filter matches a request, that request does not continue. There is no filter type that works the other way and lets only matching traffic through, so the way you use a filter is to describe the traffic you want gone, not the traffic you want to keep.

Source-level filters vs automation-step filters

Filters attach in two different places, and where you put one changes its blast radius.

A filter on the source runs once, before the event reaches any automation. If you have three automations fanning a single Stripe source out to Postgres, Slack, and Datadog, a source-level filter removes matching events from all three at once. This is the right place for exclusions that should never reach anywhere, like known bot traffic hitting a public webhook endpoint.

A filter added as a step inside an automation only affects that one automation. If Postgres should get every event but Slack should only get a subset, you filter on the Slack automation, not the source. The automation builder lets you drop a filter in between the source and the destination the same way you would drop in a transformation, per the steps in Automations: pick a source, add steps, add destinations.

Worked example: keeping Stripe test mode out of Postgres

Every Stripe event carries a livemode field, true for real transactions and false for anything fired from test mode. If your Postgres warehouse is downstream of a Stripe source, test-mode charges will show up in the same table as real ones unless something stops them.

  1. Create a Stripe source and register your endpoint under Developers > Webhooks in the Stripe dashboard, subscribing to the events you care about (payment_intent.succeeded, charge.failed, and similar).
  2. Open the Automation that routes this source to your Postgres destination.
  3. Add a Payload Contents filter step before the Postgres destination, matching on the livemode key with a value of false.
  4. Save the automation.

Test events still arrive at the source and still show up in Source Logs, so you can confirm the integration is wired correctly. They just stop before Postgres. If you later add a Slack destination on the same source for payment alerts, you attach a separate filter to that automation instead of touching the Stripe source itself, since you may want test-mode failures visible in Slack during development even while keeping them out of the production table.

Worked example: keeping bot traffic off a public webhook

A public-facing Webhook source, the kind you hand out as a form action URL or paste into a third-party tool that does not have a pre-built ProxyHook integration, attracts more than the traffic you intended. Scanners and bots find the endpoint and start posting to it, and every one of those requests becomes a row your destination has to deal with.

Two filter types handle most of this without touching the payload at all:

  • A User Agent filter matching known automated clients (empty user agents, generic HTTP libraries) stops that traffic before it counts as a real event.
  • A Country filter is useful when the source only serves a specific market, for example a form that should only accept submissions from customers in one country, and everything outside that list gets excluded.

Because both are network-level filters, they work the same way whether the payload underneath is JSON, NDJSON, or CSV, per the format options on the Webhook source. Attach them at the source level, since bad traffic should never reach any automation built on top of that endpoint, not just the first one you happened to build.

The tradeoff to keep in mind

A source-level filter is permanent for that source until you remove it. If you filter out a country today and expand into that market next quarter, nothing will tell you the filter is still there silently dropping real customer events. Automation-step filters are lower risk in that sense: they are scoped to one destination, visible right next to it in the builder, and easier to spot when you are reviewing why a specific destination looks thin on data.

Filters are worth checking against Logs, not just Activity. Source Logs show every request that reaches the endpoint, so if a destination's volume drops unexpectedly, compare that count against what the automation's Activity view reports as successful deliveries. A gap between the two is the filter working as designed, or it is the filter working on traffic you did not mean to exclude.

Filters do not require touching the system sending you data, and they do not require a code change on your end. If you are seeing noise in a destination today, the fix is usually a five-minute addition to the automation, not a new integration.

← Back to blog