# Submit a dispute's evidence to the processor

> The disputes.submit_evidence operation: POST /api/v1/disputes/{id}/submit_evidence in the REST API and the disputes_submit_evidence tool in the MCP server.

Sends the dispute's latest evidence pack to the payment processor, which passes it to the card network: the
pack's text (customer, what was sold, the service date, sign-ins and usage, the terms acceptance and the
withdrawal-right waiver, the IP country), the pack PDF and the invoice PDF as the receipt. Build the pack first
(`disputes.evidence.build`) and check it.

Evidence goes once, before `evidenceDueBy`, while the dispute needs a response; afterwards the dispute is
`under_review` until the processor reports the outcome (`dispute.closed`: won or lost). A processor without a
dispute evidence API is refused (`dispute_evidence_unsupported`): download the pack from the console and submit
it in the processor's dashboard. A dry run checks everything without calling the processor.

## At a glance

- **REST:** `POST /api/v1/disputes/{id}/submit_evidence`
- **MCP tool:** `disputes_submit_evidence`
- **Operation ID:** `disputes.submit_evidence`
- **Scope:** Brand
- **Permission:** `disputes:write`
- **Risk tier:** `financial`
- **Dry run:** Supported (send `Ownrecord-Dry-Run: true`)
- **Idempotency:** `Idempotency-Key` required
- **Modes:** Test and live
- **Authentication:** API key with the `disputes:write` scope
- **Since:** M8

## Request

### Path parameters

| Field | Type      | Description |
| ----- | --------- | ----------- |
| `id`  | `dp_…` ID |             |

### Body

This operation takes no body.

## Response

`200 OK` with a JSON object:

| Field                   | Type                                                                                              | Description |
| ----------------------- | ------------------------------------------------------------------------------------------------- | ----------- |
| `id`                    | `dp_…` ID                                                                                         |             |
| `object`                | `"dispute"`                                                                                       |             |
| `livemode`              | boolean                                                                                           |             |
| `entityId`              | `ent_…` ID                                                                                        |             |
| `brandId`               | `brd_…` ID                                                                                        |             |
| `paymentId`             | `pay_…` ID                                                                                        |             |
| `customerId`            | `cus_…` ID                                                                                        |             |
| `processor`             | one of `stripe`, `mollie`, `fake`                                                                 |             |
| `processorConnectionId` | `pcon_…` ID                                                                                       |             |
| `processorRef`          | string                                                                                            |             |
| `reason`                | string or null                                                                                    |             |
| `processorStatus`       | string or null                                                                                    |             |
| `status`                | one of `needs_response`, `under_review`, `won`, `lost`                                            |             |
| `inquiry`               | boolean                                                                                           |             |
| `fundsWithdrawnAt`      | date-time or null                                                                                 |             |
| `amount`                | money                                                                                             |             |
| `fee`                   | money or null                                                                                     |             |
| `evidenceDueBy`         | date-time or null                                                                                 |             |
| `openedAt`              | date-time                                                                                         |             |
| `closedAt`              | date-time or null                                                                                 |             |
| `ledgerTxnIds`          | array of `txn_…` ID                                                                               |             |
| `walletFreeze`          | object or null                                                                                    |             |
| `walletReversal`        | object or null                                                                                    |             |
| `evidence`              | object or null                                                                                    |             |
| `notes`                 | string or null                                                                                    |             |
| `assignee`              | object or null                                                                                    |             |
| `history`               | array of object                                                                                   |             |
| `history[].at`          | date-time                                                                                         |             |
| `history[].event`       | one of 10 values, e.g. `opened`, `wallet_frozen`, `funds_withdrawn` (all in the OpenAPI document) |             |
| `history[].by`          | string                                                                                            |             |
| `history[].note`        | string or null                                                                                    |             |
| `createdAt`             | date-time                                                                                         |             |
| `updatedAt`             | date-time                                                                                         |             |
| `version`               | integer (at least 1)                                                                              |             |

