Dispute
A chargeback. Carried by dispute.opened and dispute.closed.
There is no dispute endpoint. Like a subscription, this object reaches you through a webhook or not at all — which is why its shape is written out here.
| Field | What it is |
|---|---|
| id string | The dispute's own id. |
| object "dispute" | Always the literal string. |
| orderId string | null | The sale being charged back — readable with GET /orders/{id}. |
| status string | Where the case stands with the network. One of warning_needs_response, warning_under_review, warning_closed, needs_response, under_review, won, lost, prevented. |
| caseType string | One of inquiry, chargeback, compliance, block, resolution. inquiry is a question from the issuer and has taken no money yet; chargeback has. The two arrive through the same event, so branch on this before you tell anybody they have lost a sale. |
| reason string | null | Stripe's reason string — fraudulent, product_not_received, and so on. |
| networkReasonCode string | null | The card network's own code, such as 10.4 or 13.1. Not a Stripe identifier. |
| network string | null | The card network the case is with. |
| amount money | The disputed sale. |
| fee money | Stripe's dispute fee, which is why a £42 chargeback costs £57. |
| deducted money | Amount plus fee — what actually left the seller's balance. |
| currency string | ISO 4217, matching the money objects above. |
| dueBy string | null | ISO 8601, the response deadline — usually about twenty days. Null on a case that no longer needs one. This is the field to hang evidence-gathering off, since what wins a case normally lives in a helpdesk or a shipping account rather than in Sailo. |
| evidenceSubmittedAt string | null | ISO 8601, when a response was sent. |
| submissionCount number | How many times evidence has been submitted. |
| completenessBp number | null | How complete the submission was over its required fields, in basis points. The evidence bundle itself is never sent — it holds the buyer's address, delivery proof and the seller's own account of events, and it exists to go to Stripe rather than to whatever an integration points at. |
| fundsWithdrawnAt string | null | ISO 8601, when the money was taken back. |
| fundsReinstatedAt string | null | ISO 8601, when it was returned after a win. |
| openedAt string | null | ISO 8601, when the network opened the case. |
| createdAt string | null | ISO 8601, when the row was written. |
| updatedAt string | null | ISO 8601, when it last changed. |
Only ever a buyer against a seller
Sailo has two kinds of dispute and one of them never appears here: a seller charging back their own Sailo subscription is Sailo’s money and Sailo’s problem, and it has no business arriving in that seller’s Zapier account as though a customer had done something.
Every payload you receive is a buyer charging back one of the seller’s sales.
caseType before anything else
dispute.opened fires for an inquiry and for a chargeback, and they are
not the same event to a business.
An inquiry is the issuer asking a question on the cardholder’s behalf. No
money has moved and none may. A chargeback has taken the money.
A consumer that tells a seller “you have lost a sale” on every dispute.opened
is wrong a good fraction of the time.
Branch on caseType first: inquiry, chargeback, compliance, block,
resolution. The last three are rarer — compliance is a network-rules case,
the other two are deflection outcomes — and a consumer should handle them by
falling through rather than by assuming they cannot occur.
fundsWithdrawnAt is the unambiguous signal that money actually left: it is
null on an inquiry.
dueBy is the whole point of the event
The response deadline, usually about twenty days.
dispute.opened exists so a seller’s own tooling can go and get the evidence,
because what wins a chargeback usually lives somewhere that is not Sailo — a
helpdesk transcript, a delivery confirmation, a shipping account, a login log.
Hanging a task off dueBy is what this event is for.
It is null on a case that no longer needs a response.
The cost is more than the sale
Three money objects, and the third is the one to report:
| Field | What it is |
|---|---|
amount | The disputed sale |
fee | Stripe’s dispute fee |
deducted | Amount plus fee — what actually left the balance |
Which is why a £42 chargeback costs £57. A consumer reporting amount as the
loss is understating it by the fee on every case.
Evidence is never sent
evidenceSnapshot — the bundle assembled to answer the case — is not on this
object. It holds the buyer’s address, delivery proof and the seller’s own
account of events, and it exists to be sent to Stripe rather than syndicated to
whatever an integration points at.
completenessBp says how strong the response was, in basis points over the
required fields, without shipping the response itself. submissionCount says
how many times evidence has gone.
Statuses
warning_needs_response, warning_under_review, warning_closed,
needs_response, under_review, won, lost, prevented.
The warning_* three are inquiry states. prevented is a case a deflection
service — Visa Order Insight/RDR, Ethoca — resolved before it became a
chargeback.
dispute.closed
The case is finished; status says how it went. On a win,
fundsReinstatedAt is set — the money came back, though the fee generally
does not.
Example
{
"id": "b4e1f7a2-9d38-4c05-8e6b-1f0a3d7c2b95",
"object": "dispute",
"orderId": "8f2b41d6-0c93-4f77-a1e5-9b6d2c4a7e01",
"status": "needs_response",
"caseType": "chargeback",
"reason": "product_not_received",
"networkReasonCode": "13.1",
"network": "visa",
"amount": { "cents": 4200, "amount": "42.00", "currency": "GBP" },
"fee": { "cents": 1500, "amount": "15.00", "currency": "GBP" },
"deducted": { "cents": 5700, "amount": "57.00", "currency": "GBP" },
"currency": "GBP",
"dueBy": "2026-09-01T23:59:59.000Z",
"evidenceSubmittedAt": null,
"submissionCount": 0,
"completenessBp": null,
"fundsWithdrawnAt": "2026-08-12T09:41:07.221Z",
"fundsReinstatedAt": null,
"openedAt": "2026-08-12T09:40:58.000Z",
"createdAt": "2026-08-12T09:41:07.221Z",
"updatedAt": "2026-08-12T09:41:07.221Z"
}The chargeback guide turns this into a working evidence-gathering flow.