# Use the API to respond to disputes Learn how to manage disputes programmatically. You can programmatically manage disputes using the API. With the API, you can upload evidence, respond to disputes, and receive dispute events using webhooks. If you want to manage disputes using the Dashboard instead of using the API, see [Respond to disputes](https://docs.stripe.com/disputes/responding.md). ## Retrieve a dispute For details about a dispute, [retrieve](https://docs.stripe.com/api/disputes/retrieve.md) a `Dispute` object: ```curl curl https://api.stripe.com/v1/disputes/{{DISPUTE_ID}} \ -u "<>:" ``` ```cli stripe disputes retrieve {{DISPUTE_ID}} ``` ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = '<>' dispute = Stripe::Dispute.retrieve('{{DISPUTE_ID}}') ``` ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("<>") dispute = client.v1.disputes.retrieve('{{DISPUTE_ID}}') ``` ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "<>" dispute = stripe.Dispute.retrieve("{{DISPUTE_ID}}") ``` ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. dispute = client.v1.disputes.retrieve("{{DISPUTE_ID}}") ``` ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('<>'); $dispute = $stripe->disputes->retrieve('{{DISPUTE_ID}}', []); ``` ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "<>"; Dispute dispute = Dispute.retrieve("{{DISPUTE_ID}}"); ``` ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("<>"); DisputeRetrieveParams params = DisputeRetrieveParams.builder().build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Dispute dispute = client.v1().disputes().retrieve("{{DISPUTE_ID}}", params); ``` ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('<>'); const dispute = await stripe.disputes.retrieve('{{DISPUTE_ID}}'); ``` ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "<>" params := &stripe.DisputeParams{} result, err := dispute.Get("{{DISPUTE_ID}}", params) ``` ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("<>") params := &stripe.DisputeRetrieveParams{Dispute: stripe.String("{{DISPUTE_ID}}")} result, err := sc.V1Disputes.Retrieve(context.TODO(), params) ``` ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "<>"; var service = new DisputeService(); Dispute dispute = service.Get("{{DISPUTE_ID}}"); ``` ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var client = new StripeClient("<>"); var service = client.V1.Disputes; Dispute dispute = service.Get("{{DISPUTE_ID}}"); ``` The response contains information about the dispute and any response or evidence that’s already been provided. ```json { object: "dispute" id: "{{DISPUTE_ID}}", charge: "ch_5Q4BjL06oPWwho", evidence: { customer_name: "Jane Austen", customer_purchase_ip: "127.0.0.1", product_description: "Widget ABC, color: red", shipping_tracking_number: "Z01234567890", uncategorized_text: "Additional notes and comments", }, evidence_details: { due_by: 1403047735, submission_count: 1 } ... } ``` ## Update a dispute You [update](https://docs.stripe.com/api/issuing/disputes/update.md) the `Dispute` object and pass structured evidence with the `evidence` parameter. ```curl curl https://api.stripe.com/v1/disputes/{{DISPUTE_ID}} \ -u "<>:" \ --data-urlencode "evidence[customer_email_address]"="email@example.com" \ -d "evidence[shipping_date]"=2024-02-01 \ -d "evidence[shipping_documentation]"="{{FILE_ID}}" ``` ```cli stripe disputes update {{DISPUTE_ID}} \ -d "evidence[customer_email_address]"="email@example.com" \ -d "evidence[shipping_date]"=2024-02-01 \ -d "evidence[shipping_documentation]"="{{FILE_ID}}" ``` ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = '<>' dispute = Stripe::Dispute.update( '{{DISPUTE_ID}}', { evidence: { customer_email_address: 'email@example.com', shipping_date: '2024-02-01', shipping_documentation: '{{FILE_ID}}', }, }, ) ``` ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("<>") dispute = client.v1.disputes.update( '{{DISPUTE_ID}}', { evidence: { customer_email_address: 'email@example.com', shipping_date: '2024-02-01', shipping_documentation: '{{FILE_ID}}', }, }, ) ``` ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "<>" dispute = stripe.Dispute.modify( "{{DISPUTE_ID}}", evidence={ "customer_email_address": "email@example.com", "shipping_date": "2024-02-01", "shipping_documentation": "{{FILE_ID}}", }, ) ``` ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. dispute = client.v1.disputes.update( "{{DISPUTE_ID}}", { "evidence": { "customer_email_address": "email@example.com", "shipping_date": "2024-02-01", "shipping_documentation": "{{FILE_ID}}", }, }, ) ``` ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('<>'); $dispute = $stripe->disputes->update( '{{DISPUTE_ID}}', [ 'evidence' => [ 'customer_email_address' => 'email@example.com', 'shipping_date' => '2024-02-01', 'shipping_documentation' => '{{FILE_ID}}', ], ] ); ``` ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "<>"; Dispute resource = Dispute.retrieve("{{DISPUTE_ID}}"); DisputeUpdateParams params = DisputeUpdateParams.builder() .setEvidence( DisputeUpdateParams.Evidence.builder() .setCustomerEmailAddress("email@example.com") .setShippingDate("2024-02-01") .setShippingDocumentation("{{FILE_ID}}") .build() ) .build(); Dispute dispute = resource.update(params); ``` ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("<>"); DisputeUpdateParams params = DisputeUpdateParams.builder() .setEvidence( DisputeUpdateParams.Evidence.builder() .setCustomerEmailAddress("email@example.com") .setShippingDate("2024-02-01") .setShippingDocumentation("{{FILE_ID}}") .build() ) .build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. Dispute dispute = client.v1().disputes().update("{{DISPUTE_ID}}", params); ``` ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('<>'); const dispute = await stripe.disputes.update( '{{DISPUTE_ID}}', { evidence: { customer_email_address: 'email@example.com', shipping_date: '2024-02-01', shipping_documentation: '{{FILE_ID}}', }, } ); ``` ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "<>" params := &stripe.DisputeParams{ Evidence: &stripe.DisputeEvidenceParams{ CustomerEmailAddress: stripe.String("email@example.com"), ShippingDate: stripe.String("2024-02-01"), ShippingDocumentation: stripe.String("{{FILE_ID}}"), }, } result, err := dispute.Update("{{DISPUTE_ID}}", params) ``` ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("<>") params := &stripe.DisputeUpdateParams{ Evidence: &stripe.DisputeUpdateEvidenceParams{ CustomerEmailAddress: stripe.String("email@example.com"), ShippingDate: stripe.String("2024-02-01"), ShippingDocumentation: stripe.String("{{FILE_ID}}"), }, Dispute: stripe.String("{{DISPUTE_ID}}"), } result, err := sc.V1Disputes.Update(context.TODO(), params) ``` ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "<>"; var options = new DisputeUpdateOptions { Evidence = new DisputeEvidenceOptions { CustomerEmailAddress = "email@example.com", ShippingDate = "2024-02-01", ShippingDocumentation = "{{FILE_ID}}", }, }; var service = new DisputeService(); Dispute dispute = service.Update("{{DISPUTE_ID}}", options); ``` ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new DisputeUpdateOptions { Evidence = new DisputeEvidenceOptions { CustomerEmailAddress = "email@example.com", ShippingDate = "2024-02-01", ShippingDocumentation = "{{FILE_ID}}", }, }; var client = new StripeClient("<>"); var service = client.V1.Disputes; Dispute dispute = service.Update("{{DISPUTE_ID}}", options); ``` To view all available fields for the `evidence` parameter, see [Dispute evidence](https://docs.stripe.com/api/issuing/disputes/create.md#create_issuing_dispute-evidence). There are two types of evidence you can provide, depending on the field being updated: - Text-based evidence, such as `customer_email` and `service_date`. These types of evidence take a string of text. - File-based evidence, such as `service_documentation` and `customer_communication`. These take a [file_upload](https://docs.stripe.com/api/files/object.md#issuing_dispute_object-id) object ID. > The combined character count for all text-based evidence field submissions is limited to 150,000. You can provide documents or images (for example, a contract or screenshot) as part of dispute evidence using the [File Upload API](https://docs.stripe.com/file-upload.md). You first upload a document with the purpose of `dispute_evidence`, which generates a `File_upload` object that you can use when submitting evidence. Make sure the file meets [Stripe’s recommendations](https://docs.stripe.com/disputes/best-practices.md#file-upload-recommendations) before uploading it for evidence submission. If you’re only interested in submitting a single file or a large amount of plaintext as evidence, use `uncategorized_text` or `uncategorized_file`. However, fill in as many fields as possible so you have the best chance at overturning a dispute. ## Multiple disputes on a single payment It’s not typical, but it’s possible for a customer to dispute the same payment more than once. For example, a customer might partially dispute a payment for one of the items in an order if it was damaged in delivery, and then file a second dispute against a different item in the same order because the item didn’t work properly. Stripe distinguishes all disputes by a unique identifier, regardless of whether they’re related to a single payment. When you [list disputes](https://docs.stripe.com/api/disputes/list.md), you can filter the results to show only disputes for a particular payment by specifying the `id` of the `PaymentIntent` or `Charge` object and including the [payment_intent](https://docs.stripe.com/api/disputes/list.md#list_disputes-payment_intent) or [charge](https://docs.stripe.com/api/disputes/list.md#list_disputes-charge) filter. #### By PaymentIntent ```curl curl -G https://api.stripe.com/v1/disputes \ -u "<>:" \ -d payment_intent={{PAYMENT_INTENT_ID}} ``` ```cli stripe disputes list \ --payment-intent={{PAYMENT_INTENT_ID}} ``` ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = '<>' disputes = Stripe::Dispute.list({payment_intent: '{{PAYMENT_INTENT_ID}}'}) ``` ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("<>") disputes = client.v1.disputes.list({payment_intent: '{{PAYMENT_INTENT_ID}}'}) ``` ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "<>" disputes = stripe.Dispute.list(payment_intent="{{PAYMENT_INTENT_ID}}") ``` ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. disputes = client.v1.disputes.list({"payment_intent": "{{PAYMENT_INTENT_ID}}"}) ``` ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('<>'); $disputes = $stripe->disputes->all(['payment_intent' => '{{PAYMENT_INTENT_ID}}']); ``` ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "<>"; DisputeListParams params = DisputeListParams.builder().setPaymentIntent("{{PAYMENT_INTENT_ID}}").build(); DisputeCollection disputes = Dispute.list(params); ``` ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("<>"); DisputeListParams params = DisputeListParams.builder().setPaymentIntent("{{PAYMENT_INTENT_ID}}").build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. StripeCollection stripeCollection = client.v1().disputes().list(params); ``` ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('<>'); const disputes = await stripe.disputes.list({ payment_intent: '{{PAYMENT_INTENT_ID}}', }); ``` ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "<>" params := &stripe.DisputeListParams{PaymentIntent: stripe.String("{{PAYMENT_INTENT_ID}}")} result := dispute.List(params) ``` ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("<>") params := &stripe.DisputeListParams{PaymentIntent: stripe.String("{{PAYMENT_INTENT_ID}}")} result := sc.V1Disputes.List(context.TODO(), params) ``` ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "<>"; var options = new DisputeListOptions { PaymentIntent = "{{PAYMENT_INTENT_ID}}" }; var service = new DisputeService(); StripeList disputes = service.List(options); ``` ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new DisputeListOptions { PaymentIntent = "{{PAYMENT_INTENT_ID}}" }; var client = new StripeClient("<>"); var service = client.V1.Disputes; StripeList disputes = service.List(options); ``` #### By Charge ```curl curl -G https://api.stripe.com/v1/disputes \ -u "<>:" \ -d charge={{CHARGE_ID}} ``` ```cli stripe disputes list \ --charge={{CHARGE_ID}} ``` ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = '<>' disputes = Stripe::Dispute.list({charge: '{{CHARGE_ID}}'}) ``` ```ruby # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = Stripe::StripeClient.new("<>") disputes = client.v1.disputes.list({charge: '{{CHARGE_ID}}'}) ``` ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys import stripe stripe.api_key = "<>" disputes = stripe.Dispute.list(charge="{{CHARGE_ID}}") ``` ```python # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys client = StripeClient("<>") # For SDK versions 12.4.0 or lower, remove '.v1' from the following line. disputes = client.v1.disputes.list({"charge": "{{CHARGE_ID}}"}) ``` ```php // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys $stripe = new \Stripe\StripeClient('<>'); $disputes = $stripe->disputes->all(['charge' => '{{CHARGE_ID}}']); ``` ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys Stripe.apiKey = "<>"; DisputeListParams params = DisputeListParams.builder().setCharge("{{CHARGE_ID}}").build(); DisputeCollection disputes = Dispute.list(params); ``` ```java // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeClient client = new StripeClient("<>"); DisputeListParams params = DisputeListParams.builder().setCharge("{{CHARGE_ID}}").build(); // For SDK versions 29.4.0 or lower, remove '.v1()' from the following line. StripeCollection stripeCollection = client.v1().disputes().list(params); ``` ```node // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('<>'); const disputes = await stripe.disputes.list({ charge: '{{CHARGE_ID}}', }); ``` ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys stripe.Key = "<>" params := &stripe.DisputeListParams{Charge: stripe.String("{{CHARGE_ID}}")} result := dispute.List(params) ``` ```go // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys sc := stripe.NewClient("<>") params := &stripe.DisputeListParams{Charge: stripe.String("{{CHARGE_ID}}")} result := sc.V1Disputes.List(context.TODO(), params) ``` ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys StripeConfiguration.ApiKey = "<>"; var options = new DisputeListOptions { Charge = "{{CHARGE_ID}}" }; var service = new DisputeService(); StripeList disputes = service.List(options); ``` ```dotnet // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys var options = new DisputeListOptions { Charge = "{{CHARGE_ID}}" }; var client = new StripeClient("<>"); var service = client.V1.Disputes; StripeList disputes = service.List(options); ``` When a payment has multiple disputes, use the `id` provided for each returned dispute in the list to make sure you’re responding to the correct dispute by specifying its `id` when you [retrieve](https://docs.stripe.com/disputes/api.md#retrieve-a-dispute) or [update the dispute](https://docs.stripe.com/disputes/api.md#update-a-dispute). ## See also - [Dispute categories](https://docs.stripe.com/disputes/categories.md) - [Measuring disputes](https://docs.stripe.com/disputes/measuring.md) - [Preventing disputes and fraud](https://docs.stripe.com/disputes/prevention.md)