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.
/api/v1/disputes/{id}/submit_evidenceSends 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-Keyrequired - Modes: Test and live
- Authentication: API key with the
disputes:writescope - 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
POST /api/v1/disputes/dp_01m4ttwd3veh9apbewxheq5xb1/submit_evidence
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Response (200):
{
"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 | 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 | 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 | 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 | 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 | 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 | 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 | 409 | The dispute's processor connection is disconnected. | Connect the processor again, or use another connection of the entity. |
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 | 409 | The dispute changed at the same moment; retry. | Fetch the object again and retry the change. |
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: validation_failed, api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, scope_required, idempotency_key_required, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.