Skip to content

Dispute

A Dispute is a contested payment or delivery, such as a chargeback, a rejected Service outcome, or a buyer’s claim against a Supplier.

Properties

PropertyTypeRequiredDescription
kindstringrequiredOne of chargeback, outcome, or marketplace.
statusstringrequiredOne of open, answered, decided, appealed, or closed.
heldmoneyrequiredThe amount held from the seller until the Dispute closes.
reasontextrequiredWhat the buyer says fell short, in their words.
answerBydatetimeWhen the seller’s answer is due; a missed deadline decides for the buyer.
decisionstringOne of buyer, seller, or split, with the amounts each side keeps.
decidedBystringrequiredissuer (the cardholder’s bank) for a chargeback; worker, uninvolved in the Order, for an outcome or marketplace Dispute.
feemoneyThe card network’s fee on a chargeback, debited with the held amount when it opens.

Object

JSON
{
  "$id": "https://api.sb/tutorloop.com/disputes/dispute_1",
  "$type": "Dispute",
  "kind": "chargeback",
  "status": "open",
  "held": {
    "amount": 60,
    "currency": "USD"
  },
  "reason": "Example reason",
  "answerBy": "2026-10-22T12:00:00Z",
  "decision": "buyer",
  "decidedBy": "issuer",
  "fee": {
    "amount": 60,
    "currency": "USD"
  }
}

Relationships

  • A Dispute cites many pieces of Evidence: the Evidence each side submits on the Dispute, frozen once submitted. cites, inverse citedBy.
  • A Dispute contests one Order: the Order whose delivery or charge the Dispute contests. contests, inverse disputes.

Verbs

  1. getReturns one Dispute by id.
    GET /{namespace}/disputes/{id}readNo Event
  2. listReturns Disputes, newest first, one page at a time.
    GET /{namespace}/disputesreadNo Event
  3. acceptAccept concedes an open Dispute without contest, so the buyer keeps the held amount and the Dispute closes.
    POST /{namespace}/disputes/{dispute}/acceptdoDispute.accepted
  4. answerAnswer submits the seller’s Evidence on an open Dispute before its deadline: the contract, the delivered work, and its verdicts.
    POST /{namespace}/disputes/{dispute}/answerdoDispute.answered
  5. appealAppeal asks for one review of a decided Dispute by a Worker who took no part in the first decision.
    POST /{namespace}/disputes/{dispute}/appealdoDispute.appealed
  6. decideDecide rules on an answered Dispute for the buyer, the seller, or a split, and releases or returns the held amount.
    POST /{namespace}/disputes/{dispute}/decidedoDispute.decided

A Dispute is kept forever and never edited: it has no update or delete.

Events

Events no Verb emits. Each Verb’s Event is in the Verbs table above; every Event is delivered in the same shape.

Dispute.opened

A card issuer opened a Dispute against a charge, and the rail holds the disputed amount. Raised by the rail.

FieldTypeRequiredDescription
namestringrequiredDispute.opened.
atdatetimerequiredWhen it happened.
seqintegerIts position in the namespace, one more than the Event before; any seq is a cursor into the history.
datajsonrequiredThe Thing as the Action left it.
data.disputeDisputerequiredThe Dispute as the change left it.
data.dispute.kindstringrequiredOne of chargeback, outcome, or marketplace.
data.dispute.statusstringrequiredOne of open, answered, decided, appealed, or closed.
data.dispute.heldmoneyrequiredThe amount held from the seller until the Dispute closes.
data.dispute.reasontextrequiredWhat the buyer says fell short, in their words.
data.dispute.answerBydatetimeWhen the seller’s answer is due; a missed deadline decides for the buyer.
data.dispute.decisionstringOne of buyer, seller, or split, with the amounts each side keeps.
data.dispute.decidedBystringrequiredissuer (the cardholder’s bank) for a chargeback; worker, uninvolved in the Order, for an outcome or marketplace Dispute.
data.dispute.feemoneyThe card network’s fee on a chargeback, debited with the held amount when it opens.
data.transactionTransactionrequiredThe disputed charge.
JSON
{
  "$id": "https://api.sb/tutorloop.com/events/event_1",
  "$type": "Event",
  "name": "Dispute.opened",
  "at": "2026-10-22T12:00:00Z",
  "data": {
    "dispute": {
      "$id": "https://api.sb/tutorloop.com/disputes/dispute_1",
      "$type": "Dispute",
      "kind": "chargeback",
      "status": "open",
      "held": {
        "amount": 60,
        "currency": "USD"
      },
      "reason": "Example reason",
      "answerBy": "2026-10-22T12:00:00Z",
      "decision": "buyer",
      "decidedBy": "issuer",
      "fee": {
        "amount": 60,
        "currency": "USD"
      }
    },
    "transaction": {
      "$id": "https://api.sb/tutorloop.com/transactions/transaction_1",
      "$type": "Transaction",
      "kind": "charge",
      "amount": {
        "amount": 60,
        "currency": "USD"
      }
    }
  },
  "seq": 1
}

Permissions

Which Access level may call each Verb. One-way Verbs wait their delay window.

Operationowneradminmemberviewer
Dispute.getYesYesYesYes
Dispute.listYesYesYesYes
Dispute.acceptYesNoNoNo
Dispute.answerYesNoNoNo
Dispute.appealYesNoNoNo
Dispute.decideYesNoNoNo

Stripe

Dispute (dispute), for a Dispute whose kind is chargeback. The source of truth is Stripe: db.sb mirrors it, written only from Stripe’s webhooks.

PropertyStripe fieldSource of truth
heldamountStripe
reasonreasonStripe
statusstatusStripe
answerByevidence_details.due_byStripe
feebalance_transactions[].feeStripe

Call it

Text
Answer the latest dispute with evidence.

Example

A store disputes a catalog cleanup Order because 40 products landed in the wrong category. The Dispute holds the fee, the fix runs, and the store confirms the redelivery. The Dispute closes with no decision, and the fee is earned.