Skip to content

What Is Inside a Webhook Request

Last checked November 14, 2026

A webhook request has three parts you'll see in any app's documentation: a URL, some headers and a payload. Think of a letter. The URL is the address, the headers are the labels on the envelope, and the payload is the letter inside.

The three parts of a webhook requestURL: where the message goesHeaders: labels about the messagePayload: the data itself
Think of an address, a label and a letter.

The URL

The URL is the web address you gave the sending app. It points at the endpoint, the spot on your system that listens for messages.

Stripe shows the format as https://your-website/your-webhook-endpoint, so a site at example.com with a route called /webhook-handler would use https://example.com/webhook-handler1. The route name is your choice.

Two details are worth knowing:

  • Stripe requires that registered webhook endpoints be publicly accessible HTTPS URLs1. HTTPS means the connection is encrypted.
  • The sending app can't be trusted just because a message arrives at the URL. The signature check below exists for that reason.

The method

A webhook arrives as a POST request. POST is the kind of request that sends data to a server, as opposed to asking for a page. Stripe says its endpoint function must handle POST requests with a JSON payload that includes event information1.

The headers

HTTP headers let the client and the server pass additional information with a message in a request or response2. In a webhook, they describe the message without opening it.

Shopify says every webhook delivery includes headers that describe the topic, source store, API version, and delivery IDs3. Its documentation lists these:

Header What it carries
X-Shopify-Topic The topic name, such as products/update3
X-Shopify-Hmac-Sha256 A signature used to verify that Shopify sent the delivery3
X-Shopify-Shop-Domain The store that triggered the event3
X-Shopify-API-Version The API version used to build the payload3
X-Shopify-Webhook-Id A unique key for each delivery, used to spot duplicates3

Source: Shopify developer documentation3, checked on 2026-11-14.

GitHub works in a similar way. Its guidance says to check the X-GitHub-Event header to learn what event type was sent4.

Header names differ from one app to the next. Always read the sending app's own list.

Two headers that appear everywhere

Content-Type indicates the media type of the resource2. For a webhook, it tells you how to read the body, most often as JSON.

A signature header proves the sender. Stripe signs every webhook event by including a signature in the Stripe-Signature header1. The receiver recomputes the signature with a shared secret and compares. If the two don't match, it should reject the message.

The payload

The payload, or body, is the data about the event. Stripe sends webhook events to your app as a JSON payload that includes event information1. JSON is a text format for structured data. Reading a webhook payload and JSON shows how to read one.

Some apps let you choose the format. GitHub's guidance says that if you have an option to choose the content type, use JSON4.

A typical payload names the event, gives an ID and carries the record that changed. The exact field names depend on the app, so the maker's documentation is the reference.

Reading a request in order

  1. Check the signature header against your shared secret.
  2. Read the event type, from a header or from the payload.
  3. Check the delivery ID so you don't act on the same message twice. Shopify's delivery key exists to deduplicate individual deliveries3.
  4. Parse the payload.
  5. Reply with a success code. The page on response codes explains what to send.

Sources used

  1. Receive Stripe events in your webhook endpoint, Stripe Documentation
  2. HTTP headers, MDN Web Docs
  3. Webhooks, Shopify developer documentation
  4. Handling webhook deliveries, GitHub Docs