## Examples

### Submit the built pack

```http
POST /api/v1/disputes/dp_01m4ttwd3veh9apbewxheq5xb1/submit_evidence
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
```

Response (`200`):

```json
{
  "id": "dp_01m4ttwd3veh9apbewxheq5xb1",
  "object": "dispute",
  "livemode": true,
  "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
  "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
  "paymentId": "pay_01m4ttwd3veh9apbewxheq5xb2",
  "customerId": "cus_01m4ttwd3veh9apbewxheq5xb3",
  "processor": "stripe",
  "processorConnectionId": "pcon_01m4ttwd3veh9apbewxheq5xb4",
  "processorRef": "dp_1QOwnrecordTest01",
  "reason": "fraudulent",
  "processorStatus": "under_review",
  "status": "under_review",
  "inquiry": false,
  "fundsWithdrawnAt": "2026-10-18T08:00:00.000Z",
  "amount": {
    "amount": "12500000",
    "currency": "EUR"
  },
  "fee": {
    "amount": "15000000",
    "currency": "EUR"
  },
  "evidenceDueBy": "2026-10-25T23:59:59.000Z",
  "openedAt": "2026-10-18T08:00:00.000Z",
  "closedAt": null,
  "ledgerTxnIds": ["txn_01m4ttwd3veh9apbewxheq5xb6"],
  "walletFreeze": {
    "walletIds": ["wal_01m4ttwd3veh9apbewxheq5xb5"],
    "frozenAt": "2026-10-18T08:00:00.000Z",
    "unfrozenAt": null
  },
  "walletReversal": {
    "walletId": "wal_01m4ttwd3veh9apbewxheq5xb5",
    "credits": {
      "amount": "10000000",
      "currency": "EUR"
    },
    "restored": null
  },
  "evidence": {
    "fileId": "file_01m4ttwd3veh9apbewxheq5xb7",
    "sha256": "3f1c6d2b9a7e4f0812c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b",
    "size": 48211,
    "builtAt": "2026-10-19T09:30:00.000Z",
    "builtBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
    "sections": {
      "invoice": true,
      "ip_country": true,
      "usage": true,
      "terms": true,
      "sign_ins": false,
      "waiver": true
    },
    "receiptFileId": "file_01m4ttwd3veh9apbewxheq5xb8",
    "submittedAt": "2026-10-19T09:35:00.000Z",
    "submittedBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
    "processorFileRefs": ["file_1QOwnrecordEvidence1", "file_1QOwnrecordEvidence2"]
  },
  "notes": null,
  "assignee": null,
  "history": [
    {
      "at": "2026-10-18T08:00:00.000Z",
      "event": "opened",
      "by": "system",
      "note": null
    },
    {
      "at": "2026-10-18T08:00:00.000Z",
      "event": "wallet_frozen",
      "by": "system",
      "note": "1 wallet"
    },
    {
      "at": "2026-10-18T08:00:00.000Z",
      "event": "funds_withdrawn",
      "by": "system",
      "note": null
    },
    {
      "at": "2026-10-19T09:30:00.000Z",
      "event": "evidence_built",
      "by": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "note": null
    },
    {
      "at": "2026-10-19T09:35:00.000Z",
      "event": "evidence_submitted",
      "by": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "note": null
    }
  ],
  "createdAt": "2026-10-18T08:00:00.000Z",
  "updatedAt": "2026-10-19T09:35:00.000Z",
  "version": 4
}
```

## Errors

