Table of Contents
- Overview
- Authentication
- The Dispute Object
- Dispute Status Lifecycle
- Dispute Reason Codes
- Endpoints
- Uploading Evidence Files
- Webhook Events
- Error Reference
- End-to-End Testing Guide
Overview
- Receives the
charge.dispute.createdevent. - Creates a
Disputerecord linked to yourpayment_intent_idandcharge_id. - Forwards a
charge.dispute.createdevent to your registered webhook endpoint.
evidence_details.due_by to respond. Submitting evidence with submit: true sends it immediately and increments submission_count. You may re-submit with updated evidence before the deadline. Alternatively, POST /v1/disputes/:id/close concedes the dispute immediately.
Authentication
All requests require a bearer token (API key).404.
The Dispute Object
Field Reference
| Field | Type | Description |
|---|---|---|
dispute_id | string | Flex dispute ID (fdsp_ prefix). Use this in all API calls. |
payment_intent_id | string | Flex payment intent ID (fpi_) linked to this dispute. |
charge_id | string | null | Flex charge ID (fch_) linked to this dispute. |
amount | integer | Disputed amount in cents (e.g. 4999 = $49.99). |
currency | string | Three-letter ISO currency code (e.g. "usd"). |
status | string | Current dispute status. See Dispute Status Lifecycle. |
reason | string | Reason code provided by the card network. See Dispute Reason Codes. |
is_charge_refundable | boolean | Whether the underlying charge can be refunded. |
metadata | object | Arbitrary key-value metadata. |
created_at | string | ISO 8601 timestamp when the dispute was created. |
test_mode | boolean | true if this is a test-mode dispute. |
evidence_details | object | null | Evidence submission deadline and status. See below. |
balance_transactions | array | Balance transactions associated with this dispute (withdrawals and reinstatements). Only populated on single-dispute GET. |
payment_method_details | object | null | Card details for the disputed payment. Only populated on single-dispute GET. |
evidence_details Fields
| Field | Type | Description |
|---|---|---|
due_by | string | null | ISO 8601 deadline for submitting evidence. null if no deadline has been set yet. |
has_evidence | boolean | true if any evidence has been saved (draft or submitted). |
past_due | boolean | true if the submission deadline has passed. |
submission_count | integer | Number of times evidence has been submitted. |
balance_transactions Fields (per item)
| Field | Type | Description |
|---|---|---|
balance_transaction_id | string | Flex balance transaction ID (fbt_ prefix). |
amount | integer | Amount in cents. Negative = debit from your balance. |
fee | integer | Dispute fee in cents (charged by the card network). |
net | integer | Net impact on your balance (amount + fee). |
status | string | pending or available. |
type | string | "adjustment" for dispute debit or reinstatement credit. |
created_at | string | null | ISO 8601 timestamp. |
payment_method_details.card Fields
| Field | Type | Description |
|---|---|---|
brand | string | null | Card brand: "visa", "mastercard", "amex", "discover", etc. |
network_reason_code | string | null | Card network reason code (e.g. "10.4" for Visa, "4853" for Mastercard). |
Dispute Status Lifecycle
| Status | Description | Can Submit Evidence | Can Close |
|---|---|---|---|
needs_response | Dispute is open and awaiting your response. | ✅ | ✅ |
warning_needs_response | Inquiry (pre-chargeback) needing response. | ✅ | ✅ |
under_review | Evidence submitted; issuer reviewing. | ❌ | ❌ |
warning_under_review | Inquiry under review. | ❌ | ❌ |
won | Dispute resolved in your favour. | ❌ | ❌ |
lost | Dispute resolved against you. Funds forfeited. | ❌ | ❌ |
warning_closed | Inquiry closed without becoming a chargeback. | ❌ | ❌ |
422.
Dispute Reason Codes
| Value | Description |
|---|---|
fraudulent | Customer claims they did not authorise the charge. Most common. |
product_not_received | Customer claims they did not receive the product/service. |
product_unacceptable | Customer claims the product/service was defective or not as described. |
credit_not_processed | Customer claims a refund they were promised was never processed. |
duplicate | Customer claims they were charged twice for the same transaction. |
subscription_canceled | Customer claims they were charged after cancelling a subscription. |
unrecognized | Customer does not recognise the charge. |
bank_cannot_process | Bank returned the charge for technical reasons. |
debit_not_authorized | Customer claims the debit was not authorised. |
customer_initiated | Customer-initiated dispute. |
check_returned | Check was returned. |
incorrect_account_details | Account details were incorrect. |
insufficient_funds | Insufficient funds. |
general | General / uncategorised reason. |
Endpoints
List Disputes
| Parameter | Type | Description |
|---|---|---|
limit | integer | Number of disputes to return. Default 20, max 100. |
starting_after | string | Cursor for forward pagination. Pass the last dispute_id from the previous page. |
ending_before | string | Cursor for backward pagination. Pass the first dispute_id from the current page. |
charge | string | Filter by Flex charge ID (fch_...). |
payment_intent | string | Filter by Flex payment intent ID (fpi_...). |
Note:Example — list all disputesbalance_transactionsandpayment_method_detailsare not populated in list responses. UseGET /v1/disputes/:idto get the full dispute.
Get Dispute
balance_transactions and payment_method_details.
Path Parameters
| Parameter | Description |
|---|---|
dispute_id | Flex dispute ID (fdsp_...). |
| Status | When |
|---|---|
404 | Dispute not found or belongs to a different partner. |
Update Evidence
submit: true to submit evidence immediately. Set submit: false (or omit it) to save a draft without submitting.
The dispute must be in needs_response or warning_needs_response status.
Path Parameters
| Parameter | Description |
|---|---|
dispute_id | Flex dispute ID (fdsp_...). |
Evidence Fields
All fields are optional. Include only what is relevant to your dispute reason. Text fields| Field | Description |
|---|---|
customer_name | Full name of the customer as it appears in your records. |
customer_email_address | Email address of the customer. |
customer_purchase_ip | IP address the customer used when making the purchase. |
billing_address | Billing address as entered during checkout. |
product_description | Description of the product or service. Be specific. |
service_date | Date the service was provided (YYYY-MM-DD). |
shipping_address | Address where the product was shipped. |
shipping_carrier | Carrier name (e.g. "UPS", "FedEx"). |
shipping_date | Date the product was shipped (YYYY-MM-DD). |
shipping_tracking_number | Tracking number for the shipment. |
duplicate_charge_id | The Flex charge ID of the original, legitimate charge (for duplicate disputes). |
duplicate_charge_explanation | Explanation of why the charges are different (for duplicate disputes). |
cancellation_policy_disclosure | Explanation of how the cancellation policy was disclosed to the customer. |
cancellation_rebuttal | Rebuttal to the customer’s cancellation claim. |
refund_policy_disclosure | Explanation of how the refund policy was disclosed. |
refund_refusal_explanation | Explanation of why a refund was not issued. |
access_activity_log | Log of customer access to the service (relevant for product_not_received). |
uncategorized_text | Any additional evidence or context. |
ffile_... from POST /v1/files)
Files must be uploaded with purpose dispute_evidence before use. See Uploading Evidence Files.
| Field | Description |
|---|---|
receipt | Receipt or order confirmation. |
customer_communication | Email/chat correspondence with the customer. |
customer_signature | Signed delivery confirmation or service agreement. |
cancellation_policy | Copy of your cancellation policy. |
refund_policy | Copy of your refund policy. |
duplicate_charge_documentation | Documentation showing the original charge was legitimate. |
service_documentation | Proof the service was delivered. |
shipping_documentation | Shipping confirmation or carrier proof of delivery. |
uncategorized_file | Any additional supporting document. |
Dispute object with refreshed evidence_details.submission_count.
| Status | When |
|---|---|
404 | Dispute not found or belongs to a different partner. |
422 | Dispute is not in needs_response / warning_needs_response status. |
404 | A referenced file ID (ffile_...) does not exist. |
422 | A referenced file was not uploaded with dispute_evidence purpose. |
Close Dispute
needs_response or warning_needs_response status.
Path Parameters
| Parameter | Description |
|---|---|
dispute_id | Flex dispute ID (fdsp_...). |
Dispute object. status will be lost.
| Status | When |
|---|---|
404 | Dispute not found or belongs to a different partner. |
422 | Dispute is not in needs_response / warning_needs_response status. |
Uploading Evidence Files
Before referencing a file in an evidence submission, upload it using the Files API with purposedispute_evidence.
file_id (ffile_...) in evidence file fields. Attempting to use a file with a different purpose (e.g. identity_document) will return a 422 with a clear error message indicating which field is invalid and what purpose was found vs expected.
Webhook Events
Configure a webhook endpoint in your Flex dashboard to receive dispute lifecycle events.charge.dispute.created
Fired when a dispute is opened against one of your charges.
charge.dispute.updated
Fired when a dispute’s status, evidence, or deadline changes (including when you submit evidence via the API).
Recommended action: Refresh your local dispute record.
charge.dispute.closed
Fired when a dispute is resolved — either won, lost, or warning_closed.
Recommended action: Update your records; if lost, the funds have been debited.
charge.dispute.funds_withdrawn
Fired when funds are withdrawn from your balance to cover the disputed amount. A balance transaction is added to the dispute.
charge.dispute.funds_reinstated
Fired when a previously disputed amount is returned to your balance (dispute won).
All webhook payloads include a flex-signature header for verification. See the Webhooks documentation for signature verification details.
Error Reference
All errors follow a standard format:| HTTP Status | code | When |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
404 | not_found | Dispute or file not found (or belongs to another partner). |
422 | validation_error | Invalid status transition or file validation failure. |
500 | server_error | Internal error — contact support with the request ID. |
End-to-End Testing Guide
Prerequisites
- Flex API key (test mode)
- Test card numbers (see below)
- A registered webhook endpoint to receive events
Step 1 — Trigger a dispute
Create a checkout session and complete payment using an auto-dispute test card:| Card Number | Dispute Reason | Notes |
|---|---|---|
4000 0000 0000 0259 | fraudulent | Automatically disputed after charge |
4000 0000 0000 2685 | product_not_received | Automatically disputed after charge |
4111 1111 1111 1111 as a valid non-disputing card for comparison.
After completing payment:
- The charge is automatically disputed (test mode only)
- Flex receives the
charge.dispute.createdevent - Your webhook endpoint receives the
charge.dispute.createdevent
Step 2 — Inspect the dispute
status: "needs_response"evidence_details.due_byis a future timestampevidence_details.submission_count: 0balance_transactionscontains one debit entry
Step 3 — Submit evidence
- Response
evidence_details.submission_count: 1 - Response
statuschanges to"under_review"
Step 4 — Close a second dispute
Create another charge with the auto-dispute card. Then:- Response
status: "lost"
Step 5 — Verify multi-tenant isolation
Using a different partner’s API key, attempt to access the dispute IDs from Steps 2–4. All should return404.
Step 6 — Test error cases
Invalid status transition: TryPOST /v1/disputes/fdsp_.../close on a dispute that is already lost or under_review. Expected: 422 with message "Cannot close dispute in '...' status".
File with wrong purpose:
Upload a file with purpose=identity_document, then reference it in an evidence field. Expected: 422 with message indicating which field has the wrong file purpose.
Non-existent dispute:
404.