Most webhook guides are about receiving events from other platforms. This one is about the opposite: letting your own customers subscribe to events from *your* product.
Customer-facing webhooks let a customer enter a URL, choose events such as "order created" or "ticket closed", and have your platform send an HTTP request to their system whenever those events happen. They're one of the most requested features from technical customers, and one of the easiest to get wrong.
An API lets customers pull data from your product. Webhooks let them react to changes without polling you.
For customers, that means simpler integrations and fresher data. For you, it means fewer repetitive API calls from customers checking for changes, and a foundation that automation tools and partners can build on.
Name events consistently, for example invoice.created, invoice.paid, invoice.voided. Once customers depend on an event name or field, changing it breaks their integration, so treat the catalogue like a public API.
Decide what each payload contains. There are two common approaches:
Approach
Payload
Trade-off
Fat payload
The full resource at the time of the event
Convenient, but can be stale by the time it's processed and may expose more data than needed
Thin payload
Event type and resource ID
Customer must call your API for details, but always gets current data
Whichever you choose, include an event ID, event type, timestamp, and the ID of the account the event belongs to. Version the payload format so you can evolve it later.
Never send webhooks inline from the request that caused the event. If a customer's endpoint is slow or down, your own product shouldn't slow down with it.
Write events to a durable queue or outbox table in the same transaction as the change that produced them. Workers then pick up events, look up matching subscriptions and send the requests.
The same pipeline shape works in both directions: acknowledge or enqueue quickly, deliver from workers, retry temporary failures.
Customer endpoints fail. Retry failed deliveries with exponential backoff over a defined window, for example several attempts spread over hours. Treat timeouts and 5xx responses as retryable. Treat most 4xx responses as permanent, except for rate limiting.
Publish your retry policy so customers know what to expect.
If an endpoint fails consistently, stop sending to it and notify the customer. Endless retries waste resources and hide the problem from the people who can fix it.
Set a short request timeout. Customers should acknowledge quickly and process asynchronously, the same advice you'd follow when receiving webhooks yourself.
Generate a unique signing secret for each subscription and show it to the customer once. Sign each request with HMAC-SHA256 over the raw body and a timestamp, and send the signature in a header.
Including the timestamp lets customers reject old requests and protects against replay. Document exactly how to compute and verify the signature, and provide example code in the languages your customers use.
Support secret rotation with a period where both old and new secrets are valid.
Validate destination URLs. Customers can enter any URL, including internal addresses. Block private IP ranges, localhost and cloud metadata endpoints, and resolve DNS at send time to prevent server-side request forgery.
Require HTTPS for production endpoints.
Respect tenancy. Every event belongs to one account. Only deliver it to subscriptions owned by that account, and check this at delivery time as well as at subscription time.
Limit payload contents. Don't include secrets or unnecessary personal data in payloads.
Tell customers plainly that events may arrive more than once and out of order. Include an event ID for deduplication and a timestamp or resource version so they can ignore stale updates. Guaranteeing strict ordering across a distributed delivery system is expensive, and most customers don't need it if they're told what to expect.
A basic webhook sender is quick to prototype. The ongoing work is in retries, endpoint health, signing, URL validation, logs and customer tooling. Some teams build this in-house; others use a dedicated webhook delivery service. The right answer depends on volume, how many event types you have, and how much customer-facing tooling you need.
Pathfix is not an outbound webhook delivery service for your own product events.
Where it helps is the other direction. If your product needs to react to events in your customers' *connected* accounts, such as a calendar change or a CRM update, Pathfix Automation can listen for supported user-level webhooks and run a configured workflow in that user's context. Pathfix OAuth manages the authorization those connections depend on.
You need some way to guarantee that an event is recorded whenever the underlying change is committed. An outbox table written in the same transaction is a common, reliable approach.