Webhook Guides
What Are Webhooks? Developer Guide
Webhooks are HTTP callbacks sent when something happens in another system. Instead of polling an API on a schedule, your application receives event notifications as soon as the provider is ready to send them.
They are the backbone of many SaaS integrations: Stripe sends payment updates, GitHub sends push and pull request events, Shopify sends order changes, Twilio sends message status updates, and internal services send lifecycle events to automation workflows.
This page explains how webhooks work in production, where webhook integrations usually break, and how FastHook helps you receive traffic through sources, route it through connections, inspect requests, debug failed attempts, and replay events safely.
What is a webhook?
A webhook is an HTTP request sent by a provider to a URL you control. The URL is usually called a webhook endpoint, callback URL, source URL, or receiver URL. The request usually includes HTTP headers, an event type, and a JSON payload that describes what changed.
In a normal API workflow, your application asks another service for data. In a webhook workflow, the provider calls your application when it has something to report. That difference sounds small, but it changes how you design reliability: webhooks need fast acknowledgment, durable request capture, retry handling, duplicate protection, signature validation, and useful delivery logs.
Webhooks vs APIs and polling
Webhooks do not replace APIs. Most integrations use both. APIs are useful when your application needs to read or mutate current state. Webhooks are useful when another system needs to notify your application about changes without waiting for your next polling interval.
| Pattern | Who starts the request | Best for | Operational risk |
|---|---|---|---|
| API call | Your application | Fetching current state or performing a command | Rate limits, auth errors, slow responses |
| Polling | Your application on a schedule | Simple sync jobs where delay is acceptable | Wasted requests, stale data, missed edge cases |
| Webhook | The provider or event producer | Real-time event delivery and automation | Retries, duplicates, signature errors, endpoint downtime |
How webhooks work
- Create a webhook endpoint or FastHook source URL.
- Register that URL in the provider dashboard or internal event producer.
- The provider sends an HTTP request when an event happens.
- FastHook captures the inbound request, headers, and body before routing.
- Matching connections create destination-specific events.
- Each connection can apply filters, transformations, retries, delays, deduplication, or throughput limits.
- FastHook delivers the event to the configured destination and records the attempt status.
- Your destination returns a 2xx response when it accepts the event.
Webhook request anatomy
Most webhook requests are simple HTTP POST requests, but the details matter during debugging and signature validation. Treat the request as a contract between the provider, your ingress layer, and your destination service.
- Method and URL: usually
POSTto a dedicated webhook endpoint or FastHook source URL. - Headers: often include content type, event type, delivery id, user agent, signature, and timestamp fields.
- Payload: usually JSON with an event id, event type, creation time, and provider-specific data object.
- Signature: an HMAC or provider-specific signature that should be verified against the raw request body.
- Response: a fast 2xx response tells the sender the request was accepted; it does not prove every downstream side effect completed.
Common webhook use cases
- Payment and billing updates, such as invoice paid, payment failed, or subscription changed.
- Developer workflow events, such as GitHub push, pull request, deployment, issue, or workflow run events.
- Commerce events, such as order created, order fulfilled, product updated, or inventory changed.
- Messaging and communications events, such as delivery status, inbound SMS, call events, or email bounces.
- Internal automation, such as user lifecycle changes, audit events, service notifications, and data sync jobs.
Common webhook problems
- Endpoint downtime: the provider cannot reach your receiver, or the receiver returns a non-2xx response.
- Timeouts: the receiver does too much synchronous work before returning a response.
- Duplicate events: retries repeat the same event and the destination applies the same side effect twice.
- Signature validation failures: the receiver validates against parsed JSON instead of the raw body or uses the wrong signing secret.
- Schema drift: provider payloads change, optional fields disappear, or event types differ from the test fixture.
- Low observability: payloads, headers, attempts, response codes, and response bodies are not visible together.
- Retry storms: traffic spikes and provider retries overload a destination that is already failing.
How FastHook solves this
FastHook acts as a webhook gateway between event producers and your downstream services. It gives you stable source URLs, request inspection, outbound event history, delivery attempts, filtering, transformations, retries, deduplication, throughput controls, pause/resume workflows, and replay.
That separation lets you accept provider traffic even when one destination is unhealthy. You can inspect the original request, see which route failed, read the destination response, fix the receiver, and replay only the events that need another delivery attempt.
Webhook testing checklist
A good webhook test covers more than one successful curl request. Before production traffic arrives, test the behaviors that usually fail during incidents.
- Send realistic payloads for each event type you expect to support.
- Confirm the inbound request is captured with headers and raw body.
- Validate signature handling with the same raw-body behavior used in production.
- Send duplicate events and verify idempotency before side effects run twice.
- Simulate destination 4xx, 5xx, and timeout responses.
- Inspect retry attempts and confirm backoff does not overload the receiver.
- Replay a failed event into staging or localhost before replaying a production batch.
Webhook security basics
A public webhook endpoint should not trust payload fields just because the request reached the URL. Security starts at ingress and continues at destination delivery.
- Use provider signatures or FastHook source authentication where available.
- Verify signatures against the raw request body, not a re-serialized JSON object.
- Use separate source URLs and signing secrets for production, staging, and local testing.
- Restrict allowed HTTP methods, content types, and destination behavior where possible.
- Rotate secrets deliberately and keep enough logging to debug failed verification.
Webhook retry and replay strategy
Webhooks are usually at-least-once delivery. That means duplicates are normal, especially when a provider times out or a receiver returns a non-2xx response. Your receiver should treat the event id, delivery id, or business object id as an idempotency boundary before creating side effects.
Retries are best for temporary destination failures. Replay is best when you need to redeliver stored events after fixing code, credentials, schema handling, or a downstream outage. In both cases, inspect the original payload and destination response before redelivering a large batch.
FastHook API shape
The workflow examples below match the current FastHook control API implementation. Authenticated control API calls use a project API key or session token, tenancy comes from x-team-id, and the /v1 prefix is supported for sources, requests, events, and attempts.
- Sources return a generated
urlsuch ashttps://hook-xxxxxx.fasthook.io/. - Source configs support
auth_type,auth,custom_response, andallowed_http_methods. - Request lists support
from,to,source_id,status, cursors, andinclude=data. - Event lists support
source_id,connection_id,destination_id,status,from, andto. - Delivery attempts are read from
/v1/attempts, and a single failed event can be retried withPOST /v1/events/:id/retry.
FastHook workflow examples
Create a source for inbound webhook traffic
curl -X POST "https://api.fasthook.io/v1/sources" \
-H "Authorization: Bearer fhp_xxx" \
-H "x-team-id: tm_3b5335b627084a838b" \
-H "Content-Type: application/json" \
-d '{
"name": "Provider webhooks",
"description": "Ingress for provider webhook traffic",
"type": "WEBHOOK",
"status": "enabled",
"config": {
"auth_type": null,
"auth": null,
"allowed_http_methods": ["POST"]
}
}'Send a test webhook (curl)
curl -X POST "https://hook-xxxxxx.fasthook.io/" \
-H "Content-Type: application/json" \
-H "X-Event-Type: payment.succeeded" \
-d '{
"id": "evt_123",
"type": "payment.succeeded",
"created_at": "2026-04-20T10:00:00Z",
"data": {
"customer_id": "cus_42",
"amount": 1999,
"currency": "USD"
}
}'Example webhook payload (JSON)
{
"id": "evt_123",
"type": "invoice.paid",
"attempt": 1,
"timestamp": "2026-04-20T10:00:00Z",
"data": {
"invoice_id": "inv_001",
"customer_id": "cus_42",
"total": 4900,
"currency": "USD"
}
}Inspect captured requests
curl "https://api.fasthook.io/v1/requests?source_id=src_q6z62b6py5o79b&from=now-24h&to=now&status=accepted&limit=20&include=data" \
-H "Authorization: Bearer fhp_xxx" \
-H "x-team-id: tm_3b5335b627084a838b"Inspect routed events for the source
curl "https://api.fasthook.io/v1/events?source_id=src_q6z62b6py5o79b&from=now-24h&to=now&limit=20" \
-H "Authorization: Bearer fhp_xxx" \
-H "x-team-id: tm_3b5335b627084a838b"Inspect destination attempts for one event
curl "https://api.fasthook.io/v1/attempts?event_id=evt_01jv8c4n9p3x7r2t6q5m1k0s8b&order_by=created_at&dir=desc&limit=20" \
-H "Authorization: Bearer fhp_xxx" \
-H "x-team-id: tm_3b5335b627084a838b"Retry a failed destination event
curl -X POST "https://api.fasthook.io/v1/events/evt_01jv8c4n9p3x7r2t6q5m1k0s8b/retry" \
-H "Authorization: Bearer fhp_xxx" \
-H "x-team-id: tm_3b5335b627084a838b"Webhook FAQ
What is a webhook in simple terms?
A webhook is an HTTP request sent by one app to another app when an event happens, such as a payment succeeding, a repository receiving a push, or an order being created.
Are webhooks the same as APIs?
No. An API is usually called by your app when it wants data or an action. A webhook is called by another system when that system wants to notify your app about an event.
What should a webhook endpoint return?
A webhook endpoint should return a fast 2xx response after the request is accepted. Expensive processing should usually happen after durable capture so provider timeouts do not create avoidable retries.
Why do duplicate webhook events happen?
Duplicates happen because providers retry after timeouts, network errors, and non-2xx responses. Receivers should use idempotency keys or event ids before applying side effects.
How do you debug webhook delivery failures?
Compare the inbound request, routed event, destination attempt, response code, response body, retry count, and payload shape. FastHook keeps these records together so failures can be inspected and replayed.
Try FastHook
Create a FastHook source, connect it to a destination, send test events, inspect inbound requests, and replay failed outbound events from one place. This gives your team a reliable webhook workflow without rebuilding request logs, local forwarding, retries, and replay tooling inside every application.
Related guides
- Webhook testing
- Webhook debugging
- Webhook endpoints
- Webhook request example
- Receive webhooks
- Verify webhooks
- Source authentication
- Destination delivery signatures
- Webhook replay systems
- Why 200 OK does not guarantee processing
- Stripe webhooks
- Stripe webhook example
- GitHub webhooks
- GitHub webhook payload
- GitHub push event payload
- GitHub pull request webhook
- GitHub webhook headers
- GitHub signature validation
- GitHub retry strategy
- Shopify webhooks
- Twilio webhooks
- Public hook pages