Docs
⌕ ⌘K
Transacting / Disputes

Disputes

A dispute is the recourse a buyer has when a settled transaction did not deliver what it paid for. The seller can settle it directly while it is new; after that an independent Arbitration Board decides, and an award is paid from the seller's escrow. This is the mechanism that turns a rating into an obligation.

Agents act; your platform does not adjudicate

A dispute is a runtime economic action, so it is signed by the agent itself: the buyer agent files it, and each side answers it, with its own certificate and proof. A principal acts through your platform’s app, which signs as the agent — your platform key and the Nustro dashboard cannot file or answer. Nustro runs the process and moves the funds. Your platform surfaces the case, helps the principal act on it, and reports the result.

When a transaction can be disputed

Only the buyer can dispute — the agent that paid. A business agent that buys and sells is the applicant against its suppliers and the respondent to its own customers; its escrow never answers for something it did as a buyer. Four conditions, all evaluated against values fixed at settlement.

The transaction has settled. An unsettled transaction has nothing to dispute and no escrow to answer for it.
The dispute window is open. dispute_window_closes_at is in the future. A null value means final sale — the seller declared dispute_window_days: 0.
No dispute already exists on that transaction. One case per transaction.
Something is left to claim. The disputed amount can be at most the transaction amount minus what the seller has already refunded. A fully refunded payment cannot be disputed.
Nustro enforces

Eligibility is decided from fields snapshotted onto the transaction at settlement — dispute_window_days, dispute_window_closes_at, and the seller’s AID version — not from the seller’s live AID. A seller that shortens its window tomorrow cannot close yesterday’s transactions, and one that lengthens it cannot reopen them.

Filing a dispute

Filing is a request, not a transfer, but it is the buyer’s own economic action: the buyer agent signs it with its certificate and a bound proof. A platform key or dashboard session is refused with 401 agent_credential_required. When a principal starts the dispute in your app, your app signs as the agent.

cURL
curl -X POST https://api.nustro.com/v1/disputes \
  -H "AEAP-Certificate: eyJhbGciOiJFUzI1NiIsImtpZCI6…" \
  -H "AEAP-Proof: MEUCIQD…" \
  -H "AEAP-Timestamp: 1778924331" \
  -d '{
    "transaction_id": "pin_6b21f9c4",
    "disputed_amount": "86.00",
    "currency": "USDC",
    "reason": "not_as_described",
    "resolution_sought": "partial refund",
    "description": "Delivered dataset covered 2019-2021; the order specified 2019-2024."
  }'
FieldNotes
transaction_idThe settled transaction — the same identifier as its payment intent.
disputed_amountA decimal string. At most the transaction amount minus refunds already recorded against it.
currencyOptional; defaults to the transaction’s currency.
reasonnot_delivered · not_as_described · unauthorized · other
resolution_soughtWhat the buyer is asking for — a full refund, a partial refund, a service remedy.
descriptionThe claim in the buyer’s words.

Evidence is a separate call, available to both parties while the evidence window is open: POST /v1/disputes/{dispute_id}/evidence, multipart, with a description, an optional kind (transaction_record, communication_log, outcome_data, service_specification, other) and an optional file — PDF, JPEG, PNG, JSON or plain text, up to 10 MB. It is signed by the agent too. A case with no evidence is decided on the record alone.

The seller can settle — once

Filing opens a resolution window — 7 days by default — in which the seller agent can resolve the claim directly with the buyer. It is the seller’s only chance: once the dispute goes to the board, only the board decides, and concede and offer return 409 dispute_with_board.

StepCallResult
Seller accepts the claimPOST /v1/disputes/{id}/concedeThe buyer is paid the full disputed amount from the seller’s escrow. Closed for the buyer, no bounty.
Seller offers lessPOST /v1/disputes/{id}/offer with amount and an optional noteRecorded on the dispute, and the buyer’s platform hears about it through dispute.updated. The amount must be above zero and below the claim; a new offer replaces a pending one.
Buyer accepts the offerPOST /v1/disputes/{id}/offer/acceptThe buyer is paid the offer from the seller’s escrow. Closed as a resolved complaint, no bounty.
Buyer rejects it, or the window runs outPOST /v1/disputes/{id}/offer/rejectThe dispute goes to triage and on to the board. The claim is unchanged.

A dispute settled here counts as a resolved complaint — a smaller hit to the seller’s rating than a lost hearing, and no arbitration cost. Every offer stays on the dispute record, whatever became of it.

Settle inside the dispute, not with a refund

While a dispute is open the seller cannot refund the payment from its operational wallet — POST /v1/refunds returns 409 dispute_open. Whatever it pays the buyer comes from escrow, through the dispute. Refunds and dispute payouts on one payment together never exceed its original value. AEA/P §7.6, §8.3. Read §8 ↗

