Back to blog

Webhook Setup Guide: Step-by-Step Tutorial

Webhook setup guide for developers and no-code teams: create, test, and secure webhook endpoints, fix delivery issues, and avoid duplicates.

WG

WebhookGuide

April 27, 2026

Introduction

A webhook setup guide should get you from “I know I need this” to a working, secure integration without guesswork. Whether you’re wiring Stripe payment events into your app, reacting to GitHub pushes, syncing Shopify orders, sending Slack alerts, or automating Salesforce workflows, the core task is the same: create an endpoint that receives the right payload, handles the right headers, and responds reliably when the source app sends an event.

This guide is for developers, no-code users, and ops teams working in tools like Zapier, Make, and Pipedream, as well as teams building directly against an app’s API. By the end, you’ll know how to create, test, and secure a webhook endpoint, how to troubleshoot delivery failures, and how to avoid duplicate processing. If you need a refresher on the basics first, start with what is a webhook; if you want a broader implementation perspective, the webhook guide for developers adds more context.

The workflow is straightforward: understand how webhooks work, prepare prerequisites, create the endpoint, configure the event source, test delivery, and troubleshoot issues. The same process applies whether you’re writing code or using a no-code platform.

What Is a Webhook?

A webhook is an event-driven HTTP callback: when something happens in one app, it sends a POST request to another app’s endpoint with a payload of data. The receiving app listens for incoming requests and reacts immediately.

That makes webhooks different from polling, where an app repeatedly checks for updates on a schedule. Webhooks push data only when an event occurs, which is faster and more efficient.

They also differ from a typical API flow. With an API, your app usually requests data on demand; with a webhook, the event triggers the delivery automatically.

Common uses include Stripe payment notifications, Typeform form submissions, GitHub push events, Shopify order updates, Slack alerts, Salesforce CRM updates, and automation flows in Zapier, Make, and Pipedream.

How Webhooks Work

A webhook follows a simple event-driven flow: something happens in the source app, such as a Stripe payment succeeding or a GitHub push landing, and the app sends an HTTP POST request to your endpoint. Your server receives the request, reads the payload and headers, and processes the event, such as creating an order, updating a record, or triggering a Slack alert.

A webhook request usually includes the HTTP method, a JSON payload, headers for authentication or signature verification, and metadata like event type or delivery ID. Some providers use XML or application/x-www-form-urlencoded instead of JSON, so your handler should check the Content-Type header before parsing. Your endpoint should return a successful 2xx status code when it accepts the event. If it returns an error or times out, providers use retry logic to resend the delivery because they assume the failure was temporary.

Webhooks are usually outbound from the source app and inbound to your system, which is why this guide focuses on exposing a reliable endpoint that can receive and acknowledge requests quickly.

What You Need Before Creating a Webhook

Before you start, make sure you have permission in the source app to create or edit the webhook, access to the destination app or server that will receive it, and the event type you want to listen for. Stripe, GitHub, Shopify, Slack, and Salesforce all require you to select specific event types in their dashboards.

For real delivery, the receiver usually needs a public HTTPS endpoint. A local localhost URL cannot receive traffic from external services, so use a deployed server or a tunnel like ngrok during development. For quick inspection, RequestBin and webhook.site give you temporary endpoints that show incoming payloads and headers.

Separate sandbox environment testing from production environment setup. A sandbox environment lets you verify payload shape, retries, and authentication without affecting live data; a production environment uses real events and real credentials. Before configuring either, collect any shared secret, API key, or signature verification details required by the source app. Use the webhook testing checklist to confirm you have everything ready.

Step-by-Step Webhook Setup

  1. Identify the source app and open its webhook or integration settings. In Stripe, GitHub, Shopify, Slack, and Salesforce, this is where you choose what event to send and where to send it. If you use Zapier, Make, or Pipedream, the source may be a trigger module that exposes a webhook URL or a connector setting.

  2. Create a stable HTTPS endpoint with a clear route, such as /webhooks/stripe, and code it to accept POST requests. Keep the handler fast, return a 2xx response after validation, and verify signatures or secrets in headers before processing; see the webhook endpoint setup guide.

  3. Select the exact event, not a broad feed. Use payment_intent.succeeded in Stripe, push in GitHub, or orders/create in Shopify so you only process relevant changes.

  4. Add the endpoint URL in the source app, then configure any required signing secret or custom headers.

  5. Send a test event, inspect the payload and request headers, and confirm your server returns success. Use the webhook testing checklist and webhook implementation checklist to catch missing auth, bad routes, or failed retries.

How to Create a Webhook Endpoint

A webhook endpoint is just a server route that can receive an incoming HTTP request and respond quickly. In practice, that means exposing a URL over HTTPS, parsing the request body, validating the signature, and returning a 2xx status code only after the event has been accepted.

A good webhook URL should be stable, unique, and hard to guess. Use a clear path like https://example.com/webhooks/stripe rather than a generic route. Avoid query strings unless the provider requires them, and do not rely on localhost for production delivery. If you need to test locally, use ngrok or a similar tunnel to expose your local server.

Your handler should do as little work as possible before responding. If the event triggers slow processing, queue the job and return success first so the provider does not retry unnecessarily.

Common Webhook Payload Formats, Verification, and Debugging

A webhook payload is the data sent in the request body. It usually includes an event_type, timestamp, object data, and IDs such as event_id or resource_id. JSON is the most common format, used by Stripe and GitHub; some systems still send XML or application/x-www-form-urlencoded for older integrations. Check the Content-Type header before parsing, and document expected fields in your webhook documentation best practices.

