Stripe thin events: fetch the object, vs a Sume webhook receipt
Stripe thin events are GA for v1 resources in Endive: you fetch the object. A Sume webhook carries the receipt; an oversized one points to result_url.

Stripe's changelog lists thin events for API v1 resources as generally available in the Endive API version dated 2026-09-30. A thin event tells you which object changed and you fetch the current object yourself. A Sume webhook works the other way round: it carries the finished receipt, and you only fetch when the body is too large to ship.
So if you are porting a Stripe handler, the shape of the work changes. Stripe asks for a follow-up call to get the data. Sume asks for one only in the oversize case.
What Stripe says a thin event is
Stripe's events page describes a thin event as a lightweight notification with limited information about the event and the affected object. You then make a call to fetch the complete event or the related resource. A snapshot event carries the complete object as it was when the event was raised, which Stripe warns can be stale by the time you process it.
One caveat from the same day: the changelog says thin events for v1 resources are GA in Endive, while the event destinations page I read still states that thin events come from API v2 resource state changes. Check which of the two your account and API version actually produce before you rely on it.
| Format | Payload | To get current data |
|---|---|---|
| Thin event | Small: IDs and type of the related object | Fetch the related object or the full event |
| Snapshot event | Large: a snapshot of the object | Fetch the latest object, because the snapshot may be outdated |
What a Sume webhook carries
A Sume job webhook is sent when the job reaches a terminal state: job.completed, job.failed or job.canceled. The body has event, request_id, job_id, a status of OK or ERROR, and payload.artifacts. A Format run webhook (format.run.terminal) carries the run receipt in its payload, with a status of OK or ERROR and an outcome of ok, degraded or error.
The one place Sume behaves like a thin event is the size cap. The run webhooks page says a receipt over 1 MiB arrives as payload null with error.code payload_too_large and a result_url. A handler that reads payload and finds null should fetch result_url, not treat the run as failed. The status is still the run's real outcome.
What to change in a ported handler
Sume does not offer a thin-event mode that you can switch on. The webhook format is fixed, and the docs I read describe no option to choose between small and large payloads.
- Do not add a fetch call to the happy path. Read the receipt from the body.
- Branch on payload being null. If it is, fetch result_url once and continue with the same code.
- Keep the dedupe key from the envelope: job_id for job webhooks, request_id (which equals the run id) for run webhooks.
- Keep a poll on status_url as a backstop for deliveries that never arrive.
Checklist for the port
Stripe's own page pairs thin events with typed SDK helpers that fetch the related object for you. A Sume receiver has nothing equivalent to call, because the receipt is already in the body, so the port mostly deletes code. What remains is verification, dedupe and the null-payload branch.
Test the oversize branch on purpose. Send your handler a body with payload set to null and error.code payload_too_large and confirm it fetches result_url once, records the result, and returns 200. Most handlers are only ever tested with the happy path and fail the first time a large receipt arrives. Also keep the stale-data warning in mind: a Sume receipt is the final state of that run, so unlike a Stripe snapshot it does not need a refresh before you act on it.
Sources
Related posts
More in Developers
- Sume 503: provider_capacity_exceeded vs provider_not_configured
Sume 503s differ: provider_capacity_exceeded: retry later, same key; provider_not_configured is no hard retries, job_ledger_not_configured is an outage
- Sume API errors: a 13-line function that says retry or fix
Map a failed Sume response to out-of-credit, wait, back off, fix the key, retry with the same key, or fix the request, using the documented error envelope.
- sume/auto for an image series: why to pin a model id instead
sume/auto never tells you which model ran, and job.model stays sume/auto. For a series that must match, send one catalog id such as google/nano-banana-2.
- SUME_API_BASE_URL has /v1, the SDK baseUrl does not: which is right?
The Sume CLI base URL is https://api.sume.com/v1 and it sends x-api-key by default; the SDK baseUrl is https://api.sume.com with no /v1. Both env sets compared.
Written by Sume