> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reap.global/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Challenge a cleared card transaction for chargeback.

When a cardholder does not recognise a charge, never received what they paid for, or was billed the wrong amount, you file a dispute and Reap takes the case to the card network. You send the transaction ID and a reason; Reap derives the card, the cardholder identity, and the currency from the transaction itself.

Subscribe to [`CARD_DISPUTE_STATUS_UPDATED`](/api-reference/card-dispute-status-updated) for the outcome. Cases can take weeks to resolve, so treat the webhook as the source of truth rather than polling.

<Note>
  A dispute is not a [fraud alert](/cards/fraud-alerts). Confirming a fraud alert blocks the card but does not recover the money. A dispute is the path for recovering the money. The two are independent: neither requires the other, and you can file both against the same transaction.
</Note>

***

## Before you file

| Requirement                                          | Detail                                                                                                                                                                                                      |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The transaction is `CLEARED`                         | Money has to have actually moved. `PENDING` and `VOID` transactions cannot be disputed. See the [transaction lifecycle](/transactions/lifecycle). Otherwise returns `CARD_DISPUTE_TRANSACTION_NOT_CLEARED`. |
| Within 180 days of the transaction                   | Measured from the transaction date. Otherwise returns `CARD_DISPUTE_FILING_WINDOW_EXPIRED`.                                                                                                                 |
| Amount is at most the cleared amount, net of refunds | Defaults to that full amount when omitted. A partly refunded transaction can still be disputed for the remainder. Otherwise returns `CARD_DISPUTE_AMOUNT_INVALID`.                                          |
| No live dispute on the transaction                   | A second dispute returns `CARD_DISPUTE_ALREADY_EXISTS`. You may refile only if the earlier case was `CANCELED` or `DECLINED`, meaning it never reached the network.                                         |

<Note>
  An `Idempotency-Key` is required on [File dispute](/api-reference/disputes/file-dispute). A retry carrying the same key replays the original response, so a network timeout on your side does not turn into an error on the retry. Without it a retry of a request that already succeeded returns `CARD_DISPUTE_ALREADY_EXISTS`.
</Note>

***

## File a dispute

<Steps>
  <Step title="Collect the reason from the cardholder">
    Pick the [dispute reason](/cards/disputes/reasons) that matches what the cardholder is telling you. The reason determines whether a signature is needed and how the network handles the case, so it is worth surfacing as a clear choice in your UI rather than guessing.
  </Step>

  <Step title="File it">
    Call [File dispute](/api-reference/disputes/file-dispute) with `transactionId` and `reason`.

    Optionally send `amount` to dispute part of the charge, and `contactEmail` to route the outcome somewhere other than the cardholder's email on file. Everything else is derived from the transaction.
  </Step>

  <Step title="Check whether a signature is needed">
    The response carries `requiresCardholderSignature`. When it is `true` the dispute is created as `PENDING_SIGNATURE` and will not progress until the cardholder signs. Continue to [Collect the cardholder signature](#collect-the-cardholder-signature).

    When it is `false` the dispute is created as `RECEIVED` and Reap takes it from there.
  </Step>

  <Step title="Track the outcome">
    You receive [`CARD_DISPUTE_STATUS_UPDATED`](/api-reference/card-dispute-status-updated) on every status change through to resolution.
  </Step>
</Steps>

***

## Collect the cardholder signature

Fraud and consumer disputes need a signed statement from the cardholder before the case can move. Reap generates a pre-filled form and gives you a link to hand to them.

<Steps>
  <Step title="Mint a link">
    Call [Mint signature link](/api-reference/disputes/mint-signature-link). You get back a `url` and an `expiresAt` one hour out.
  </Step>

  <Step title="Send the cardholder to it">
    Open the `url` in a browser or web view. The form is pre-filled with the dispute details; the cardholder reviews and signs.
  </Step>

  <Step title="Mint a fresh link if it expires">
    Links are single-use instances with a one-hour life and are never cached. Call the endpoint again for a new one. Concurrent links are safe, and each stays valid until it expires or is signed.
  </Step>
</Steps>

```mermaid theme={null}
sequenceDiagram
  participant Backend as Your backend
  participant Reap
  participant Cardholder

  Backend->>Reap: POST /disputes
  Reap-->>Backend: PENDING_SIGNATURE, requiresCardholderSignature true
  Backend->>Reap: POST /disputes/:id/signature-link
  Reap-->>Backend: url, expiresAt
  Backend->>Cardholder: Open the signature form
  Cardholder-->>Reap: Signs
  Reap->>Backend: CARD_DISPUTE_STATUS_UPDATED (RECEIVED)
```

<Warning>
  Signing does not update the dispute instantly. Reap confirms the signed form separately, so reading the dispute right after the cardholder finishes can still return `PENDING_SIGNATURE`. That is expected. Wait for [`CARD_DISPUTE_STATUS_UPDATED`](/api-reference/card-dispute-status-updated) to move to `RECEIVED`, and do not send the cardholder back to sign a second time.
</Warning>

Requesting a link for a dispute that does not need one returns `CARD_DISPUTE_SIGNATURE_NOT_REQUIRED`.

***

## Dispute lifecycle

| Status              | Meaning                                                                      |
| ------------------- | ---------------------------------------------------------------------------- |
| `PENDING_SIGNATURE` | Waiting on the cardholder to sign. The case does not progress until they do. |
| `RECEIVED`          | Recorded and queued for review.                                              |
| `REVIEWING`         | Under review before it goes to the network.                                  |
| `SUBMITTED`         | Filed with the card network. Now waiting on their ruling.                    |
| `WON`               | The network ruled for the cardholder.                                        |
| `LOST`              | The case was filed and the network ruled for the merchant.                   |
| `REFUNDED`          | The charge was refunded.                                                     |
| `DECLINED`          | Reap did not file the case with the network.                                 |
| `CANCELED`          | The case was withdrawn before resolution.                                    |

```mermaid theme={null}
flowchart LR
  Pending["PENDING_SIGNATURE"] --> Received["RECEIVED"]
  Received --> Reviewing["REVIEWING"]
  Reviewing --> Submitted["SUBMITTED"]
  Received --> Submitted
  Submitted --> Won["WON"]
  Submitted --> Lost["LOST"]
  Submitted --> Refunded["REFUNDED"]
  Won --> Refunded
```

`DECLINED` and `LOST` are easy to confuse. `DECLINED` means the case never reached the card network. `LOST` means it was filed and the network ruled for the merchant.

A dispute can also be sent back to `PENDING_SIGNATURE` after review if more is needed from the cardholder, and can be canceled or declined at any point before resolution. `resolvedAt` is set once the case reaches a final status.

***

## Next

<CardGroup cols={1}>
  <Card title="Dispute Reasons" icon="list" href="/cards/disputes/reasons">
    The full reason vocabulary, grouped by category, and which ones need a cardholder signature.
  </Card>
</CardGroup>
