Data

Webhook Payload Generator

Get realistic JSON payloads to test webhooks without relying on real events. Cover success cases, errors, and common edge cases.

Instant🔒In your browserNo signup
Live
    View as text

    Why test webhooks with real payloads

    Developing webhook integrations without reliable test payloads leads to production bugs. Most common mistake: assuming all events have the same shape. GitHub can send push events with no commits (forced), Stripe includes variable metadata depending on customer plan, and Slack changes structure by message type.

    Using generated payloads prevents three critical issues: breaking deploys when the provider updates their API, not handling edge cases (partial refunds, unanswered calls), and testing only happy path. Payloads here include 550 errors, disputes, and cancelled events many devs forget.

    Real example: a startup lost $12k because their Stripe webhook didn't handle payment_intent.payment_failed with card_declined error. They assumed all failed payments happened silently. Test payloads reveal these scenarios before deploying.

    Typical payload structure by provider

    GitHub structures events with action (opened, closed), repository, and the affected object (issue, PR, release). Always includes sender. Stripe uses type (dot notation) and nests data in object. Pattern: resource.event (customer.created, invoice.paid).

    Slack and Discord use numeric or string type. Slack includes nested event for app mentions, Discord differentiates interactions (type 2 = slash command, type 3 = button). Shopify uses topic with slash notation: orders/create, products/update.

    Twilio is REST-style: all fields top-level (MessageSid, CallStatus, From). Mailgun uses simple event (delivered, bounced) with metadata in message. Knowing these patterns speeds debugging: if you see type string + data.object, it's Stripe; if you see MessageSid, it's Twilio.

    Edge cases that break integrations

    Test payloads must include: empty arrays (GitHub push with no commits), null values (Stripe customer without email), missing fields (Slack messages without text when it's file_share). Also: duplicate events (Shopify resends if no 200 in 5s), and giant payloads (Zoom 3-hour recordings).

    Common errors: not validating refunded: true in Stripe charges (amount can be partial), assuming Discord interactions always have member (DMs don't include it), and not checking attempt_count in invoices (Stripe retries up to 4 times).

    A Twilio payload with NumMedia > 0 requires parsing MediaUrl0, MediaUrl1... dynamically. GitHub pull_request can have mergeable: null (calculating), not just true/false. Mailgun permanent vs temporary bounces change retry logic.

    Effective local testing strategy

    Use tools like ngrok or webhook.site to receive requests locally. Set up a /webhooks/:provider route that logs the complete payload. Important: verify signatures (GitHub uses HMAC-SHA256, Stripe has its own lib).

    Recommended structure: one handler per provider with schema validation (Zod, Joi). Log unknown payloads to Sentry to detect API changes. Implement idempotency: save event.id or MessageSid in Redis/DB to ignore duplicates.

    For CI/CD: commit sample payloads to tests/fixtures/webhooks/ and write tests that run them through your handler. Mock signatures with test secret. This prevents regressions when refactoring webhook code. Most webhook bugs are validations that fail silently.

    FAQ

    Why are payloads formatted as escaped JSON strings?

    To copy them directly into your code. You can JSON.parse() or paste into a test. Also works for logs and debugging.

    Are these payloads real or fictional?

    They're real structures based on official provider documentation, with fictional data (invented IDs, emails, timestamps).

    How do I handle payloads from unlisted providers?

    Look for 'Webhook Examples' section in their API docs. Most include sample payloads. Alternatively, create a temporary endpoint with webhook.site.

    Should I verify signatures in development?

    Yes, always. Use the provider's test secret. This prevents bugs where payload passes in dev but fails in production due to invalid signature.

    Was this generator useful?