Webhook TestingWebhooksRequest CatcherAPI TestingIntegration TestingDeveloper Tools

How to Test Webhooks by Returning Custom Responses

Most webhook debugging tools let developers inspect incoming requests. But many integrations also depend on the response the endpoint returns—and testing only one side of that conversation is often not enough.

Payment providers retry on 500. CRMs disable integrations on repeated 4xx responses. Automation platforms pause workflows on timeouts. To test integrations properly, developers need to control both what they receive and what they send back.

Updated August 29, 202611 min readBy MockFlow Team

Why Webhook Responses Matter

Webhooks are not one-way notifications. The calling service reads the HTTP response your endpoint returns and often makes decisions based on it. Depending on the status code, the sender may:

  • Retry the request — most providers retry on 5xx responses and timeouts, sometimes for hours or days.
  • Mark the webhook as failed — repeated non-2xx responses can flag the delivery as permanently failed.
  • Disable the integration — some platforms automatically pause or disable webhook endpoints after sustained failures.
  • Trigger alerts— 4xx responses may immediately notify the sender's monitoring system.
  • Pause downstream workflows — automation tools like Zapier or Make halt a zap when the receiving endpoint returns an error.

Common response codes and their typical semantics in webhook integrations:

  • 200 OK — delivery confirmed. No retry.
  • 202 Accepted — payload received; processing asynchronously.
  • 401 Unauthorized — authentication failure; may disable the endpoint.
  • 404 Not Found — endpoint does not exist; no retry expected.
  • 500 Internal Server Error — transient failure; retry expected.

For a broader breakdown of status code behavior, see HTTP status codes every developer should test.

The Problem with Traditional Request Catchers

Traditional request catchers—tools like Webhook.site and RequestBin—are built around one primary use case: inspecting what arrives at a URL. They do that well. Developers can:

  • View the full request payload.
  • Inspect HTTP headers, query parameters, and method types.
  • Capture multiple requests in a session and compare them.

But most basic request catchers return a fixed 200 OK to every request. That means developers cannot:

  • Test how the sender behaves when the endpoint returns a 500.
  • Verify retry logic without setting up a real backend service.
  • Simulate authentication failures to check integration error handling.
  • Test delayed responses to see how timeouts are handled.

This gap forces developers to spin up custom Express servers, deploy temporary endpoints to staging, or write throwaway scripts just to simulate realistic response behavior. For more context on this limitation, see the best Webhook.site alternatives comparison.

What Is Custom Response Testing?

Custom response testing means configuring exactly what your endpoint returns to the calling service—before you write any production code. Instead of receiving requests passively, the endpoint actively participates in the integration test by returning a controlled response.

A configurable response typically includes:

  • HTTP status code — control whether the sender sees a success, client error, or server error.
  • Response body — return JSON, plain text, or an empty body to test how the sender parses responses.
  • Response headers — include custom headers like X-Request-ID, Retry-After, or Content-Type.
  • Response delay — introduce latency to simulate slow processing, network conditions, or timeout scenarios.

With these controls, a public testing URL can participate in the integration instead of only recording traffic. In MockFlow, the MockFlow request catcher covers inspection plus a configurable JSON response body. Custom status codes, headers, and delays are configured on mock API endpoints in the same project.

Example: Testing a Payment Webhook

Consider a Stripe-style payment webhook. Stripe sends a POST request to your endpoint when a payment succeeds:

POST /webhooks/stripe
Content-Type: application/json
Stripe-Signature: t=1234567890,v1=abc...

{
  "type": "payment_intent.succeeded",
  "data": {
    "object": {
      "amount": 4900,
      "currency": "usd",
      "id": "pi_3NxYZA..."
    }
  }
}

Scenario 1: Successful delivery. Configure the request catcher to return 200 OK with an empty body. Stripe considers the webhook delivered and does not retry.

HTTP/1.1 200 OK
Content-Type: application/json

{}

Scenario 2: Endpoint failure. Switch the response to 500 Internal Server Error. Stripe schedules a retry. Inspect the retried requests in the catcher to verify the retry interval, whether the payload is identical, and whether Stripe includes any retry-specific headers.

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
  "error": "Internal server error"
}

This two-scenario test validates both the happy path and the retry path without writing a single line of backend code.

Example: Testing Retry Logic

