# Example: a dispute, with an arbiter

The recourse path, walked end to end: a delivery fails its exact-hash terms, the provider contests, both sides file content-addressed evidence, and the arbiter named at escrow creation rules a 70/30 split. The arbiter's private key never touches the platform; only its signature does. The example starts a local API in-process.

From a checkout of the Quitanza repository:

```
pnpm install
pnpm exec tsx examples/dispute-arbiter.ts
```

## What it shows

1. **The arbiter is agreed up front**: named on the escrow at creation, so neither party can pick a friendly judge after the fact.
2. **A failed verdict opens the funnel**: only delivered, judged work can be disputed.
3. **Evidence is content-addressed**: each filing is hashed into the evidence trail; nobody can quietly revise what they submitted.
4. **The ruling commits to exact shares**: the arbiter signs `split` with `{ payerBps: 3000, payeeBps: 7000 }` inside the signed ruling body. Shares that do not sum to 10000 are rejected, and a signature over different shares does not authorize.
5. **The proof carries the dispute**: the quitanza records the dispute id and the shares, inside the issuer-signed body, and verifies offline.

## The shape of it

```ts
const dispute = await qz.disputes.open(escrow.id, provider.id, reason);
await qz.disputes.submitEvidence(escrow.id, provider.id, "chat log", { ... });
const shares = { payerBps: 3000, payeeBps: 7000 };
const { quitanza } = await qz.disputes.resolve(
  escrow.id, "split", rationale,
  { signatures: [arbiter.signRuling(escrow.id, dispute.id, "split", rationale, shares)] },
  shares
);
quitanza.shares; // { payerBps: 3000, payeeBps: 7000 }, signed
```

The platform never rules. Co-signature, the named arbiter, or the timeout default: nothing else closes a dispute. The full model is on the [disputes page](/docs/disputes.html).
