GuideSaaSAPIWebhooksBackend

API and Webhook Integration Basics for SaaS Builders

Most SaaS products are integrations — they send and receive data from external systems via APIs and webhooks. This guide covers the two fundamental patterns (request-response and event-driven), explains how to debug both when they fail, and introduces the tools that make integration work faster.

TL;DR

  • APIs are request-response: your code asks, the server answers.
  • Webhooks are event-driven: the server pushes data to your endpoint when something happens.
  • • Most integration bugs are payload parsing errors, missing headers, or misconfigured endpoints.
  • • Debug by capturing the raw request first, then writing the handler.
  • • Use the Webhook Tester to receive and inspect webhooks before you write a single line of handler code.

1. What APIs and Webhooks Are

An API (Application Programming Interface) is a structured contract that lets two systems communicate. In web integrations, this almost always means HTTP-based APIs: your application sends an HTTP request (GET, POST, PUT, DELETE) to a remote server, and the server sends back a response — typically JSON.

A webhook is an HTTP callback: instead of your system asking for data, the remote system sends data to you. You register a URL (your endpoint), and when an event occurs in the remote system, it sends an HTTP POST to that URL with the event payload in the body.

ConceptDirectionTriggered byTypical use
API callYou → themYour codeFetch data, create resources, query state
WebhookThem → youRemote eventPayment completed, order shipped, user signed up

2. Request-Response vs Event-Driven Systems

Request-response is the older and simpler pattern. Your code controls when data is fetched. This works well for on-demand queries (look up a user, create a record, check a status). The downside: if you need to know when something changes, you have to keep asking — a technique called polling.

Event-driven (webhooks) inverts this: the data finds you. When a payment completes in Stripe, Stripe sends a payment_intent.succeeded event to your registered endpoint. No polling, no delay.

Most modern SaaS products use both: APIs for querying and creating resources, webhooks for receiving real-time notifications. See Webhooks vs Polling for a detailed comparison.

3. Typical Integration Workflows

API integration flow

  1. Obtain credentials (API key, OAuth token, client secret).
  2. Construct the request — set the method, URL, headers (Authorization, Content-Type), and body.
  3. Send the request; check the HTTP status code (200, 201, 400, 401, 403, 404, 429, 500).
  4. Parse the response body — usually JSON.
  5. Handle errors and retry logic (check for Retry-After headers on 429).

Webhook integration flow

  1. Register your endpoint URL in the provider's dashboard.
  2. Receive the POST request at your endpoint — return a 200 OK immediately.
  3. Verify the webhook signature (HMAC-SHA256 or similar) to confirm authenticity.
  4. Parse the event type and route to the appropriate handler.
  5. Process asynchronously — do not block the HTTP response with slow operations.

4. Debugging API Calls

When an API call fails, start with the response body — not the status code. Status codes tell you the category of error; the body tells you what went wrong.

Common causes by status code:

StatusMeaningCheck first
400Bad RequestRequest body / query params format
401UnauthorizedAuthorization header — token present and valid?
403ForbiddenScopes / permissions — does the token have access?
404Not FoundURL path — typo, wrong version, resource deleted?
422UnprocessableBusiness logic validation — read the error field in body
429Rate LimitedRetry-After header; implement exponential backoff
500Server ErrorProvider-side issue; check their status page

Use the API Response Formatter to pretty-print and inspect the raw response body — especially useful for large or nested JSON error objects.

5. Debugging Webhook Payloads

The hardest part of webhook development is that the sender controls the payload — you can't easily reproduce it locally. The safest workflow:

  1. 1.Capture the raw request first. Use the Webhook Tester to receive the live event from the provider. This shows you the exact headers, method, and body before you write any handler code.
  2. 2.Check the signature header. Stripe sends Stripe-Signature; GitHub sends X-Hub-Signature-256. These are HMAC-SHA256 hashes of the raw body using your webhook secret. Verify before trusting the payload.
  3. 3.Return 200 immediately. Most providers retry if your endpoint doesn't respond within a few seconds. Offload heavy processing to a queue.
  4. 4.Handle duplicates. Webhooks can arrive more than once (network retries). Use the event ID to deduplicate: store seen IDs and skip processing if the ID has already been handled.

Never trust a webhook without verifying its signature. Anyone can send a POST to your public endpoint. Always validate the HMAC signature using the raw request body (before parsing) and your shared secret.

6. Common Integration Mistakes

Parsing the body before verifying the signature

Signature verification must use the raw bytes of the request body — not the parsed JSON. Parsing first may alter whitespace or key ordering, breaking the HMAC comparison.

Not returning 200 quickly enough

If your webhook handler takes more than 5–10 seconds (provider-dependent), the provider marks the delivery as failed and retries. Move slow operations (database writes, email sends) to an async queue.

Missing the Content-Type header on API requests

Many APIs reject POST requests without Content-Type: application/json. Use the Cookie Parser and Query String Parser to inspect request components when debugging unexpected 400 errors.

Ignoring retry logic

On 429 Too Many Requests, check the Retry-After header and implement exponential backoff. Retrying immediately worsens rate-limit situations.

Storing webhook payloads synchronously

If your database is slow or down when a webhook arrives, your endpoint returns a 500, the provider retries, and you end up with duplicates. Use an idempotency key (the event ID) and process asynchronously.

Try the Tools

These tools accelerate the debugging workflows described in this guide — all free and browser-based.

FAQ

What is the difference between an API and a webhook?

An API call is initiated by your code — you ask, they answer. A webhook is initiated by the remote system — an event happens, they tell you. APIs are synchronous and on-demand; webhooks are asynchronous and event-driven.

How do I receive webhooks during local development?

Use the Webhook Tester to capture and inspect the payload structure first. For local handler testing, tools like ngrok or Cloudflare Tunnel expose your local server to the public internet, allowing real webhooks to reach your dev machine.

How do I verify a webhook signature?

Compute HMAC-SHA256 of the raw request body using your webhook secret as the key. Compare the result (hex-encoded) to the value in the signature header. If they match, the payload is authentic. Never verify on the parsed body — parsing can alter bytes.

What should my webhook endpoint return?

Return HTTP 200 (or 201/204) as quickly as possible — ideally within 3 seconds. If the provider gets no response, it retries. Do not run slow operations (database inserts, email sends, API calls) synchronously in the webhook handler.

What is idempotency and why does it matter for webhooks?

Idempotency means processing the same event multiple times produces the same result as processing it once. Webhooks can arrive more than once (due to retries). Check the event ID against a store of already-processed IDs and skip if the event has been handled before.

How do I debug a webhook that is failing silently?

Use the Webhook Tester to confirm the payload is reaching an endpoint correctly. Check the provider's webhook delivery logs (most providers like Stripe and GitHub show delivery attempts and response codes). Then inspect the request headers and body with the tools on this page.

Related Reading