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
evidence_details Fields
balance_transactions Fields (per item)
payment_method_details.card Fields
Dispute Status Lifecycle
Attempting to submit evidence or close a dispute in a non-actionable status returns
422.
Dispute Reason Codes
Endpoints
List Disputes
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
Example
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
Request Body
Evidence Fields
All fields are optional. Include only what is relevant to your dispute reason. Text fields
File fields — use a Flex File ID (
ffile_... from POST /v1/files)
Files must be uploaded with purpose dispute_evidence before use. See Uploading Evidence Files.
Example — save a draft (no submission)
Dispute object with refreshed evidence_details.submission_count.
Close Dispute
needs_response or warning_needs_response status.
Path Parameters
Request Body
No body required.
Example
Dispute object. status will be lost.
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: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:
Use
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.