| Code                                                                                                                   | HTTP status | When                                                                                         | What to do                                                                                                                                                                                                                           |
| ---------------------------------------------------------------------------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found)                               | 404         | No dispute with this ID in this brand and mode.                                              | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.                                                                                                                                 |
| [`dispute_status_invalid`](https://ownrecord.io/docs/reference/errors.md#dispute_status_invalid)                       | 409         | The dispute doesn't take evidence any more (already submitted, or closed).                   | Reload the dispute. Evidence is built and submitted only while the dispute needs a response (`needs_response`); once submitted (`under_review`) or closed (`won`, `lost`) it can't change. `details.status` is the dispute's status. |
| [`dispute_evidence_missing`](https://ownrecord.io/docs/reference/errors.md#dispute_evidence_missing)                   | 409         | The pack hasn't been built yet.                                                              | Build the pack with `disputes.evidence.build`, check it in the console (or in the returned `evidence.sections`), then submit it.                                                                                                     |
| [`dispute_evidence_past_due`](https://ownrecord.io/docs/reference/errors.md#dispute_evidence_past_due)                 | 409         | The deadline to respond (`evidenceDueBy`) has passed.                                        | The processor no longer takes evidence after `evidenceDueBy`. The dispute closes as the card network decides; Ownrecord records the outcome from the processor's webhook.                                                            |
| [`dispute_evidence_changed`](https://ownrecord.io/docs/reference/errors.md#dispute_evidence_changed)                   | 409         | The pack's file is missing or changed, or the pack was rebuilt while it was being submitted. | Reload the dispute, check the latest pack and submit again.                                                                                                                                                                          |
| [`dispute_evidence_unsupported`](https://ownrecord.io/docs/reference/errors.md#dispute_evidence_unsupported)           | 400         | The processor takes no dispute evidence through its API.                                     | Download the evidence pack from the console and submit it in the processor's own dashboard. `details.processor` names the processor.                                                                                                 |
| [`processor_connection_disconnected`](https://ownrecord.io/docs/reference/errors.md#processor_connection_disconnected) | 409         | The dispute's processor connection is disconnected.                                          | Connect the processor again, or use another connection of the entity.                                                                                                                                                                |
| [`processor_request_failed`](https://ownrecord.io/docs/reference/errors.md#processor_request_failed)                   | 502         | The processor refused or didn't answer; `retryable` says whether to retry.                   | If `retryable` is true, retry with the same Idempotency-Key after a short wait; otherwise check `details.code`.                                                                                                                      |
| [`version_conflict`](https://ownrecord.io/docs/reference/errors.md#version_conflict)                                   | 409         | The dispute changed at the same moment; retry.                                               | Fetch the object again and retry the change.                                                                                                                                                                                         |
| [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied)                                 | 403         | You can't work on disputes of this brand.                                                    | Ask an organization owner or admin for a role or scope that allows this action.                                                                                                                                                      |

It can also return these [common errors](https://ownrecord.io/docs/reference.md#common-errors): [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed), [`api_version_unsupported`](https://ownrecord.io/docs/reference/errors.md#api_version_unsupported), [`invalid_json`](https://ownrecord.io/docs/reference/errors.md#invalid_json), [`unsupported_media_type`](https://ownrecord.io/docs/reference/errors.md#unsupported_media_type), [`authentication_required`](https://ownrecord.io/docs/reference/errors.md#authentication_required), [`api_key_invalid`](https://ownrecord.io/docs/reference/errors.md#api_key_invalid), [`scope_required`](https://ownrecord.io/docs/reference/errors.md#scope_required), [`idempotency_key_required`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_required), [`idempotency_key_reused`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_reused), [`idempotency_in_progress`](https://ownrecord.io/docs/reference/errors.md#idempotency_in_progress), [`approval_required`](https://ownrecord.io/docs/reference/errors.md#approval_required), [`approval_rejected`](https://ownrecord.io/docs/reference/errors.md#approval_rejected), [`approval_expired`](https://ownrecord.io/docs/reference/errors.md#approval_expired), [`stale_approval`](https://ownrecord.io/docs/reference/errors.md#stale_approval), [`approval_policy_denied`](https://ownrecord.io/docs/reference/errors.md#approval_policy_denied), [`rate_limited`](https://ownrecord.io/docs/reference/errors.md#rate_limited), [`internal_error`](https://ownrecord.io/docs/reference/errors.md#internal_error).
