Fat vs. thin webhook payloads
A thin webhook payload announces that something happened and carries just enough to act: an event type, identifiers, a timestamp. A fat payload carries the full state of the object involved, so the receiver needs no follow-up API call. The choice shapes the security posture, API traffic, and failure modes of an entire webhook integration, and neither is simply better; they trade different problems.
The two shapes
A thin payload, sometimes called an event notification, looks like this:
{
"type": "invoice.paid",
"data": { "invoice_id": "inv_8kX2mP", "customer_id": "cus_1WqT9r" }
}
The receiver calls the API to fetch whatever it needs about inv_8kX2mP. A fat payload, in event-driven-architecture vocabulary event-carried state transfer, embeds the object:
{
"type": "invoice.paid",
"data": {
"invoice_id": "inv_8kX2mP",
"customer_id": "cus_1WqT9r",
"amount": 4900,
"currency": "usd",
"status": "paid",
"paid_at": "2026-08-26T09:14:02Z"
}
}
What thin payloads buy
Less sensitive data in flight. The webhook pipeline, delivery logs, and any receiver-side request logging only ever see IDs. For payloads that would otherwise carry PII or payment data, thin events shrink the compliance surface: the sensitive fetch happens over the API, under its authentication and its audit trail.
Freshness by construction. A fat payload is a snapshot from when the event fired. Deliveries retry and arrive out of order, so a receiver applying fat payloads can overwrite new state with old. A thin payload forces a fetch of current state, which makes stale-overwrite bugs structurally impossible; whatever the fetch returns is the truth as of now.
Smaller, stabler contracts. The event schema is a handful of fields, so the object model can evolve without re-versioning every event type.
What fat payloads buy
No read amplification. Every thin delivery triggers an API call, so a burst of events becomes a burst of reads against the provider's API, rate limits included. Fat payloads make the webhook self-contained: at high volume this is the difference between a receiver that just writes and one that hammers the API it was meant to relieve.
Receivers without API access. A fat payload can be consumed by systems that hold no API credentials at all, which matters when events fan out to many internal consumers or to third parties.
Sense despite deletion. An event about an object that was deleted moments later still carries usable state; the thin receiver's follow-up fetch returns a 404 and the context is gone.
Choosing, and the middle path
The deciding questions are usually: how sensitive is the object data, how much do consumers care about point-in-time state versus current state, and can every consumer call the API. Payment and healthcare providers lean thin for the compliance surface; developer tools lean fat for the integration convenience.
Many mature APIs land in the middle: a payload carrying the commonly needed fields plus IDs for the rest, or a per-endpoint setting that lets each consumer pick. Note that the Standard Webhooks specification is deliberately silent here: it standardizes the envelope, headers, and signatures, and either payload shape rides inside it. For the full design treatment, see the designing webhook payloads lesson and the webhook payload entry.
Frequently asked questions
Should webhook payloads contain full data or just IDs?
IDs (thin) when the data is sensitive or consumers must always act on current state; full data (fat) when volume makes per-event API fetches expensive or receivers lack API access. Many providers send common fields plus IDs, or make it a per-endpoint choice.
What is event-carried state transfer?
The event-driven-architecture name for fat payloads: the event carries the state of the object it concerns, so consumers update themselves without calling back to the source system.
Why do payment providers prefer thin payloads?
Because the payload passes through delivery infrastructure, retry queues, and logs on both sides. Keeping card, payout, and identity data out of that path and behind an authenticated API fetch shrinks the compliance and breach surface considerably.
Do thin payloads have ordering problems too?
They mostly sidestep them. Since each event triggers a fetch of current state, a late or out-of-order delivery still results in up-to-date data. Fat-payload consumers must instead compare timestamps or versions to avoid overwriting newer state with an older snapshot.
Ready to send webhooks?
Svix handles signing, retries, rate limiting, and delivery observability for the webhooks you send to your users, so your team can stay focused on your product.
Start sending webhooks with Svix or read the build vs. buy analysis