Update a dispute's notes or assignee
The disputes.update operation: PATCH /api/v1/disputes/{id} in the REST API and the disputes_update tool in the MCP server.
/api/v1/disputes/{id}Changes the team's internal notes on a dispute (or removes them with null) and who works on it: a member
who may work on the brand's disputes (support, admins and owners), or null to unassign. Notes are never sent
to the processor: the evidence is the pack (disputes.evidence.build). Works in every status, also after the
dispute closed.
At a glance
- REST:
PATCH /api/v1/disputes/{id} - MCP tool:
disputes_update - Operation ID:
disputes.update - Scope: Brand
- Permission:
disputes:write - Risk tier:
write - Dry run: Supported (send
Ownrecord-Dry-Run: true) - Idempotency:
Idempotency-Keyoptional - Modes: Test and live
- Authentication: API key with the
disputes:writescope - Since: M8
Request
Path parameters
| Field | Type | Description |
|---|---|---|
id | dp_… ID |
Body
A JSON object (Content-Type: application/json):
| Field | Type | Required | Description |
|---|---|---|---|
notes | string or null | No | |
assignee | object or null | No | |
expectedVersion | integer (at least 1) | No |
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
Take the dispute and note what the customer said
PATCH /api/v1/disputes/dp_01m4ttwd3veh9apbewxheq5xb1
Authorization: Bearer or_test_…
Content-Type: application/json
{
"assignee": {
"type": "user",
"id": "usr_01m4ttwd3veh9apbewxheq5xh6"
},
"notes": "Customer says a family member bought the credits; usage log shows 3 API sessions.",
"expectedVersion": 2
}
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": "needs_response",
"status": "needs_response",
"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": null,
"notes": "Customer says a family member bought the credits; usage log shows 3 API sessions.",
"assignee": {
"type": "user",
"id": "usr_01m4ttwd3veh9apbewxheq5xh6"
},
"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": "updated",
"by": "usr_01m4ttwd3veh9apbewxheq5xh6",
"note": "assignee, notes"
}
],
"createdAt": "2026-10-18T08:00:00.000Z",
"updatedAt": "2026-10-19T09:30:00.000Z",
"version": 3
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | Nothing to change, or a value is invalid. | Fix the fields listed in details.issues and send the request again. |
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_assignee_invalid | 400 | The person isn't a member who may work on this brand's disputes. | Assign a member of the organization who may work on this brand's disputes in this mode (support, admins and owners at the organization, the entity or this brand). details.userId is the ID given. |
version_conflict | 409 | The dispute changed since expectedVersion, or at the same moment. | 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: api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, scope_required, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.