Webhook Tester
Construct HTTP requests, generate cURL commands, and preview raw HTTP — no requests sent from your browser
Content-Type is auto-injected from the selector below (unless you add it here manually).
Enter a URL above to generate the request output.
You’re integrating a payment webhook from Stripe. Before writing the handler code, you want to see exactly what the request looks like — headers, body, content type — and construct a matching cURL command to test your endpoint locally. You need to build the request visually and generate the cURL command, without setting up a tunnel or deploying anything.
Why This Tester (Not the HTTP Request Builder)
PureDevTools has an HTTP Request Builder for general HTTP requests with multiple output formats. This tool is focused on webhooks — construct webhook payloads, format the HTTP preview, validate JSON bodies, add custom headers, and generate cURL commands ready to paste into your terminal. Use the HTTP builder for general API requests; use this tester for webhook-specific workflows.
What Is a Webhook?
A webhook is an HTTP callback — a POST (or GET/PUT/PATCH) request sent automatically by one service to notify another service when an event occurs. GitHub sends webhooks when code is pushed, Stripe sends them when a payment succeeds, and Slack sends them when a message is posted. Unlike polling, where you repeatedly ask “did anything happen?”, webhooks push data to you the moment an event fires.
Because webhooks are just plain HTTP requests, you can inspect, replay, and debug them using standard tools like curl. This tool helps you construct those requests before you write any code.
How to Use This Webhook Request Builder
1. Select the HTTP Method
Most webhook payloads use POST. However, some services use:
| Method | When used |
|---|---|
POST | New event notifications (most common) |
PUT | Full resource updates |
PATCH | Partial resource updates |
DELETE | Resource deletion events |
GET | Ping / health-check webhooks |
GET requests have no body. The body editor hides automatically when GET is selected.
2. Enter the Endpoint URL
Paste the destination URL — the endpoint on your server that will receive the webhook. Examples:
https://api.myapp.com/webhooks/stripehttps://hooks.slack.com/services/T00/B00/xxxhttp://localhost:3000/webhook(local development)
3. Add Headers
Common webhook headers you may need:
| Header | Example value | Purpose |
|---|---|---|
Authorization | Bearer eyJ... | Authentication token |
X-Hub-Signature-256 | sha256=abc... | GitHub HMAC signature |
X-Webhook-Secret | mysecret | Shared secret validation |
X-Request-ID | uuid-v4 | Idempotency / tracing |
User-Agent | MyApp/1.0 | Sender identification |
The Content-Type header is injected automatically based on your body type selection — no need to add it manually unless you want to override it.
4. Choose a Content Type (body requests only)
| Content type | When to use | Body format |
|---|---|---|
application/json | REST APIs, most modern webhooks | JSON object or array |
application/x-www-form-urlencoded | Legacy systems, some payment gateways | key=value&key2=value2 |
text/plain | Simple string payloads | Any plain text |
When using application/x-www-form-urlencoded, you can paste a JSON object and the tool will automatically convert it to the correct encoded format.
5. Write the Request Body
For JSON bodies, the tool validates your JSON in real time and highlights any syntax errors. A green “Valid JSON” badge confirms the payload is parseable.
Example webhook body:
{
"event": "user.created",
"timestamp": "2026-01-15T10:30:00Z",
"data": {
"userId": "usr_abc123",
"email": "user@example.com",
"plan": "free"
}
}
6. Copy the Output
cURL Command — paste directly into your terminal to send the request:
curl -X POST 'https://api.myapp.com/webhooks/stripe' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer sk_test_abc123' \
-d '{"event":"payment.succeeded","amount":2999}'
HTTP Preview — the raw HTTP/1.1 format useful for understanding exactly what is sent:
POST /webhooks/stripe HTTP/1.1
Host: api.myapp.com
Content-Type: application/json
Authorization: Bearer sk_test_abc123
{"event":"payment.succeeded","amount":2999}
Webhook Security: Signature Verification
Most production webhook providers sign their payloads to prevent spoofing. Add the appropriate header:
| Provider | Signature header |
|---|---|
| GitHub | X-Hub-Signature-256: sha256=<HMAC-SHA256> |
| Stripe | Stripe-Signature: t=...v1=... |
| Shopify | X-Shopify-Hmac-Sha256: <base64-HMAC> |
| Slack | X-Slack-Signature: v0=<HMAC-SHA256> |
Your server should verify this signature before processing any webhook payload. Never trust a webhook without signature validation.
Debugging Webhooks Locally
When developing locally, use a tunnelling tool to expose your local server to the public internet so webhook providers can reach it:
# With ngrok (most common)
ngrok http 3000
# => https://abc123.ngrok-free.app → http://localhost:3000
# With Cloudflare Tunnel
cloudflared tunnel --url http://localhost:3000
Copy the public URL, use it as the webhook endpoint in the provider’s dashboard, then trigger a test event. Use this tool to construct a matching cURL command to replay the event without waiting for the provider.
Testing Webhook Payloads with cURL
The generated cURL command is immediately usable. Common flags you might add:
# Show response headers
curl -X POST 'https://...' -H 'Content-Type: application/json' -d '{}' -i
# Follow redirects
curl -X POST 'https://...' -d '{}' -L
# Verbose (shows full request + response)
curl -X POST 'https://...' -d '{}' -v
# Save response body to file
curl -X POST 'https://...' -d '{}' -o response.json
Common Webhook Patterns
Ping / Health Check
GET https://api.example.com/webhook/ping
Response: 200 OK
Event Notification
POST https://app.example.com/webhooks
Content-Type: application/json
X-Event-Type: order.placed
{
"event": "order.placed",
"orderId": "ord_789",
"amount": 4999,
"currency": "USD"
}
Retry Semantics
Most webhook systems retry delivery on failure (e.g., non-2xx response or timeout). Design your endpoint to be idempotent — processing the same payload twice should produce the same result. Use the X-Request-ID header or a payload id field to detect and deduplicate retries.
Frequently Asked Questions
Does this tool send actual HTTP requests? No. This tool is a request constructor — it generates cURL commands and HTTP previews that you copy and run in your own terminal. No requests are sent from your browser. This means your credentials and payload data never leave your device.
Why not send the request directly from the browser? Browser-based HTTP requests are subject to CORS (Cross-Origin Resource Sharing) restrictions. Most webhook endpoints do not serve CORS headers, so direct browser-to-endpoint requests would be blocked. The cURL command approach bypasses CORS entirely by running from your terminal.
Can I test webhooks to localhost?
Yes. Generate the cURL command with a http://localhost:PORT/path URL and run it from your terminal. The request goes directly to your local process.
How do I handle form-urlencoded bodies?
Select application/x-www-form-urlencoded as the content type and either type key=value&key2=value2 in the body, or paste a JSON object — the tool automatically converts it to the encoded format.
My provider uses a custom content type like application/webhook+json — can I use that?
Yes. Add a Content-Type header manually in the Headers section with your custom value. Manually-added Content-Type headers take precedence over the auto-injected one.
What is the HTTP Preview useful for? The HTTP preview shows the raw HTTP/1.1 wire format of the request — exactly what bytes a client sends over the socket. It is useful for documenting requests in runbooks, pasting into Postman’s import dialog (which accepts raw HTTP), and understanding the exact header and body format.