dispute.created and dispute.status-changed webhooks.
Rinne is never the claimant. It receives the provider’s report and relays it, so a dispute always originates outside Rinne—there is no way for your organization or Rinne to open one.
Where disputes come from
Disputes arrive from the provider that processed the original transaction. Each rail has its own vocabulary for the same idea, and Rinne absorbs that difference at the provider boundary: event names and payload fields describe Rinne’s lifecycle, not the provider’s. You integrate once, regardless of which rail a dispute came from. Thetype field names the rail:
Today disputes reach you from the PIX rail (
PIX_INFRACTION). Card chargebacks will arrive through these same two events, so handling both types now needs no later change.Lifecycle
A dispute tracks progress and verdict on two separate fields:status says how far the claim has got, and outcome says how it ended.
status is an ordered progression and a dispute only ever moves forward. CLOSED is the single terminal status, so a finished dispute is exactly status == "CLOSED".
outcome is null for the entire life of the dispute until it closes, and is always set once it has:
A partially resolved claim is
UPHELD with a smaller amount, not a separate outcome.
Disputes and the disputed transaction
Every dispute is linked to the transaction it challenges throughtransaction_id. Use that field to reconcile a dispute against the payment in your own system.
The dispute lifecycle is tracked separately from the transaction lifecycle: a dispute.created or dispute.status-changed event reports the claim’s progress and is not a transaction status change. You receive dispute events independently of any transaction.status-changed event for the same payment.
A single transaction can accumulate more than one dispute. Key your own records on dispute_id, not on transaction_id.
The dispute webhooks
Both events use the same envelope, Svix signatures, and retry behavior as every other Rinne event—see Webhooks. In the envelope,source is dispute-service and company_id is the merchant the claim is filed against.
Both payloads carry an entity field holding the full dispute object as it stood when the event was emitted, so you never need a follow-up request to act on a dispute. The API reference lists every field it contains; two of them are easy to misread:
amountis the amount at risk, in cents—an upper bound rather than an exact figure, currently derived from the disputed transaction. Rails that report an amount of their own will carry it here instead.dispute_detailsis free text describing the claim, and its author is not recorded—it may be the payer in their own words, a risk analyst at the reporting institution, or a generated message. Display it and read it, but never parse it or branch your logic on its contents.
dispute.created
Emitted when Rinne records a dispute for the first time.
OPEN. A dispute whose first notification to reach Rinne already describes a finished claim is created at CLOSED, with outcome already set—so handle a created event that is already closed rather than assuming a status change will follow.
dispute.status-changed
Emitted when the dispute moves forward: OPEN to UNDER_REVIEW, or either of those to CLOSED with a verdict in outcome.
Next steps
Webhooks
Endpoint setup, Svix signature verification, and retries
Transactions
The payment lifecycle a dispute challenges
Ledger entries
How settled amounts are recorded against a merchant
API reference
Full dispute event schemas under Webhooks → Events

