Generate sample webhook payloads for Stripe, GitHub, Slack, Shopify and more. Sign them with an HMAC secret, add headers and POST to your endpoint. Free.
This payload generator produces realistic webhook request bodies for the services developers integrate most often, signs them with your signing secret, and can POST the signed request straight at your endpoint. It exists because building a webhook receiver otherwise means waiting for a real event to fire, or hand-writing JSON that is subtly wrong in the exact field your parser cares about. Pick a provider, pick an event, and you get the payload shape that provider actually sends — ready to copy into a fixture, a test suite or your API documentation.
Everything runs in the browser. Payload construction, secret generation and HMAC signing all happen client-side through the Web Crypto API, so your signing secret is never transmitted to us. The only network request made is the optional test POST, and that goes directly to the endpoint URL you type in.
Seventeen provider profiles ship with the tool, each carrying its own signature header name, signature algorithm and a set of representative events: Stripe, GitHub, Slack, Shopify, Twilio, SendGrid, Discord, PayPal, Mailchimp, HubSpot, Zendesk, Jira (Atlassian), Asana, Linear, Trello, PagerDuty and a Custom profile for your own service.
Events are the ones you actually build against — Stripe's payment_intent.succeeded, customer.subscription.created and charge.failed; GitHub's push, pull_request and issues; Shopify's orders/create, products/create and customers/create; Slack's message, app_mention and reaction_added; SendGrid's delivered, opened and clicked. The generated JSON is fully editable, so you can bend a template into the edge case you need to test — a null customer, a zero-amount charge, an unexpected extra field — and it stays signable.
A webhook endpoint is a public URL that accepts POST requests from anyone who finds it. Without verification, an attacker can forge a payment_intent.succeeded and get free goods. Providers solve this with an HMAC: they share a secret with you at subscription time, compute HMAC(secret, payload) over the exact raw request body, and send the result in a header. You recompute it and compare.
Each provider names that header differently, and the tool uses the correct one per profile — Stripe-Signature, GitHub's X-Hub-Signature-256 (with its sha256= prefix), X-Slack-Signature, X-Shopify-Hmac-SHA256, X-Twilio-Signature, PAYPAL-TRANSMISSION-SIG and so on. Algorithms differ too: most use HMAC-SHA256, Twilio uses SHA-1, and the encoding is hex for some providers and base64 for others. Getting any one of these details wrong produces a signature that never matches, which is the most common reason a working integration fails in staging.
A signature alone does not stop replay: a captured valid request can be resent indefinitely. Providers that care about this bind a timestamp into the signed string and send it in its own header — Stripe's t component, X-Slack-Request-Timestamp, PAYPAL-TRANSMISSION-TIME, X-Zendesk-Webhook-Signature-Timestamp. The tool generates a current timestamp and includes it in the signature computation for the profiles that require it, so what you send matches what production sends.
Three rules for the receiving side, in order of how often they are broken:
crypto.timingSafeEqual or your language's equivalent, never ==, so response timing cannot leak the expected signature byte by byte.The tool includes a verification mode that runs this comparison for you: paste a payload, a secret and a signature you received, and it tells you whether they match — useful for debugging a receiver that rejects real production traffic when you need to know which side is wrong.
If you are on the sending side and need a signing secret of your own, generate a random value rather than inventing one. The tool produces cryptographically random hex values using crypto.getRandomValues, which is the browser's CSPRNG — not Math.random(), whose output is predictable from a handful of observed values and is unfit for any security purpose. A 16-byte (32 hex character) value gives 128 bits of entropy, which is ample for HMAC signing. Use a different secret per environment and per consumer, so rotating one does not force you to rotate all of them, and store it as an environment variable rather than in code — the .env file generator will build the file for you.
If you are sending to a local development server, note that the request originates from your browser, so the endpoint must be reachable from it and must permit the cross-origin request — a localhost URL works, a private URL behind a VPN your browser cannot reach does not. For inspecting deliveries a provider is already sending you, use the webhook tester and inspector instead; to shape and replay arbitrary requests, the HTTP request builder is the broader tool.
A tool that builds a realistic request body for you instead of making you write one by hand. Here it produces webhook payloads matching the JSON structure that named providers actually send, so your handler is tested against the real shape.
Yes. Free, no account required, and no cap on how many payloads or signatures you generate.
Use the generator in the signing section, which draws random bytes from the browser's cryptographically secure random source. A 32-character hex value carries 128 bits of entropy and is more than sufficient for HMAC signing. Never build a secret from Math.random() or a memorable phrase.
Most use HMAC-SHA256; Twilio uses SHA-1. Encoding is hex for some providers and base64 for others, and GitHub prefixes its value with sha256=. Each provider profile here applies its own algorithm, encoding and header name automatically.
Yes. Enter your endpoint URL and the tool POSTs the payload with the signature header, timestamp header and any custom headers attached, then shows you the response status and body.
Nearly always because the receiver signs the parsed and re-serialised JSON rather than the raw request body. Whitespace and key order are part of the signed bytes. Capture the raw body before your JSON middleware runs.
No. HMAC computation happens in your browser via the Web Crypto API. The only outbound request is the optional test POST, which goes directly to the endpoint URL you supply.
Yes. The verification mode takes a payload, a secret and a signature and reports whether they match, which quickly settles whether a rejected delivery is the sender's fault or the receiver's.
Check the timestamp header alongside the signature and reject anything outside a tolerance window of about five minutes. Also record delivery IDs and ignore duplicates, since most providers retry and at-least-once delivery means your handler must be idempotent.
Yes. Choose the Custom profile, paste your own JSON payload, set your header name and secret, and sign it the same way.
Testing webhook integrations can be challenging because you need to trigger real events in third-party systems, which often requires complex setup or can have side effects. A webhook payload generator allows you to:
HMAC (Hash-based Message Authentication Code) signatures are the standard way to secure webhooks. Here's how they work:
Different providers use different signature formats:
t=timestamp,v1=signature - Includes timestamp for replay protectionsha256=signature - Simple SHA256 hash with prefixv0=signature with v0:timestamp:body signing formatNever trust webhook data without signature verification. An attacker could send fake webhook requests to your endpoint if you don't verify signatures.
// Example: Verifying a webhook signature (Node.js)
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
Always use HTTPS for webhook endpoints to protect data in transit. Webhooks may contain sensitive information like customer data, payment details, or authentication tokens.
Use timestamps or nonces to prevent replay attacks where an attacker resends a valid webhook request:
Create a local webhook endpoint or use a service like ngrok to expose your local server:
# Using ngrok to create a public URL
ngrok http 3000
# Your webhook URL: https://abc123.ngrok.io/webhook
Use the "Send Test Payload" feature to post the generated payload to your endpoint, or copy the curl command:
curl -X POST https://your-endpoint.com/webhook \\
-H "Content-Type: application/json" \\
-H "X-Webhook-Signature: sha256=abc123..." \\
-d '{"event": "test"}'
Test that your webhook endpoint correctly verifies signatures using the "Verify Signature" section. This helps you debug signature validation logic.
Stripe uses Stripe-Signature header with format: t=timestamp,v1=signature
// Stripe signature verification
const stripe = require('stripe');
const sig = request.headers['stripe-signature'];
try {
const event = stripe.webhooks.constructEvent(
request.body,
sig,
endpointSecret
);
// Handle the event
} catch (err) {
// Invalid signature
}
GitHub uses X-Hub-Signature-256 header with format: sha256=signature
// GitHub signature verification
const crypto = require('crypto');
const signature = request.headers['x-hub-signature-256'];
const hmac = crypto.createHmac('sha256', secret);
const digest = 'sha256=' + hmac.update(request.body).digest('hex');
const isValid = crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
Slack uses X-Slack-Signature with timestamp-based signing:
// Slack signature verification
const timestamp = request.headers['x-slack-request-timestamp'];
const signature = request.headers['x-slack-signature'];
// Check timestamp is recent (within 5 minutes)
if (Math.abs(Date.now() / 1000 - timestamp) > 300) {
throw new Error('Old timestamp');
}
const sigBasestring = `v0:${timestamp}:${request.body}`;
const mySignature = 'v0=' +
crypto.createHmac('sha256', secret)
.update(sigBasestring)
.digest('hex');
Problem: Generated signature doesn't match what your endpoint expects
Solutions:
Problem: Webhook payload fails to parse as JSON
Solutions:
Problem: Webhook requests timeout
Solutions:
Problem: Required headers not being sent
Solutions:
Our development team can help you design, implement, and secure webhook integrations for your applications. From signature verification to scalable webhook processing architectures, we have you covered.
A webhook is an HTTP callback that occurs when a specific event happens. Instead of constantly polling an API for updates, webhooks push data to your application in real-time. Testing webhooks is crucial because you need to ensure your endpoint correctly receives, validates, and processes incoming webhook data before going live. Using a payload generator allows you to test without triggering real events in production systems.
HMAC (Hash-based Message Authentication Code) uses a shared secret key to generate a cryptographic hash of the webhook payload. The sender creates the hash and includes it in the request headers. The receiver regenerates the hash using the same secret and compares it to the received signature. If they match, the payload is authentic and hasn't been tampered with. This prevents attackers from sending fake webhook requests to your endpoint.
Different providers use different signature algorithms (SHA256, SHA1, etc.) and formats to suit their specific needs. Some include timestamps for replay protection (Stripe, Slack), while others use simpler formats (GitHub, Shopify). The underlying principle is the same—HMAC-based authentication—but the implementation details vary. Always consult each provider's documentation for their specific signature format.
This tool is designed for development and testing purposes. While you can generate payloads that match production formats, you should never share production webhook secrets in any tool. Use development or test credentials, and test against development/staging endpoints. For production testing, use the provider's built-in test features or create separate test mode credentials.
SHA256 and SHA1 are different cryptographic hash algorithms. SHA256 produces a 256-bit (64 character hex) hash and is considered more secure. SHA1 produces a 160-bit (40 character hex) hash and is being phased out due to security vulnerabilities. Most modern providers use SHA256, but some older systems (like Twilio) still use SHA1 for backward compatibility. Always use the algorithm specified by your webhook provider.
Replay attacks occur when an attacker resends a valid webhook request. Protect against them by: 1) Checking timestamps—reject requests older than 5 minutes, 2) Using nonces—store and check one-time-use values, 3) Implementing idempotency—process each webhook only once using unique event IDs, 4) Logging all webhook attempts for audit trails. Providers like Stripe and Slack include timestamps in their signatures specifically for replay protection.
Your webhook endpoint should return a 2xx status code (typically 200 or 204) as quickly as possible to acknowledge receipt. Process the webhook asynchronously in a background queue rather than during the HTTP request. Return 4xx for client errors (invalid signature, malformed payload) that shouldn't be retried, and 5xx for server errors that should be retried. Most providers will retry failed webhooks with exponential backoff.
For local development, use a tunneling service like ngrok, localtunnel, or Cloudflare Tunnel to expose your local server to the internet with a public URL. These services create a secure tunnel to your localhost, allowing webhook providers to send requests to your development machine. Remember to use test/development credentials and never expose production secrets. Alternatively, use this tool to manually send test payloads to your local endpoint.
Common reasons for signature verification failures: 1) Using the wrong algorithm (SHA256 vs SHA1), 2) Signing a modified payload (JSON formatting, whitespace changes), 3) Character encoding issues (ensure UTF-8), 4) Missing or incorrect timestamp in timestamp-based signatures (Stripe, Slack), 5) Including/excluding headers in the signed data incorrectly, 6) Secret key mismatch or typo. Always sign the exact raw payload bytes without any modifications.
Production webhook best practices: 1) Always verify signatures—never trust unverified webhooks, 2) Use HTTPS endpoints only, 3) Implement replay protection with timestamps/nonces, 4) Process webhooks asynchronously in queues, 5) Return 2xx responses immediately, 6) Store secrets in environment variables or secret managers, 7) Log all webhook attempts for debugging, 8) Implement idempotency using event IDs, 9) Set up monitoring and alerting for failed webhooks, 10) Test thoroughly in staging before production deployment.
Yes! The Monaco code editor allows you to fully customize webhook payloads. Edit the JSON directly in the editor to test different scenarios, edge cases, or custom fields specific to your integration. The editor includes syntax highlighting and validation to help catch JSON errors. You can also save modified payloads for later use or share them with your team for consistent testing.
To debug signature validation: 1) Log the raw payload bytes being signed, 2) Log the generated signature from your code, 3) Compare with the signature from this tool, 4) Verify you're using the correct algorithm and secret, 5) For timestamp-based signatures (Stripe, Slack), log the timestamp being used, 6) Check that no middleware is modifying the payload (body parsers, compression), 7) Use constant-time comparison (timingSafeEqual) to prevent timing attacks, 8) Test with the Verify Signature feature to confirm your logic matches the provider's specification.