The board, and what happens next

StatusMeaning
PENDING · PRE_ARBITRATIONFiled and in the seller’s resolution window. The disputed amount is provisionally held; the seller agent keeps operating.
TRIAGEUnresolved. Nustro compares the exposure — disputed amount plus bounty — with the seller’s escrow. Within the balance, that amount goes into DISPUTE_HOLD. Above it, the whole balance is held and the escrow goes CONSTRAINED, which suspends the seller agent until it recovers.
EVIDENCEThe board is seated and both sides submit evidence. The board can extend the window once, by 3 days, if what it has is not enough.
VOTINGThe arbitrators vote for the buyer or the seller.
RESOLVEDThe hearing is decided — BUYER or SELLER. Unless the outcome is already final, the losing side has until the escalation_deadline to escalate.
ESCALATEDThe losing side escalated; a new, larger board hears the case.
HearingBoardDecided by
13 arbitratorsStrict majority
25, none from hearing 1Strict majority
3 — the last7, none from earlier boardsSimple majority of the votes cast, even if the board could not be kept full. An exact tie — including no votes at all — goes to the buyer.

The record carries the current hearing, each hearing’s decision with its basis — strict_majority, simple_majority or tie_to_buyer — the escalation_deadline, and final. Only the losing side of hearing 1 or 2 can escalate (POST /v1/disputes/{id}/escalate), within 7 days of the decision; each escalation holds the next board’s bounty from the seller’s escrow.

Enforcement is automatic

The outcome is final when the escalation deadline passes with no escalation, when one side has won two hearings, or when the third hearing is decided. Enforcement then runs on its own — no party, platform or Nustro staff action. On a buyer win the award moves from the seller’s escrow to the buyer and is added to the transaction’s dispute_paid, and dispute.resolved fires. Escrow is the only balance Nustro can move, and it moves only on protocol events: there is no discretionary transfer path and no endpoint that reverses a settlement.

Costs fall on the seller

The respondent pays the arbitrators’ bounty, from its escrow, and the buyer is never charged for filing — recourse that costs money to seek is not recourse. Lost disputes still lower a buyer’s rating through the dispute-fairness signal, which discourages frivolous filing. AEA/P §8. Read §8 ↗

What your platform should build

Show the window while it is open. A buyer who does not know they can dispute will not. Surface dispute_window_closes_at on the transaction, and say plainly when it is final sale.
File from your app, as the agent, with evidence. The filing form is the one moment the buyer’s principal has full context. File, then attach the evidence straight away — evidence added later is worth less.
Put the seller’s choices in front of its principal. Concede, offer, or let the board decide — with the resolution window’s deadline. A seller that learns of a case after the window has lost its only chance to settle it.
Subscribe to dispute.filed, dispute.updated and dispute.resolved. dispute.updated carries offers, rejections, escalations and evidence requests — the moments a principal has to act.
Surface escrow impact to sellers. A hold reduces available escrow, and a constrained escrow suspends the whole agent — buying included. Sellers should see that in your UI, not discover it when a transaction is refused.

The Nustro dashboard shows every dispute involving your agents, read-only. GET /v1/disputes lists them across your platform, filterable by status, side and agent.

Common errors

CodeStatusWhat it means
agent_credential_required401Sent with a platform key or dashboard session. Every dispute action is signed by the acting agent.
not_applicant403The agent is not the buyer of that transaction — filing, or acting on an offer.
not_respondent403A concession or offer from anyone but the seller.
transaction_not_settled409Filed against a transaction that has not settled. Re-read the transaction.
final_sale409The seller declared no dispute window for that transaction. Not recoverable.
dispute_window_expired409The window has passed. Not recoverable — the dispute path is closed for that transaction.
dispute_exists409A dispute is already open. Re-render the existing case rather than offering the form again.
fully_refunded409The seller has refunded the whole payment; nothing is left to dispute.
amount_exceeds_unrefunded409The disputed amount is above the transaction amount minus refunds. Lower it — the one filing error the user can fix in place.
dispute_with_board409A concession or offer after the dispute went to the board.
offer_window_closed409An offer outside pre-arbitration or after the resolution window.
offer_amount_invalid422The offer is not above zero and below the claim. For the full claim, concede.
no_pending_offer409Accept or reject with no offer pending.
evidence_window_closed409Evidence submitted after the window closed.
not_losing_party403Escalation by the side that won the hearing, or by a non-party.
escalation_window_closed409The escalation deadline has passed; enforcement has run or is running.
dispute_final409The outcome is final — two hearings won, or the third decided. Nothing more can be filed on it.

Next