Most webhook providers implement automatic retries when the receiving endpoint fails. Common retry triggers include:

  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable
  • Connection timeout (no response within the provider's threshold)

To test retry behavior, return one of these error codes from the receiving endpoint—or from a MockFlow mock API profile—then watch incoming attempts. A Request Catcher is the right tool for inspecting each payload; it currently acknowledges delivery with HTTP 200 and a configurable JSON body. You can verify:

  • How many retry attempts the provider makes.
  • The time intervals between retries (exponential backoff vs fixed).
  • Whether the payload is byte-identical across retries.
  • Whether retry-specific headers like X-Webhook-Attempt are included.
  • When the provider gives up and marks the delivery as failed.

To simulate a timeout, configure a response delay on a mock API endpoint that is longer than the provider's timeout threshold. The request will hang, and the provider will eventually close the connection and retry. This lets teams confirm retry behavior before it happens in production.

Example: Testing Authentication Failures

Integrations often include authentication tokens or signatures in the request headers. Testing how the integration handles authentication failures requires returning the right error codes:

HTTP/1.1 401 Unauthorized
Content-Type: application/json
WWW-Authenticate: Bearer realm="api"

{
  "error": "Invalid or missing authentication token"
}

Or simulate a permission error where the caller is authenticated but not authorized:

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": "This endpoint does not accept requests from this source"
}

Returning these responses from a real URL lets you observe exactly how the sending platform behaves. Does it retry? Does it notify someone? Does it silently fail? Does it disable the integration? You can answer these questions during development rather than in production.

For a deeper dive into testing authentication-related status codes, see how to test API error responses.

How MockFlow Helps Test Both Sides of an Integration

MockFlow includes a webhook catcher for inbound inspection and mock API endpoints for outbound response simulation. Together they cover both sides of an integration without standing up a temporary backend.

Request inspection (Request Catcher):

  • Capture every incoming request in real time on a persistent public URL.
  • Inspect the full request body, headers, query parameters, and method.
  • View request metadata including timing and origin IP.
  • Replay a captured request to a target server when you are ready.

What the catcher returns today:

  • Custom response body — configure the JSON body sent back to the caller. Catchers currently respond with HTTP 200 and Content-Type: application/json.

Response simulation (mock API endpoints):

  • Custom status code — return any HTTP status (200, 202, 401, 404, 500, and more).
  • Custom response body — return JSON, plain text, or other body types.
  • Custom response headers — add headers the calling service expects or reads.
  • Configurable response delay — add milliseconds of latency to simulate slow processing or trigger timeout behavior.

This combination means developers can test both sides of the integration conversation without standing up temporary backend services or writing custom middleware.

For context on the broader webhook debugging workflow, see how to debug webhooks and inspect incoming requests.

Real-World Use Cases

Custom response testing applies across every type of integration that relies on webhooks or HTTP callbacks.

Webhook Development

During early development, before a real webhook handler exists, use a request catcher as a placeholder. Inspect payloads from the live provider, understand the data structure, and return appropriate status codes to prevent the provider from piling up retry attempts while the handler is being built.

Payment Provider Testing

Stripe, Paddle, and similar payment platforms send webhook events for payment success, failure, refunds, disputes, and subscription changes. Testing each event type—and each possible response code—confirms that your integration handles every payment lifecycle scenario, not only successful charges.

CRM Integrations

CRM platforms like HubSpot and Salesforce push updates when contacts, deals, or records change. Returning a 500 from the receiving endpoint shows whether the CRM will queue the update and retry, or silently drop it. Knowing this behavior before production prevents data loss in the integration.

Zapier Automations

Zapier sends webhooks as part of multi-step zap workflows. When a webhook step returns an error, the zap may pause, retry, or fail permanently. Testing these scenarios with controlled responses helps teams understand what happens to the rest of the workflow when one step fails.

Third-Party SaaS Integrations

Many SaaS tools offer webhook-based event notifications for user activity, billing changes, or status updates. Custom response testing confirms that slow responses do not cause duplicate deliveries, that auth headers are validated correctly, and that provider retry windows align with your system's recovery time.

Internal API Testing

Internal services that emit webhooks—job queues, data pipelines, event buses—benefit from the same approach. Use a request catcher to validate that internal producers send the correct payload format, include required headers, and handle receiver errors according to your team's SLAs.

Request Catcher vs Traditional Mock APIs

Request catchers and mock APIs overlap in some areas but serve different primary use cases. Here is a practical comparison:

CapabilityRequest CatcherMock API
Receive RequestsYesYes
Inspect PayloadsYes — live viewTypically no
Inspect HeadersYesTypically no
Return Custom ResponsesCustom JSON body (HTTP 200)Yes — status, body, headers
Simulate DelaysNoYes
Replay WorkflowsYesLimited
Integration TestingIdealGood for outbound calls
Frontend TestingNot primary useIdeal

Use a request catcher when a third-party service is pushing data to your endpoint and you need to observe what arrives and control what you return. Use a mock API when your own application is making outbound calls and you need to simulate the responses it receives. Many real workflows require both.

For a full overview of available tools, see the best mock API tools for developers guide, or read the API testing checklist for frontend teams.

Best Practices for Integration Testing

Effective integration testing with a request catcher goes beyond sending one request and calling it done. Here are practices that produce more reliable integrations:

  • Test success responses first. Confirm the payload format is correct and the provider marks the delivery as complete before moving to error scenarios.
  • Test failure responses intentionally. Return 500, 502, and 503 from a mock API or your handler to understand how retries work for each provider before relying on them in production.
  • Test retry behavior explicitly. Count incoming retry attempts, measure intervals, and confirm the payload is consistent across attempts.
  • Simulate response delays on mock APIs. Test how the sender handles slow responses and verify that your timeout thresholds are set appropriately.
  • Inspect request headers carefully. Authentication signatures, idempotency keys, and correlation IDs are often in headers—verify they are present and well-formed.
  • Validate payload structure. Confirm field names, types, nesting, and optional fields match your integration contract before writing handlers.
  • Verify authentication handling. Return 401 and 403 to confirm the sending platform does not silently ignore authentication failures.
  • Test edge cases. Missing fields, empty arrays, unexpected types, and duplicate event IDs—catch these during testing, not in production.
  • Document expected responses. Record which status codes trigger which provider behavior, and include this in integration documentation or runbooks.

Why This Workflow Saves Time

Without a public inspector URL and a way to simulate responses, testing integration behavior typically requires:

  • A temporary Express or Fastify server deployed somewhere publicly accessible.
  • Custom middleware to return different status codes based on test scenarios.
  • A local tunnel like ngrok to expose the server to the external webhook provider.
  • Manual coordination between the developer and the third-party service.
  • Teardown and cleanup after testing is complete.

This setup can take significant time per integration and per test scenario. A public Request Catcher removes the capture overhead: the URL is already reachable, incoming requests are stored automatically, and you can set the JSON body returned to the caller. Use mock API endpoints in the same project when you need specific status codes, headers, or delays.

The result is faster integration cycles, more thorough testing across response scenarios, and fewer surprises when a real webhook handler is deployed.

See how this fits into a broader testing strategy in the webhook debugging guide and the API error response testing guide.

FAQ

Why do webhook responses matter?

Webhook senders change behavior based on the HTTP response they receive. A 200 confirms delivery, a 500 triggers a retry, and a 401 may disable the integration. Controlling both sides of the conversation is necessary for thorough integration testing.

Can request catchers return custom responses?

Yes. MockFlow's Request Catcher lets you configure the JSON body returned to the caller. Catchers currently respond with HTTP 200. Custom status codes, headers, and delays are configured on mock API endpoints in the same project.

How do I test retry behavior?

Return 500, 502, or 503 from a mock API profile or your handler, or set a delay long enough to trigger a timeout. Most webhook providers retry automatically. Watch incoming requests to count retries, check the intervals, and verify the payload is consistent. Use a Request Catcher when you need to inspect those payloads.

What status codes should I test when building a webhook endpoint?

At minimum: 200 OK, 202 Accepted, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error, and timeout. Each exercises different sender behavior and is worth documenting explicitly for each provider you integrate with.

Can I simulate delayed webhook responses?

Yes. MockFlow mock API endpoints support a configurable response delay so you can test slow endpoints and connection timeouts without custom infrastructure. Set the delay above the provider's timeout threshold to observe timeout behavior. Request Catchers currently respond immediately.

Updated August 2026

Return a custom body from a catcher URL

Create a Request Catcher, set the response body the provider expects (often { "received": true }), paste the public URL into the dashboard, and fire a test event. Then replay that captured request to your local handler. Walkthrough: free request catcher.

Start testing integrations faster with MockFlow

Use MockFlow's Request Catcher to inspect incoming webhook payloads and return a configurable JSON body. Use mock API endpoints in the same project when you need custom status codes, headers, or delays.