Learn more about the improvements that come with the V3 Disputes API, which is for both merchants and partners.
Overview
Affirm delivers the V3 Disputes API, which offers a cleaner API experience with full support for listing disputes via query params and pagination, richer dispute context via structured evidence fields, and a simplified URL structure.
All new integrations should use V3. V1 will remain available for existing partners, but won't receive further enhancements.
Authentication
While V1 had separate APIs for merchants and partners, V3 is a unified API for both merchant and partner API keys.
Base URL
# V1
/api/partner/v1/merchants/{merchant_id}/disputes
# V3
/api/v3/disputes
GET /{dispute_id}
GET /{dispute_id}Response body: status updates
status updatesThe status field, which appears on the response object, is also accepted as a query parameter when listing disputes. V3 introduces new status enums with clearer descriptors.
V1 to V3 mapping:
| V1 Value | V3 Equivalent |
|---|---|
needs_review | action_required_merchant |
under_review | no_merchant_action_needed |
lost | closed_customer_favor |
won | closed_merchant_favor |
partially_won | closed_customer_partial_favor |
Note: The five V1 statuses (
lost,needs_review,partially_won,under_review,won) aren't returned by V3 and aren't accepted asstatusfilter values. If your V1 integration relied on these values, you must instead map to the 5 new statuses or use a closed-open state logic based onclosed_at.
Response body: Renamed fields
| V1 Field | V3 Field | Notes |
|---|---|---|
amount | dispute_amount | Same field, only renamed |
reason | dispute_reason | Same field, only renamed |
opening_note | comments[] | The new field is an array of strings, rather than a single string. |
opening_note_attachments | attached_files[] | The new field is an array of {file_name, file_url} objects, rather than a single file ID string. |
Response body: Removed fields
| V1 Field | Notes |
|---|---|
open | Use status to determine whether a dispute is open or closed. |
closing_reason | Removed |
closing_note | Removed |
Response body: New fields
| V3 Field | Type | Description |
|---|---|---|
order_id | string (nullable) | Your internal merchant order ID associated with the dispute. |
transaction_amount | integer (nullable) | The original transaction amount in the smallest currency denomination (e.g. cents). |
updated | datetime (nullable) | Timestamp of when the dispute was last updated. |
extra_evidence[] | array (nullable) | Structured evidence submitted against the dispute. |
Each item in extra_evidence[] can contain one of the following structured objects:
| Object | Fields |
|---|---|
shipping_info | company_name, tracking_number, delivery_date |
communication_info | contact_type, first_contact_date, last_contact_date, merchant_contact_name |
return_info | type, method, return_date, store_address, shipping_information |
Example:
"extra_evidence": [
{
"communication_info": {
"contact_type": "already_contacted",
"merchant_contact_name": "Test Contact",
"first_contact_date": "2025-12-30T00:00:00Z",
"last_contact_date": "2026-01-30T00:00:00Z"
}
},
{
"shipping_info": {
"company_name": "usps",
"tracking_number": "12312312312",
"delivery_date": "2025-12-30T00:00:00Z"
}
},
{
"return_info": {
"type": "all",
"return_date": "2025-12-30T00:00:00Z",
"method": "in_store",
"store_address": "123 Harbrook Lane"
}
}
]Response body: transition_logs changes
transition_logs changesWithin the transition_logs object, we simplify the DisputeEvent object significantly by removing the following V1 fields:
| Removed V1 Field | Notes |
|---|---|
id | Event ID no longer returned. |
dispute_id | Redundant, given request context. |
is_financial | Removed |
financial_amount | Removed |
financial_amount_currency | Removed |
financial_transaction_type | Removed |
dispute_snapshot | Removed |
Note: The V3
DisputeEventfield contains onlytype(string) andcreated(datetime).
Example:
"transition_logs": [
{
"type": "created",
"created": "2026-03-04T02:29:19Z"
},
{
"type": "customer_evidence_added",
"created": "2026-03-04T02:29:19Z"
}
]GET / [List Disputes]
GET / [List Disputes]With the V3 Disputes API, we introduce support for listing disputes via query parameters with pagination. The following parameters are available:
merchant_id: Required for partners.statusdispute_reasoncreated_beforecreated_afterresolved_beforeresolved_afterlimitpage_number: Set to 1 by default.
POST /{dispute_id}/close
POST /{dispute_id}/closeNo changes to the request body. However, the response body includes the updated DisputeEvent object. (See the Response body: transition_logs changes section for details.)
POST /{dispute_id}/submit_evidence
POST /{dispute_id}/submit_evidenceRequest body: Renamed or restructured fields
| V1 Field | V3 Equivalent | Notes |
|---|---|---|
evidence_file_token | file_ids[] | Required. The V3 field is an array of file ID strings, rather than a single value. |
| (absent) | comment | Required. You can now add a comment or summary accompanying the evidence submission. |
Request body: New extra_evidence[] array
extra_evidence[] arrayCurrently for the new array, merchants and partners can only provide shipping_info:
| Object | Fields |
|---|---|
shipping_info | company_name, tracking_number, delivery_date |
Webhooks
Along with updates to the API, we've additionally added new fields to purchase_dispute_opened, purchase_dispute_updated, and purchase_dispute_resolved webhooks.
purchase_dispute_opened
Request body: new fields
| Field | Type | Notes |
|---|---|---|
| currency | string (ISO 4217) | |
| customer_won_amount | integer | Will be null until dispute is closed |
| dispute_amount | integer | |
| dispute_reason | string-enum | |
| dispute_status | string-enum | Will use same enums as Dispute API V3 responses |
| response_due_by | string (ISO 8601) | Will be null is merchant action is not required |
| transaction_amount | integer | |
| transaction_id | string |
Example Payload**
{
created: "2026-03-09T16:58:18.377000Z",
currency: "USD",
customer_won_amount: null,
dispute_amount: 11500,
dispute_id: "EKZP6EBDPBANQE7T",
dispute_reason: "cancellation_or_return_not_processed",
dispute_status: "no_merchant_action_needed",
event_id: "239fbad1-2d78-42d3-9f05-697a5a12fdfd",
event_timestamp: "2026-03-09T16:58:19Z",
event_type: "purchase_dispute_opened",
merchant_id: "0XWX3IT8HD2VOH4Q",
order_id: "test",
response_due_by: null,
transaction_amount: 11500,
transaction_id: "5S30-RRG7"
}purchase_disputed_updated
| Field | Type | Notes |
|---|---|---|
| currency | string (ISO 4217) | |
| customer_won_amount | integer | Will be null until dispute is closed |
| dispute_amount | integer | |
| dispute_reason | string-enum | |
| dispute_status | string-enum | Will use same enums as Dispute API V3 responses |
| response_due_by | string (ISO 8601) | |
| transaction_amount | integer | |
| transaction_id | string |
{
created: "2026-03-09T17:41:37.277000Z",
currency: "USD",
customer_won_amount: null,
dispute_amount: 11500,
dispute_id: "EKZP6EBDPBANQE7T",
dispute_reason: "cancellation_or_return_not_processed",
dispute_status: "action_required_merchant",
event_id: "1512005e-807b-404c-8d2b-5cfff33f13e1",
event_timestamp: "2026-03-09T17:41:38Z",
event_type: "purchase_dispute_updated",
merchant_id: "0XWX3IT8HD2VOH4Q",
order_id: "test",
response_due_by: "2026-03-24T17:41:37.257000Z",
transaction_amount: 11500,
transaction_id: "5S30-RRG7"
}purchase_disputed_closed
| Field | Type | Notes |
|---|---|---|
| currency | string (ISO 4217) | |
| customer_won_amount | integer | |
| dispute_amount | integer | |
| dispute_reason | string-enum | |
| dispute_status | string-enum | Will use same enums as Dispute API V3 responses |
| response_due_by | string (ISO 8601) | Will be null is merchant action is not required |
| transaction_amount | integer | |
| transaction_id | string |
{
created: "2026-03-09T17:54:22.435000Z",
currency: "USD",
customer_won_amount: 11500,
dispute_amount: 11500,
dispute_id: "EKZP6EBDPBANQE7T",
dispute_reason: "cancellation_or_return_not_processed",
dispute_status: "closed_customer_favor",
event_id: "cf35caa0-19f1-48b6-9607-71dfd04c1202",
event_timestamp: "2026-03-09T17:54:22Z",
event_type: "purchase_dispute_resolved",
merchant_id: "0XWX3IT8HD2VOH4Q",
order_id: "test",
response_due_by: null,
transaction_amount: 11500,
transaction_id: "5S30-RRG7"
}