Verify authenticity by recomputing the HMAC signature with your shared secret and comparing it to headers like X-Signature; use X-Request-Id to trace a single delivery across systems. If a request fails, inspect request logs on your server and delivery logs in the source app to see the exact status codes and retry behavior. Handle idempotency by storing event IDs so repeated deliveries from retry logic do not create duplicates. Common failures map to 400 malformed payload, 401/403 bad auth or signature, 404 wrong endpoint, 415 unsupported format, and 500 server errors.

How to Test a Webhook

Testing should cover both the happy path and the failure path. Start by sending a test event from the provider’s dashboard, then confirm your endpoint receives the request, parses the payload, and returns a 2xx response. If the provider supports it, compare the test delivery with a real event in a sandbox environment so you can verify that the payload shape matches production expectations.

You can also test with RequestBin or webhook.site to inspect the exact headers and body your endpoint would receive. For local development, ngrok lets you forward a public HTTPS URL to your machine so you can test without deploying first.

When testing, check that signature verification passes, the Content-Type header matches your parser, and duplicate deliveries do not create duplicate records. The webhook testing checklist is useful here, especially if you need to confirm retries, status codes, and error handling.

How to Secure a Webhook Endpoint

Use HTTPS for every webhook endpoint and make sure the server presents a valid TLS certificate. Without TLS, anyone on the network path can inspect or tamper with payloads, which defeats the point of secure event delivery.

Treat every webhook URL as sensitive. Protect it with a shared secret and verify each request with an HMAC signature or the provider’s equivalent signing method. Rotate secrets on a schedule, and update both sides carefully so you do not break delivery in the production environment.

Defense in depth matters. If the provider publishes source IP ranges, add an IP allowlist; combine that with rate limiting to reduce abuse and payload validation to reject malformed or unexpected data before it reaches your business logic. Keep permissions narrow so the receiving service only has the access it needs, especially if the webhook triggers database writes or downstream automation.

Before launch, run through a webhook implementation checklist and confirm the endpoint is live, the correct event is selected, signature verification works, tests pass, logs are enabled, and retries are understood. Build for duplicates with idempotency so repeated deliveries do not create duplicate orders, tickets, or records.

Why Webhooks Fail and How to Debug Delivery Problems

If a webhook is not working, start with the basics: confirm the URL is correct, the endpoint is reachable over HTTPS, and the source app is sending the event you expect. A wrong route, expired TLS certificate, or typo in the webhook URL can stop delivery immediately.

Next, compare the provider’s delivery logs with your server’s request logs. Look for the status code returned by your endpoint, the request body, the X-Signature header, and the X-Request-Id value so you can trace one delivery end to end. If the provider shows retries, check whether your endpoint timed out, returned a 4xx or 5xx response, or rejected the payload because the parser expected a different format.

If the event arrives but nothing happens, the problem is often in your application logic rather than the webhook transport. Verify that the handler is reading the correct event type, that idempotency checks are not discarding valid events, and that background jobs or queues are processing successfully.

Webhook Retries and Duplicate Event Prevention

Most providers retry failed deliveries when they do not receive a successful 2xx response. Retry logic usually kicks in after a timeout or server error, then repeats the request until the provider gives up or the delivery succeeds. That is why a webhook endpoint should respond quickly and avoid long-running work.

Because retries can resend the same event, you need idempotency. Store the provider’s event ID, delivery ID, or another unique key before processing, and skip the event if you have already handled it. This prevents duplicate orders, duplicate tickets, and repeated notifications.

If the provider includes a retry count or delivery attempt number, log it alongside the event so you can tell whether a failure is new or a repeat. This also helps when comparing request logs with delivery logs during debugging.

Common Webhook Setup Mistakes

The most common mistakes are simple: using the wrong URL, forgetting to expose a public HTTPS endpoint, parsing the wrong payload format, skipping signature verification, and returning a slow response that triggers retries.

Other frequent issues include testing only in production, ignoring sandbox environment differences, failing to document expected headers and payload fields, and not using idempotency to prevent duplicate processing. Teams also run into trouble when they assume every provider uses the same JSON structure or when they hard-code secrets instead of rotating them safely.

If you want a final pass before launch, compare your setup with the webhook implementation checklist, the webhook endpoint setup guide, and the webhook documentation best practices.

Webhooks vs APIs

Webhooks and APIs both move data between systems, but they work differently. An API is usually request-driven: your app asks for data when it needs it. A webhook is event-driven: the source app sends data automatically when something happens.

That difference matters for design. APIs are better for fetching current state on demand, while webhooks are better for reacting to changes in near real time. In many systems, you use both: an API to fetch details after a webhook arrives, and a webhook to tell you when to fetch them.

Final Checklist

  • Use a stable HTTPS endpoint with a valid TLS certificate
  • Accept POST requests and return a fast 2xx response
  • Parse the correct payload format: JSON, XML, or application/x-www-form-urlencoded
  • Verify the HMAC signature with your shared secret
  • Log request logs, delivery logs, X-Signature, and X-Request-Id
  • Test in a sandbox environment before production environment rollout
  • Use ngrok, RequestBin, or webhook.site for local testing
  • Add idempotency so retries do not create duplicates
  • Apply IP allowlist and rate limiting where appropriate
  • Review the webhook testing checklist before launch