NAV

chargehound

API
cURL Node Python Ruby Go Java

Overview

Chargehound's API is organized around REST. JSON is returned by all API responses, including errors, although our API libraries convert responses to appropriate language-specific objects. All API URLs listed in this documentation are relative to https://api.chargehound.com/v1/. For example, the /disputes/ resource is located at https://api.chargehound.com/v1/disputes.

All requests must be made over HTTPS.

Authentication

curl -u test_123:
var chargehound = require('chargehound')(
  'test_123'
);
import chargehound
chargehound.api_key = 'test_123'
require 'chargehound'
Chargehound.api_key = 'test_123'
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123") 
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("test_123");

Make sure to replace test_123 with your API key.

You have two API keys, one for test and one for live data.

Authentication to the API is performed via HTTP Basic Auth. Your API key serves as your username. You do not need to provide a password, so the full authorization string should have the form {{key}}:.

If you are setting authentication in the HTTP Headers with the form Authorization: Basic {{credentials}} be sure to base 64 encode the credentials so that, for example, test_123: becomes dGVzdF9YWFg6.

Errors

{
  "url": "/v1/disputes/puppy/submit",
  "livemode": false,
  "error": {
    "status": 404,
    "message": "A dispute with id 'puppy' was not found",
    "type": "dispute_not_found"
  }
}

Chargehound uses conventional HTTP response codes to indicate success or failure of an API request. In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error that resulted from the provided information (e.g. a required parameter was missing, a payment failed, etc.), and codes in the 5xx range indicate an error with our servers.

HTTP status code summary

Status Description
200 - OK Everything worked as expected.
201 - Created The resource was successfully created.
202 - Accepted The request was successfully processed but not completed.
400 - Bad Request The request data was invalid or incomplete.
401 - Unauthorized Invalid API key provided.
403 - Forbidden Insecure connection.
404 - Not Found Resource could note be found.
500 - Server Error Something went wrong on Chargehound's end.

Error details

An API error has a few standard fields in the "error" JSON object. These fields are "status", "message", and "type".

"status" is the HTTP status code of the error.

"message" is a human readable description of the error. This is the place to look when debugging.

"type" is a structured error type string. This can help you programmatically handle some errors.

Error types

Type Description
authentication Invalid API key provided.
dispute_closed Dispute won/lost and cannot be updated.
dispute_not_found No dispute found for the given ID.
dispute_overdue Dispute overdue and cannot be submitted.
dispute_submitted Dispute already submitted and cannot be submitted again.
dispute_uneditable Dispute cannot be updated.
invalid_correspondence Invalid correspondence data.
invalid_fields Invalid fields data.
invalid_past_payments Invalid past payments data.
invalid_products Invalid products data.
invalid_request The request data was invalid or incomplete.
missing_fields Missing fields required by template.
missing_template Template not set for dispute.
template_not_found No template found for the given ID.

Handling errors

var Chargehound = require('chargehound')('test_123')

// Use the Chargehound library to make a request
.then(function () {
  // handle success
})
.catch(function (err) {
  if (err instanceof Chargehound.error.ChargehoundBadRequestError) {
    // Invalid parameters were supplied in the request

    console.log('Status is: ' + err.status)
    console.log('Message is: ' + err.message)

  } else if (err instanceof Chargehound.error.ChargehoundAuthenticationError) {
    // Incorrect or missing API key
  } else if (err instanceof Chargehound.error.ChargehoundError) {
    // Generic Chargehound error (404, 500, etc.)
  } else {
    // Handle any other types of unexpected errors
  }
})
from chargehound.error import (
  ChargehoundError, ChargehoundBadRequestError, 
  ChargehoundAuthenticationError
)

try:
  # Use the Chargehound library to make a request
except ChargehoundBadRequestError, e:
  # Invalid parameters were supplied in the request

  print 'Status is: %s' % e.status
  print 'Message is: %s' % e.message

  pass
except ChargehoundAuthenticationError, e:
  # Incorrect or missing API key
  pass
except ChargehoundError, e:
  # Generic Chargehound error (404, 500, etc.)
  pass
except Exception, e:
  # Handle any other types of unexpected errors
  pass
require 'chargehound/error'

begin
  # Use the Chargehound library to make a request
rescue Chargehound::ChargehoundBadRequestError => e
  # Invalid parameters were supplied in the request

  puts 'Status is: #{e.status}'
  puts 'Message is: #{e.message}'

rescue Chargehound::ChargehoundAuthenticationError => e
  # Incorrect or missing API key
rescue Chargehound::ChargehoundTimeoutError => e
  # The request timed out (default timeout is 60 seconds)
rescue Chargehound::ChargehoundError => e
  # Generic Chargehound error (404, 500, etc.)
rescue => e
  # Handle any other types of unexpected errors
end
import (
  "fmt"
  "github.com/chargehound/chargehound-go"
)

// Use the Chargehound library to make a request

chErr := err.(chargehound.Error)

switch chErr.Type() {
case BadRequestError:
  // Invalid parameters were supplied in the request

  fmt.Println(chErr.Error())

case chargehound.UnauthorizedError:
  // Missing API key
case chargehound.ForbiddenError:
  // Incorrect API key
case chargehound.NotFoundError:
  // Not found
case chargehound.InternalServerError:
  // Internal server error
case chargehound.GenericError:
  // Generic Chargehound error 
default:
  // Handle any other types of unexpected errors
}
import com.chargehound.errors.ChargehoundException;

try {
  // Use the Chargehound library to make a request
} catch (ChargehoundException.HttpException.Unauthorized exception) {
  // Missing API key
} catch (ChargehoundException.HttpException.Forbidden exception) {
  // Incorrect API key
} catch (ChargehoundException.HttpException.NotFound exception) {
  // Not found
} catch (ChargehoundException.HttpException.BadRequest exception) {
  // Bad request
} catch (ChargehoundException.HttpException.InternalServerError exception) {
  // Internal server error
} catch (ChargehoundException exception) {
  // Generic Chargehound error
} catch (Exception exception) {
  // Handle any other types of unexpected errors
}

When using our client libraries Chargehound also provides typed exceptions when errors are returned from the API.

Response metadata

Our API responses contain a few standard metadata fields in the JSON. These fields are "object", "livemode", and "url".

"object" identifies the type of object returned by the API. Currently the object can be a "dispute", "list", or "webhook". A list contains a list of other objects in the "data" field.

"livemode" shows whether the API returned test or live data. The mode is determined by which API key was used to authenticate.

"url" shows the path of the request that was made.

Libraries

Chargehound offers wrapper libraries in the following languages:

HTTP

When sending a body along with Content-Type: application/json, the Chargehound API expects JSON.

curl -X PUT https://api.chargehound.com/v1/disputes/dp_123 \
  -u test_123: \
  -H "Content-Type: application/json" \
  -d "{\"fields\": { \"product_url\":  \"http://www.example.com/products/cool\" } }"

When sending a body along with Content-Type: application/x-www-form-urlencoded, the Chargehound API expects form data. This Content Type is set automatically by curl. Dictionaries can be expressed with square brackets.

curl -X PUT https://api.chargehound.com/v1/disputes/dp_123 \
  -u test_123: \
  -d fields[product_url]=http://www.example.com/products/cool

If you are making HTTP requests directly, be sure to set the Content-Type header in PUT/POST requests to specify the format of the body. The Chargehound API supports JSON and URL encoding.

Versioning

The Chargehound API uses versioning to roll out backwards-incompatible changes over time.

About Versioning

The API version will control the API and webhook behaviors, such as parameters accepted in requests, and response properties. Your account was automatically set to the latest version when you signed up.

A new version of the API is released when backwards-incompatible changes are made to the API. To avoid breaking your code, we will never force you to upgrade until you’re ready.

We will be releasing backwards-compatible changes without introducing new versions. Your code will be able to handle these changes no matter what version it's on.

Examples of backwards-incompatible changes:

Examples of backwards-compatible changes:

Upgrading API Version

We recommend staying up-to-date with the current API version to take advantage of latest improvements to the Chargehound API.

To see your current version and upgrade to the latest, visit the API Version section of the API tab on the Chargehound dashboard here.

All requests to the API will use your organization API settings, unless you override the API version. Versioning of the Chargehound API will be released as dates, displayed as: YYYY-MM-DD

The API version used by your webhooks can be configured individually for each webhook URL you have configured in the Webhook URLs section of the API tab on the Chargehound dashboard here.

Testing API Version

To set the API version on a specific request, send a Chargehound-Version header. The API version will be set to the version that you specify for that individual request.

curl -X POST https://api.chargehound.com/v1/disputes \
  -u test_123: \
  -H "Chargehound-Version: YYYY-MM-DD"
var chargehound = require('chargehound')('test_123', {
  version: 'YYYY-MM-DD'
});
import chargehound
chargehound.api_key = 'test_123'
chargehound.version = 'YYYY-MM-DD'
require 'chargehound'
Chargehound.api_key = 'test_123'
Chargehound.version = 'YYYY-MM-DD'
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123",
  &chargehound.ClientParams{APIVersion: "YYYY-MM-DD"})
import com.chargehound.Chargehound;
Chargehound chargehound = new Chargehound("test_123");
chargehound.setApiVersion("YYYY-MM-DD");

Changelog

Version 2021-09-15

In this API version, we changed the behavior of the webhook dispute.closed event.

In older versions, a dispute.closed notification would only be sent if Chargehound submitted the dispute. Starting with this version, the dispute.closed notification will be sent for all closed disputes, whether Chargehound submitted evidence or not.

Version 2020-02-28

In this API version, we changed the behavior of the accept filters and the accepted state.

In older versions, workflow rules for accepting disputes were only applied to new disputes, and disputes in the accepted state could be submitted normally by API requests. Accepted disputes were intended to help with dashboard organization and did not affect API integrations.

Starting with this version, workflow rules for accepting disputes are also applied when disputes are updated or submitted via API, and disputes in the accepted state cannot be submitted by API requests without the force parameter. Accepted disputes are intended to complement manual review filters.

Version 2017-10-30

In this API version, we’ve cleaned up some attribute names in order to make them more consistent and intuitive.

Documentation

Documentation is available for all releases:

Disputes

The dispute object

Dispute objects represent a dispute created on a charge. They can also be referred to as chargebacks. In order to contest a dispute, attach a template and update the dispute with the template's required fields.

A dispute object is:

Field Type Description
id string A unique identifier for the dispute. This id is set by the payment processor of the dispute.
state string State of the dispute. One of needs_response,submitted, under_review, won, lost, warning_needs_response, warning_under_review, warning_closed , response_disabled, charge_refunded, requires_review, accepted, queued.
reason string Reason for the dispute. One of general, fraudulent, duplicate, subscription_canceled, product_unacceptable, product_not_received, unrecognized, credit_not_processed, incorrect_account_details, insufficient_funds, bank_cannot_process, debit_not_authorized, goods_services_returned_or_refused, goods_services_cancelled, transaction_amount_differs, retrieved, customer_initiated
charged_at string ISO 8601 timestamp - when the charge was made.
disputed_at string ISO 8601 timestamp - when the charge was disputed.
due_by string ISO 8601 timestamp - when dispute evidence needs to be disputed by.
submitted_at string ISO 8601 timestamp - when dispute evidence was submitted.
closed_at string ISO 8601 timestamp - when the dispute was resolved.
submitted_count integer Number of times the dispute evidence has been submitted.
template string Id of the template attached to the dispute.
fields dictionary Evidence fields attached to the dispute.
missing_fields dictionary Any fields required by the template that have not yet been provided.
products array A list of products in the disputed order. (See Product data for details.)
correspondence array A list of communications with the customer. (See Customer correspondence for details.)
charge string Id of the disputed charge. This id is set by the payment processor of the dispute.
is_charge_refundable boolean Can the charge be refunded.
amount integer Amount of the disputed charge. Amounts are in cents (or other minor currency unit.)
currency string Currency code of the disputed charge. e.g. 'USD'.
fee integer The amount deducted due to the payment processor's chargeback fee. Amounts are in cents (or other minor currency unit.)
reversal_amount integer The amount deducted due to the chargeback. Amounts are in cents (or other minor currency unit.)
reversal_currency string Currency code of the deduction amount. e.g. 'USD'.
customer string Id of the customer (if any). This id is set by the payment processor of the dispute.
customer_name string Name of the customer (if any).
customer_email string Email of the customer (if any).
customer_purchase_ip string IP of purchase (if available).
address_zip string Billing address zip of the charge.
address_line1_check string State of address check (if available). One of pass, fail, unavailable, unchecked.
address_zip_check string State of address zip check (if available). One of pass, fail, unavailable, unchecked.
cvc_check string State of cvc check (if available). One of pass, fail, unavailable, unchecked.
statement_descriptor string The descriptor that appears on the customer's credit card statement for this change.
account_id string The account id for accounts that are charged directly through Stripe (if any). (See Stripe charging directly for details.)
created string ISO 8601 timestamp - when the dispute was created in Chargehound.
updated string ISO 8601 timestamp - when the dispute was last updated in Chargehound.
source string The source of the dispute. One of mock, api, braintree, vantiv, adyen, worldpay, paypal, amex, 'checkout', or stripe
processor string The payment processor of the dispute. One of braintree, vantiv, adyen, worldpay, paypal, amex, 'checkout', or stripe
kind string The kind of the dispute. One of chargeback, pre_arbitration or retrieval
account string The Id of the connected account for this dispute.
reference_url string Custom URL with dispute information, such as the dispute or charge in your company dashboard.

Submitting a dispute

Definition:

POST /v1/disputes/{{dispute_id}}/submit
chargehound.Disputes.submit();
chargehound.Disputes.submit()
Chargehound::Disputes.submit
ch.Disputes.Submit(*chargehound.UpdateDisputeParams)
chargehound.disputes.submit();

Example request:

curl -X POST https://api.chargehound.com/v1/disputes/dp_123/submit \
  -u test_123: \
  -d template=unrecognized \
  -d fields[customer_name]="Susie Chargeback" 
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.submit('dp_123', {
  template: 'unrecognized',
  fields: {
    customer_name: 'Susie Chargeback'
  }
}, function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.submit('dp_123',
  template='unrecognized',
  fields={
    'customer_name': 'Susie Chargeback'
  }
)
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.submit('dp_123',
  template: 'unrecognized',
  fields: {
    'customer_name' => 'Susie Chargeback'
  }
)
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.UpdateDisputeParams{
  ID:       "dp_123",
  Template: "unrecognized",
  Fields: map[string]interface{}{
    "customer_name": "Susie Chargeback",
  },
}

dispute, err := ch.Disputes.Submit(&params)
import com.chargehound.Chargehound;
import com.chargehound.models.Dispute;

Chargehound chargehound = new Chargehound("test_123");

Map<String, Object> fields = new HashMap<String, Object>();
fields.put("customer_name", "Susie Chargeback");

chargehound.disputes.submit("dp_123",
  new Dispute.UpdateParams.Builder()
    .template("unrecognized")
    .fields(fields)
    .finish()
);

Example response:

{
  "customer": "cus_123",
  "livemode": false,
  "updated": "2016-10-18T20:38:51",
  "currency": "usd",
  "missing_fields": {},
  "address_zip_check": "pass",
  "closed_at": null,
  "id": "dp_123",
  "customer_name": "Susie Chargeback",
  "fee": 1500,
  "reversal_amount": 500,
  "due_by": "2016-11-18T20:38:51",
  "state": "submitted",
  "statement_descriptor": "COMPANY",
  "source": "stripe",
  "charge": "ch_123",
  "template": "unrecognized",
  "is_charge_refundable": false,
  "cvc_check": "unavailable",
  "customer_email": "susie@example.com",
  "account_id": null,
  "address_line1_check": "pass",
  "object": "dispute",
  "customer_purchase_ip": null,
  "disputed_at": "2016-09-18T20:38:51",
  "submitted_count": 0,
  "reason": "unrecognized",
  "reversal_total": 2000,
  "reversal_currency": "usd",
  "address_zip": null,
  "submitted_at": "2016-10-18T20:38:51",
  "created": "2016-09-18T20:38:51",
  "url": "/v1/disputes/dp_123",
  "fields": {
    "customer_name": "Susie Chargeback"
  },
  "charged_at": "2016-09-18T20:38:51",
  "products": [],
  "past_payments": [],
  "correspondence": [],
  "reference_url": null,
  "amount": 500,
  "processor": "stripe",
  "account": "default"
}

You will want to submit the dispute through Chargehound after you receive the dispute.created webhook notification. With one POST request you can update a dispute with the evidence fields and send the generated response to the source payment processor.

The dispute will be in the submitted state if the submit was successful.

Parameters

Parameter Type Required? Description
template string optional The id of the template to use.
fields dictionary optional Key value pairs to hydrate the template's evidence fields.
products array optional List of products the customer purchased. (See Product data for details.)
correspondence array optional A list of communications with the customer. (See Customer correspondence for details.)
past_payments array optional History of the customer's valid, non-disputed transactions using the same card. (See Past payments for details.)
reference_url string optional Custom URL with dispute information, such as the dispute or charge in your company dashboard.
queue boolean optional Queue the dispute for submission. (See Queuing for submission for details.)
force boolean optional Submit a dispute in manual review (see Manual review for details) or submit an accepted dispute (see Accepting a dispute for details.)
account string optional Id of the connected account for this dispute (if multiple accounts are connected). View your connected accounts in the Chargehound dashboard settings page here.

Possible errors

Error code Description
400 Bad Request Dispute has no template, or missing fields required by the template.

Creating a dispute

Disputes are usually not created via the REST API. Instead, once your payment processor is connected we will mirror disputes via webhooks. You will reference the dispute with the same id that is used by the payment processor. If you are working on a standalone integration, please refer to this section.

Retrieving a list of disputes

Definition:

GET /v1/disputes
chargehound.Disputes.list();
chargehound.Disputes.list()
Chargehound::Disputes.list
ch.Disputes.List(*chargehound.ListDisputesParams)
chargehound.disputes.list();

Example request:

curl https://api.chargehound.com/v1/disputes?state=warning_needs_response&state=needs_response \
  -u test_123:
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.list({state: ['warning_needs_response', 'needs_response']}, function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.list(state=['warning_needs_response', 'needs_response'])
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.list(state: %w[warning_needs_response needs_response])
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

disputeList, err := ch.Disputes.List(&chargehound.ListDisputesParams{
    State: []string{
      "warning_needs_response",
      "needs_response",
    },
  })
import com.chargehound.Chargehound;
import com.chargehound.models.DisputesList;

Chargehound chargehound = new Chargehound("test_123");

DisputesList.Params params = new DisputesList.Params.Builder()
    .state("warning_needs_response", "needs_response")
    .finish();

DisputesList result = chargehound.disputes.list(params);

Example response:

{
  "has_more": false,
  "url": "/v1/disputes",
  "livemode": false,
  "object": "list",
  "data": [
    {
      "customer": "cus_123",
      "updated": null,
      "currency": "usd",
      "missing_fields": {},
      "address_zip_check": "pass",
      "closed_at": null,
      "id": "dp_123",
      "customer_name": "Susie Chargeback",
      "fee": 1500,
      "reversal_amount": 500,
      "due_by": "2016-11-18T20:38:51",
      "state": "needs_response",
      "statement_descriptor": "COMPANY",
      "source": "stripe",
      "charge": "ch_123",
      "template": null,
      "is_charge_refundable": false,
      "cvc_check": "unavailable",
      "customer_email": "susie@example.com",
      "account_id": null,
      "address_line1_check": "pass",
      "object": "dispute",
      "customer_purchase_ip": null,
      "disputed_at": "2016-09-18T20:38:51",
      "submitted_count": 0,
      "reason": "unrecognized",
      "reversal_total": 2000,
      "reversal_currency": "usd",
      "address_zip": null,
      "submitted_at": null,
      "created": "2016-09-18T20:38:51",
      "url": "/v1/disputes/dp_123",
      "fields": {},
      "charged_at": "2016-09-18T20:38:51",
      "products": [],
      "past_payments": [],
      "correspondence": [],
      "reference_url": null,
      "amount": 500,
      "processor": "stripe",
      "account": "default"
    }
  ]
}

This endpoint will list all the disputes that we have synced from your payment processor(s). By default the disputes will be ordered by created with the most recent dispute first. has_more will be true if more results are available.

Parameters

Parameter Type Required? Description
limit integer optional Maximum number of disputes to return. Default is 20, maximum is 100.
starting_after string optional A dispute id. Fetch the next page of disputes (disputes created before this dispute).
ending_before string optional A dispute id. Fetch the previous page of disputes (disputes created after this dispute).
state string optional Dispute state. Filter the disputes by state. Multiple state parameters can be provided to expand the filter to multiple states.
account string optional Account id. Will only fetch disputes under that connected account. View your connected accounts in the Chargehound dashboard settings page here.

Retrieving a dispute

Definition:

GET /v1/disputes/{{dispute_id}}
chargehound.Disputes.retrieve();
chargehound.Disputes.retrieve()
Chargehound::Disputes.retrieve
ch.Disputes.Retrieve(*chargehound.RetrieveDisputeParams)
chargehound.disputes.retrieve();

Example request:

curl https://api.chargehound.com/v1/disputes/dp_123 \
  -u test_123:
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.retrieve('dp_123', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.retrieve('dp_123')
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.retrieve('dp_123')
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.RetrieveDisputeParams{
  ID: "dp_123",
}

dispute, err := ch.Disputes.Retrieve(&params)
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("test_123");

chargehound.disputes.retrieve("dp_123");

Example response:

{
  "customer": "cus_123",
  "livemode": false,
  "updated": null,
  "currency": "usd",
  "missing_fields": {},
  "address_zip_check": "pass",
  "closed_at": null,
  "id": "dp_123",
  "customer_name": "Susie Chargeback",
  "fee": 1500,
  "reversal_amount": 500,
  "due_by": "2016-11-18T20:38:51",
  "state": "needs_response",
  "statement_descriptor": "COMPANY",
  "source": "stripe",
  "charge": "ch_123",
  "template": null,
  "is_charge_refundable": false,
  "cvc_check": "unavailable",
  "customer_email": "susie@example.com",
  "account_id": null,
  "address_line1_check": "pass",
  "object": "dispute",
  "customer_purchase_ip": null,
  "disputed_at": "2016-09-18T20:38:51",
  "submitted_count": 0,
  "reason": "unrecognized",
  "reversal_total": 2000,
  "reversal_currency": "usd",
  "address_zip": null,
  "submitted_at": null,
  "created": "2016-09-18T20:38:51",
  "url": "/v1/disputes/dp_123",
  "fields": {},
  "charged_at": "2016-09-18T20:38:51",
  "products": [],
  "past_payments": [],
  "correspondence": [],
  "reference_url": null,
  "amount": 500,
  "processor": "stripe",
  "account": "default"
}

You can retrieve a single dispute by its id.

Updating a dispute

Definition:

PUT /v1/disputes/{{dispute_id}}
chargehound.Disputes.update();
chargehound.Disputes.update()
Chargehound::Disputes.update
ch.Disputes.Update(*chargehound.UpdateDisputeParams)
chargehound.disputes.update();

Example request:

curl -X PUT https://api.chargehound.com/v1/disputes/dp_123 \
  -u test_123: \
  -d template=unrecognized \
  -d fields[customer_name]="Susie Chargeback" 
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.update('dp_123', {
  template: 'unrecognized',
  fields: {
    customer_name: 'Susie Chargeback'
  }
}, function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.update('dp_123',
  template='unrecognized',
  fields={
    'customer_name': 'Susie Chargeback'
  }
)
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.update('dp_123',
  template: 'unrecognized',
  fields: {
    'customer_name' => 'Susie Chargeback'
  }
)
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.UpdateDisputeParams{
  ID:       "dp_123",
  Template: "unrecognized",
  Fields: map[string]interface{}{
    "customer_name": "Susie Chargeback",
  },
}

dispute, err := ch.Disputes.Update(&params)
import com.chargehound.Chargehound;
import com.chargehound.models.Dispute;

Chargehound chargehound = new Chargehound("test_123");

Map<String, Object> fields = new HashMap<String, Object>();
fields.put("customer_name", "Susie Chargeback");

chargehound.disputes.update("dp_123",
  new Dispute.UpdateParams.Builder()
    .template("unrecognized")
    .fields(fields)
    .finish()
);

Example response:

{
  "customer": "cus_123",
  "livemode": false,
  "updated": "2016-10-18T20:38:51",
  "currency": "usd",
  "missing_fields": {},
  "address_zip_check": "pass",
  "closed_at": null,
  "id": "dp_123",
  "customer_name": "Susie Chargeback",
  "fee": 1500,
  "reversal_amount": 500,
  "due_by": "2016-11-18T20:38:51",
  "state": "needs_response",
  "statement_descriptor": "COMPANY",
  "source": "stripe",
  "charge": "ch_123",
  "template": "unrecognized",
  "is_charge_refundable": false,
  "cvc_check": "unavailable",
  "customer_email": "susie@example.com",
  "account_id": null,
  "address_line1_check": "pass",
  "object": "dispute",
  "customer_purchase_ip": null,
  "disputed_at": "2016-09-18T20:38:51",
  "submitted_count": 0,
  "reason": "unrecognized",
  "reversal_total": 2000,
  "reversal_currency": "usd",
  "address_zip": null,
  "submitted_at": null,
  "created": "2016-09-18T20:38:51",
  "url": "/v1/disputes/dp_123",
  "fields": {
    "customer_name": "Susie Chargeback"
  },
  "charged_at": "2016-09-18T20:38:51",
  "products": [],
  "past_payments": [],
  "correspondence": [],
  "reference_url": null,
  "amount": 500,
  "processor": "stripe",
  "account": "default"
}

You can update the template and the fields on a dispute.

Parameters

Parameter Type Required? Description
template string optional The id of the template to use.
fields dictionary optional Key value pairs to hydrate the template's evidence fields.
products array optional List of products the customer purchased. (See Product data for details.)
correspondence array optional A list of communications with the customer. (See Customer correspondence for details.)
past_payments array optional History of the customer's valid, non-disputed transactions using the same card. (See Past payments for details.)
reference_url string optional Custom URL with dispute information, such as the dispute or charge in your company dashboard.
submit boolean optional Submit dispute evidence immediately after update. If the submit fails, updated fields will still be saved.
queue boolean optional Queue the dispute for submission. (See Queuing for submission for details.)
force boolean optional Submit a dispute in manual review (see Manual review for details) or submit an accepted dispute (see Accepting a dispute for details.)

Possible errors

Error code Description
400 Bad Request Dispute has no template, or missing fields required by the template.

Queuing for submission

Queuing a dispute for submission allows you to stage evidence that will be automatically submitted at a later time. Typically a payment processor only allows a dispute response to be submitted once, making it impossible to edit the response. Queuing a dispute for submission allows you to make changes to the dispute's response while being confident that the dispute will be submitted on time.

You can queue a dispute by setting the queue parameter to true when making a request to submit or create a dispute. The dispute will be in the queued state if the request was successful.

Accepting a dispute

Definition:

POST /v1/disputes/{{dispute_id}}/accept
chargehound.Disputes.accept();
chargehound.Disputes.accept()
Chargehound::Disputes.accept
ch.Disputes.Accept(*chargehound.AcceptDisputeParams)
chargehound.disputes.accept();

Example request:

curl -X POST https://api.chargehound.com/v1/disputes/dp_123/accept \
  -u test_123:
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.accept('dp_123', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.accept('dp_123')
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.accept('dp_123')
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.AcceptDisputeParams{
  ID:       "dp_123"
}

dispute, err := ch.Disputes.Accept(&params)
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("test_123");

chargehound.disputes.accept("dp_123");

Example response:

{
  "customer": "cus_123",
  "livemode": false,
  "updated": "2016-10-18T20:38:51",
  "currency": "usd",
  "missing_fields": {},
  "address_zip_check": "pass",
  "closed_at": null,
  "id": "dp_123",
  "customer_name": "Susie Chargeback",
  "fee": 1500,
  "reversal_amount": 500,
  "due_by": "2016-11-18T20:38:51",
  "state": "accepted",
  "statement_descriptor": "COMPANY",
  "source": "stripe",
  "charge": "ch_123",
  "template": "unrecognized",
  "is_charge_refundable": false,
  "cvc_check": "unavailable",
  "customer_email": "susie@example.com",
  "account_id": null,
  "address_line1_check": "pass",
  "object": "dispute",
  "customer_purchase_ip": null,
  "disputed_at": "2016-09-18T20:38:51",
  "submitted_count": 0,
  "reason": "unrecognized",
  "reversal_total": 2000,
  "reversal_currency": "usd",
  "address_zip": null,
  "submitted_at": "2016-10-18T20:38:51",
  "created": "2016-09-18T20:38:51",
  "url": "/v1/disputes/dp_123",
  "fields": {},
  "charged_at": "2016-09-18T20:38:51",
  "products": [],
  "past_payments": [],
  "correspondence": [],
  "reference_url": null,
  "amount": 500,
  "processor": "stripe",
  "account": "default"
}

If you do not wish to respond to a dispute you can accept the dispute. Accepting a dispute will remove the dispute from your queue of disputes that need response.

The dispute will be in the accepted state if the request was successful.

In order submit a dispute that has been accepted via the API, you will need to pass an extra force parameter or the dispute will stay in the accepted state.

You can tell a dispute has been accepted if when you submit it you receive a 202 status and the state does not change to submitted.

Product data

If a customer purchased multiple products in a disputed order, those products can be individually attached to a dispute when updating or submitting the dispute. Each product has the following properties:

Example usage:

curl -X PUT https://api.chargehound.com/v1/disputes/dp_123 \
  -u test_123: \
  -d products="[{
                   \"name\" : \"Saxophone\",
                   \"description\" : \"Alto saxophone, with carrying case\",
                   \"image\" : \"https://static.chargehound.com/saxophone.png\",
                   \"sku\" : \"17283001272\",
                   \"quantity\" : 1,
                   \"amount\" : 20000,
                   \"url\" : \"http://www.example.com\",
                   \"shipping_carrier\": \"fedex\",
                   \"shipping_tracking_number\": \"657672264372\" 
                },{
                   \"name\" : \"Milk\",
                   \"description\" : \"Semi-skimmed Organic\",
                   \"image\" : \"https://static.chargehound.com/milk.png\",
                   \"sku\" : \"26377382910\",
                   \"quantity\" : \"64oz\",
                   \"amount\" : 400,
                   \"url\" : \"http://www.example.com\",
                   \"shipping_carrier\": \"fedex\",
                   \"shipping_tracking_number\": \"657672264372\" 
                }]"
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.update('dp_123', {
  products: [{
    'name': 'Saxophone',
    'description': 'Alto saxophone, with carrying case',
    'image': 'https://static.chargehound.com/saxophone.png',
    'sku': '17283001272',
    'quantity': 1,
    'amount': 20000,
    'url': 'http://www.example.com',
    'shipping_carrier': 'fedex',
    'shipping_tracking_number': '657672264372' 
  },{
    'name': 'Milk',
    'description': 'Semi-skimmed Organic',
    'image': 'https://static.chargehound.com/milk.png',
    'sku': '26377382910',
    'quantity': '64oz',
    'amount': 400,
    'url': 'http://www.example.com',
    'shipping_carrier': 'fedex',
    'shipping_tracking_number': '657672264372' 
  }]
}, function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.update('dp_123',
  products=[{
     'name': 'Saxophone',
     'description': 'Alto saxophone, with carrying case',
     'image': 'https://static.chargehound.com/saxophone.png',
     'sku': '17283001272',
     'quantity': 1,
     'amount': 20000,
     'url': 'http://www.example.com',
     'shipping_carrier': 'fedex',
     'shipping_tracking_number': '657672264372' 
  }, {
     'name': 'Milk',
     'description': 'Semi-skimmed Organic',
     'image': 'https://static.chargehound.com/milk.png',
     'sku': '26377382910',
     'quantity': '64oz',
     'amount': 400,
     'url': 'http://www.example.com',
     'shipping_carrier': 'fedex',
     'shipping_tracking_number': '657672264372' 
  }]
)
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.update('dp_123',
  products: [{
     'name' => 'Saxophone',
     'description' => 'Alto saxophone, with carrying case',
     'image' => 'https://static.chargehound.com/saxophone.png',
     'sku' => '17283001272',
     'quantity' => 1,
     'amount' => 20000,
     'url' => 'https://www.example.com'
  },{
     'name' => 'Milk',
     'description' => 'Semi-skimmed Organic',
     'image' => 'https://static.chargehound.com/milk.png',
     'sku' => '26377382910',
     'quantity' => '64oz',
     'amount' => 400,
     'url' => 'https://www.example.com'
  }]
)
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.UpdateDisputeParams{
  ID:       "dp_123",
  Products: []chargehound.Product{
    {
      Name:                   "Saxophone",
      Description:            "Alto saxophone, with carrying case",
      Image:                  "http://static.chargehound.com/saxophone.png",
      Sku:                    "17283001272",
      Quantity:               1,
      Amount:                 20000,
      Url:                    "http://www.example.com",
      ShippingCarrier:        "fedex",
      ShippingTrackingNumber: "657672264372",
    },
    {
      Name:                   "Milk",
      Description:            "Semi-skimmed Organic",
      Image:                  "http://static.chargehound.com/milk.png",
      Sku:                    "26377382910",
      Quantity:               "64oz",
      Amount:                 400,
      Url:                    "http://www.example.com",
      ShippingCarrier:        "fedex",
      ShippingTrackingNumber: "657672264372",
    },
  },
}

dispute, err := ch.Disputes.Update(&params)
import com.chargehound.Chargehound;
import com.chargehound.models.Dispute;
import com.chargehound.models.Product;

Chargehound chargehound = new Chargehound("test_123");

Product saxophoneProduct = new Product.Builder()
  .name("Saxophone")
  .description("Alto saxophone, with carrying case")
  .image("http://static.chargehound.com/saxophone.png")
  .sku("17283001272")
  .quantity(1)
  .amount(20000)
  .url("http://www.example.com")
  .shippingCarrier("fedex")
  .shippingTrackingNumber("657672264372")
  .finish();

Product milkProduct = new Product.Builder()
  .name("Milk")
  .description("Semi-skimmed Organic")
  .image("http://static.chargehound.com/milk.png")
  .sku("26377382910")
  .quantity("64oz")
  .amount(400)
  .url("http://www.example.com")
  .shippingCarrier("fedex")
  .shippingTrackingNumber("657672264372")
  .finish();

List<Product> products = new ArrayList<Product>();
products.add(saxophoneProduct);
products.add(milkProduct);

chargehound.disputes.update("dp_123",
  new Dispute.UpdateParams.Builder()
  .products(products)
  .finish()
);

Product data fields

Field Type Required? Description
name string required The name of the product ordered.
quantity string or integer required The number or quantity of this product (e.g. 10 or "64oz").
amount integer required The price paid for this item, in cents (or other minor currency unit).
description string optional A product description - for example, the size or color.
image url optional A URL showing the product image.
sku string optional The stock-keeping unit.
url url optional The URL of the purchased item, if it is listed online.
shipping_carrier string optional Shipping carrier for the shipment for the product.
shipping_tracking_number string optional Shipping tracking number for the shipment for the product.

Customer correspondence

If you have a record of email communication with the customer, you can attach that record to a dispute when updating or submitting the dispute. Each correspondence item has the following properties:

Example usage:

curl -X PUT https://api.chargehound.com/v1/disputes/dp_123 \
  -u test_123: \
  -d correspondence="[{ \
       \"to\": \"customer@example.com\", \
       \"from\": \"noreply@example.com\", \
       \"sent\": \"2019-03-31 09:00:22PM UTC\", \
       \"subject\": \"Your Order\", \
       \"body\": \"Your order was received.\", \
       \"caption\": \"Order confirmation email.\" \
     }, { \
       \"to\": \"customer@example.com\", \
       \"from\": \"noreply@example.com\", \
       \"sent\": \"2019-04-03 08:59:36PM UTC\", \
       \"subject\": \"Your Order\", \
       \"body\": \"Your order was delivered.\", \
       \"caption\": \"Delivery confirmation email.\" \
     }]"
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.update('dp_123', {
  correspondence: [{
    'to': 'customer@example.com',
    'from': 'noreply@example.com',
    'sent': '2019-03-31 09:00:22PM UTC',
    'subject': 'Your Order',
    'body': 'Your order was received.',
    'caption': 'Order confirmation email.'
  }, {
    'to': 'customer@example.com',
    'from': 'noreply@example.com',
    'sent': '2019-04-01 09:00:22PM UTC',
    'subject': 'Your Order',
    'body': 'Your order was delivered.',
    'caption': 'Delivery confirmation email.'
  }]
}, function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.update('dp_123',
  correspondence=[{
    'to': 'customer@example.com',
    'from': 'noreply@example.com',
    'sent': '2019-03-31 09:01:01PM UTC',
    'subject': 'Your Order',
    'body': 'Your order was received.',
    'caption': 'Order confirmation email.'
  }, {
    'to': 'customer@example.com',
    'from': 'noreply@example.com',
    'sent': '2019-04-01 09:01:01PM UTC',
    'subject': 'Your Order',
    'body': 'Your order was delivered.',
    'caption': 'Delivery confirmation email.'
  }]
)
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.update('dp_123',
  correspondence: [{
    'to' => 'customer@example.com',
    'from' => 'noreply@example.com',
    'sent' => '2019-03-31 09:01:26PM UTC',
    'subject' => 'Your Order',
    'body' => 'Your order was received.',
    'caption' => 'Order confirmation email.'
  }, {
    'to' => 'customer@example.com',
    'from' => 'noreply@example.com',
    'sent' => '2019-04-01 09:01:26PM UTC',
    'subject' => 'Your Order',
    'body' => 'Your order was delivered.',
    'caption' => 'Delivery confirmation email.'
  }]
)
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.UpdateDisputeParams{
  ID: "dp_123",
  Correspondence: []chargehound.CorrespondenceItem{
    {
      To: "customer@example.com",
      From: "noreply@example.com",
      Sent: "2019-03-31 09:04:05PM UTC",
      Subject: "Your Order",
      Body: "Your order was received.",
      Caption: "Order confirmation email."
    },
    {
      To: "customer@example.com",
      From: "noreply@example.com",
      Sent: "2019-04-01 09:04:05PM UTC",
      Subject: "Your Order",
      Body: "Your order was delivered.",
      Caption: "Delivery confirmation email."
    },
  },
}

dispute, err := ch.Disputes.Update(&params)
import com.chargehound.Chargehound;
import com.chargehound.models.Dispute;
import com.chargehound.models.Email;

Chargehound chargehound = new Chargehound("test_123");

Email confirmationEmail = new Email.Builder()
  .to("customer@example.com")
  .from("noreply@example.com")
  .sent("2019-03-31 09:04:55PM UTC")
  .subject("Your Order")
  .body("Your order was received.")
  .caption("Order confirmation email.")
  .finish();

Email deliveryEmail = new Email.Builder()
  .to("customer@example.com")
  .from("noreply@example.com")
  .sent("2019-04-01 09:04:55PM UTC")
  .subject("Your Order")
  .body("Your order was delivered.")
  .caption("Delivery confirmation email.")
  .finish();

List<Email> correspondence = new ArrayList<Email>();
correspondence.add(confirmationEmail);
correspondence.add(deliveryEmail);

chargehound.disputes.update("dp_123",
  new Dispute.UpdateParams.Builder()
  .correspondence(correspondence)
  .finish()
);

Correspondence item fields

Field Type Required? Description
to string required The address where the email was sent. E.g. the customer's email address.
from string required The address of the email sender. E.g. your company's support email address.
sent string optional When the email was sent.
subject string required The email subject line.
body string required The email body, as plain text.
caption string optional A description of the email.

Past payments

Showing a history of valid transactions with a customer can serve as evidence that their disputed transaction was also a valid transaction. If you are unable to include past payment details, Chargehound may be able to automatically fetch past payments from your payment processor.

The past payments provided to our API should be successful, non-disputed transactions that used the same credit card as the disputed transaction. The past payment list should not include more than 10 payments. You can update the past payment history when updating or submitting the dispute. Each payment has the following properties:

Example usage:

curl -X PUT https://api.chargehound.com/v1/disputes/dp_123 \
  -u test_123: \
  -d past_payments="[{ \
       \"id\": \"ch_1\", \
       \"amount\": 20000, \
       \"currency\": \"usd\", \
       \"charged_at\": \"2019-09-10 10:18:41PM UTC\", \
       \"device_id\": \"ABCD\", \
       \"item_description\": \"10 saxophones\", \
       \"user_id\": \"chargehound@example.com\", \
       \"ip_address\": \"127.0.0.1\", \
       \"shipping_address\": \"2211 N First Street San Jose, CA 95413\" \
     }, { \
       \"id\": \"ch_2\", \
       \"amount\": 50000, \
       \"currency\": \"usd\", \
       \"charged_at\": \"2019-09-03 10:18:41PM UTC\", \
       \"device_id\": \"ABCD\", \
       \"item_description\": \"1 gallon of semi-skimmed milk\", \
       \"user_id\": \"chargehound@example.com\", \
       \"ip_address\": \"127.0.0.1\", \
       \"shipping_address\": \"2211 N First Street San Jose, CA 95413\" \
     }]"
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.update('dp_123', {
  past_payments: [{
    'id': 'ch_1',
    'amount': 20000,
    'currency': 'usd',
    'charged_at': '2019-09-10 11:09:41PM UTC',
    'device_id': 'ABCD',
    'item_description': '10 saxophones',
    'user_id': 'chargehound@example.com',
    'ip_address': '127.0.0.1',
    'shipping_address': '2211 N First Street San Jose, CA 95413'
  }, {
    'id': 'ch_2',
    'amount': 50000,
    'currency': 'usd',
    'charged_at': '2019-09-03 11:09:41PM UTC',
    'device_id': 'ABCD',
    'item_description': '1 gallon of semi-skimmed milk',
    'user_id': 'chargehound@example.com',
    'ip_address': '127.0.0.1',
    'shipping_address': '2211 N First Street San Jose, CA 95413'
  }]
}, function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.update('dp_123',
  past_payments = [{
    'id': 'ch_1',
    'amount': 20000,
    'currency': 'usd',
    'charged_at': '2019-09-10 11:10:06PM UTC',
    'device_id': 'ABCD',
    'item_description': '10 saxophones',
    'user_id': 'chargehound@example.com',
    'ip_address': '127.0.0.1',
    'shipping_address': '2211 N First Street San Jose, CA 95413'
  }, {
    'id': 'ch_2',
    'amount': 50000,
    'currency': 'usd',
    'charged_at': '2019-09-03 11:10:06PM UTC',
    'device_id': 'ABCD',
    'item_description': '1 gallon of semi-skimmed milk',
    'user_id': 'chargehound@example.com',
    'ip_address': '127.0.0.1',
    'shipping_address': '2211 N First Street San Jose, CA 95413'
  }]
)
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.update('dp_123',
  past_payments: [{
    'id' => 'ch_1',
    'amount' => 20000,
    'currency' => 'usd',
    'charged_at' => '2019-09-10 11:10:14PM UTC',
    'device_id' => 'ABCD',
    'item_description' => '10 saxophones',
    'user_id' => 'chargehound@example.com',
    'ip_address' => '127.0.0.1',
    'shipping_address' => '2211 N First Street San Jose, CA 95413'
  }, {
    'id' => 'ch_2',
    'amount' => 50000,
    'currency' => 'usd',
    'charged_at' => '2019-09-03 11:10:14PM UTC',
    'device_id' => 'ABCD',
    'item_description' => '1 gallon of semi-skimmed milk',
    'user_id' => 'chargehound@example.com',
    'ip_address' => '127.0.0.1',
    'shipping_address' => '2211 N First Street San Jose, CA 95413'
  }]
)
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.UpdateDisputeParams{
  ID:       "dp_123",
  PastPayments: []chargehound.PastPayment{
    {
      ID: "ch_1",
      Amount: 20000,
      Currency: "usd",
      ChargedAt: "2019-09-10 11:10:22PM UTC",
      DeviceId: "ABCD",
      ItemDescription: "10 saxophones",
      UserId: "chargehound@example.com",
      IPAddress: "127.0.0.1",
      ShippingAddress: "2211 N First Street San Jose, CA 95413",  
    },
    {
      ID: "ch_2",
      Amount: 50000,
      Currency: "usd",
      ChargedAt: "2019-09-03 11:10:22PM UTC",
      DeviceId: "ABCD",
      ItemDescription: "1 gallon of semi-skimmed milk",
      UserId: "chargehound@example.com",
      IPAddress: "127.0.0.1",
      ShippingAddress: "2211 N First Street San Jose, CA 95413",
    },
  },
}

dispute, err := ch.Disputes.Update(&params)
import com.chargehound.Chargehound;
import com.chargehound.models.Dispute;
import com.chargehound.models.PastPayment;

Chargehound chargehound = new Chargehound("test_123");

PastPayment firstPayment = new PastPayment.Builder()
  .id("ch_1")
  .amount(20000)
  .currency("usd")
  .chargedAt("2019-09-10 11:10:47PM UTC")
  .deviceId("ABCD")
  .itemDescription("10 saxophones")
  .userId("chargehound@example.com")
  .ipAddress("127.0.0.1")
  .shippingAddress("2211 N First Street San Jose, CA 95413")
  .finish();

PastPayment secondPayment = new PastPayment.Builder()
  .id("ch_2")
  .amount(50000)
  .currency("usd")
  .chargedAt("2019-09-03 11:10:47PM UTC")
  .deviceId("ABCD")
  .itemDescription("1 gallon of semi-skimmed milk")
  .userId("chargehound@example.com")
  .ipAddress("127.0.0.1")
  .shippingAddress("2211 N First Street San Jose, CA 95413")
  .finish();


List<PastPayment> pastPayments = new ArrayList<PastPayment>();
pastPayments.add(firstPayment);
pastPayments.add(secondPayment);

chargehound.disputes.update("dp_123",
  new Dispute.UpdateParams.Builder()
  .pastPayments(pastPayments)
  .finish()
);

Past payment fields

Field Type Required? Description
id string required The ID of the transaction in your payment processor.
amount integer required The amount of the transaction, in cents (or other minor currency unit.)
currency string required A 3 character ISO currency code.
charged_at string or integer required The date of the transaction, as a formatted string or Unix timestamp.
device_id string optional The unique device ID of the buyer
item_description string optional The description or name of the item purchased
user_id string optional The user login or email address of the buyer
ip_address string optional The IP Address of the buyer device
shipping_address string optional The shipping address of the transaction

Manual review

Example usage:

curl -X POST https://api.chargehound.com/v1/disputes/dp_123/submit \
  -u test_123: \
  -d force=true
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.submit('dp_123', {
  force: true
}, function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.submit('dp_123',
  force=True
)
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.submit('dp_123',
  force: true
)
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.UpdateDisputeParams{
  Force: true
}

dispute, err := ch.Disputes.Submit(&params)
import com.chargehound.Chargehound;
import com.chargehound.models.Dispute;

Chargehound chargehound = new Chargehound("test_123");

chargehound.disputes.submit("dp_123",
  new Dispute.UpdateParams.Builder()
    .force(true)
    .finish()
);

You might want to have the chance to look over some disputes before you submit your response to the bank, so we allow you create rules to mark certain disputes for manual review.

In order submit a dispute that has been marked for review via the API, you will need to pass an extra force parameter or the dispute will stay in the manual review queue.

You can tell a dispute has been marked for manual review if when you submit it you receive a 202 status and the state does not change to submitted.

Braintree read only

Example usage:

curl -X POST https://api.chargehound.com/v1/disputes/dp_123/submit \
  -u test_123: \
  -d charge=ch_123
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.submit('dp_123', {
  charge: 'ch_123'
}, function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.submit('dp_123',
  charge='ch_123'
)
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.submit('dp_123',
  charge: 'ch_123'
)
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.UpdateDisputeParams{
  Charge: "ch_123"
}

dispute, err := ch.Disputes.Submit(&params)
import com.chargehound.Chargehound;
import com.chargehound.models.Dispute;

Chargehound chargehound = new Chargehound("test_123");

chargehound.disputes.submit("dp_123",
  new Dispute.UpdateParams.Builder()
    .charge("ch_123")
    .finish()
);

If Chargehound does not have access to the Braintree disputes API, you'll need to create a Braintree user with disputes access and add their credentials to your Chargehound account. Login to Braintree and create a Braintree user here with role permissions that include viewing and editing disputes. Add the credentials for that user on your settings page here.

You will also need to attach the Braintree transaction id using the charge parameter when updating or submitting disputes using the Chargehound API.

You can always reconnect your Braintree account from the settings page here to grant Chargehound access to the disputes API, this will make your integration easier.

Stripe charging directly

Example usage:

curl -X POST https://api.chargehound.com/v1/disputes/dp_123/submit \
  -u test_123: \
  -d account_id=acct_123
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.submit('dp_123', {
  account_id: 'acct_123'
}, function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.submit('dp_123',
  account_id='acct_123'
)
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.submit('dp_123',
  account_id: 'acct_123'
)
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.UpdateDisputeParams{
  AccountID: "acct_123"
}

dispute, err := ch.Disputes.Submit(&params)
import com.chargehound.Chargehound;
import com.chargehound.models.Dispute;

Chargehound chargehound = new Chargehound("test_123");

chargehound.disputes.submit("dp_123",
  new Dispute.UpdateParams.Builder()
    .accountId("acct_123")
    .finish()
);

In order to work with Stripe Managed or Connected account integrations that charge directly, you will need to attach the Stripe account id to the dispute using the account_id parameter. When you receive a webhook to your Connect webhook endpoint, get the account from the event. The account_id is the Stripe account id that you will need to set.

Integration Guide

This section walks through some of the technical details of completing a Chargehound integration.

Getting started

Before you can use the Chargehound API, you will need your API keys. Your API keys can be found on the settings page in the "View API keys" section.

In order to submit a dispute you will also need to specify the template to use. Templates are referenced by an ID. You can see a list of your organization's templates and their IDs on the templates page.

Linking data

// Use the charge ID to look up payment data.
var charge = dispute.charge
// Order ID may help find payment data.
var order = dispute.fields['order_id']
# Use the charge ID to look up payment data.
charge = dispute.charge
# Order ID may help find payment data.
order = dispute.fields['order_id']
# Use the charge ID to look up payment data.
charge = dispute.charge
# Order ID may help find payment data.
order = dispute.fields['order_id']
// Use the charge ID to look up payment data.
charge := dispute.charge
// Order ID may help find payment data.
order := dispute.fields["order_id"]
// Use the charge ID to look up payment data.
String charge = dispute.charge;
// Order ID may help find payment data.
String order = dispute.fields.get("order");

The first step in responding to a dispute with Chargehound is linking the dispute to key data in your system. The exact details of this vary by payment processor and company. Here are the most common IDs you will use to link data:

Collecting evidence

You will need to collect specific evidence in order to submit a dispute. The fields hash on a dispute represents this evidence. The exact fields depend on your template. To understand the data you will need to collect, go to the templates page and click "View details" to see customized documentation for a template.

On the template page, click the "Fields" tab to see the overall list of fields for the template. Required fields are needed to submit a response with the template. Optional fields represent additional information that is good to have, but not necessary. You should set a value for as many of the optional fields as possible, but they are not required to submit a response.

Click on the template's "Integration" tab to see an example of how to update the fields and submit the dispute using Chargehound's API. Chargehound will fill some of the evidence fields automatically, but it is unlikely that we can get all the evidence we need without your help. The "Collecting Evidence" tool helps you check what fields you will need to collect.

Formatting fields

You will encounter a few different types of fields. To view the types of your fields, use the "Fields" tab of the template page described above. Currently Chargehound templates can have text, date, number, amount url, and email fields, and each type is validated differently. Here's a breakdown of what Chargehound expects for each type:

Field Type Validation
text string Multi-line strings are ok, but be sensitive to your template layout.
date string or integer Submitted responses will be reviewed by humans so try to format dates to be human readable and friendly, although no specific format is enforced. You can also provide a Unix timestamp, which will be formatted by Chargehound.
number integer A number should be an integer, not a float.
amount integer An amount should be an integer that represents the cents (or other minor currency unit) value. E.g. $1 is 100.
url string A URL should be a fully qualified URL including the scheme (http:// or https://).
email string An email should be a valid email address.

Once you have all your evidence properly formatted, use the submit endpoint to submit a dispute. The submit endpoint adds the template and evidence fields to a dispute just like the update endpoint, and it also submits the evidence to be reviewed. If you get a 400 response code or ChargehoundBadRequestError after a submit or update it is probably because one of the evidence fields is not properly formatted. When you get a 201 response code the dispute was successfully submitted and you are done.

Metadata and custom fields

Chargehound tries to automatically collect standard information from your payment processor when a dispute is created. You can also define a list of custom fields and metadata fields that you would like to automatically collect on the processors tab of your team settings page here. These fields will be automatically copied to the evidence fields of your disputes when they are created in Chargehound.

For example, if you add an "order_id" to your Stripe Charges with metadata fields, you could easily access that ID in the fields of the disputes created in Chargehound. You could use the ID to find more relevant evidence data in your system, and/or use the ID in your templates.

Stripe metadata

If you connected a Stripe account, Chargehound can automatically collect data from your Charge, Customer, or Subscription metadata fields.

Braintree custom fields

If you connected a Braintree account, Chargehound can automaticaly collect data from your Transaction or Customer custom fields. Your Braintree custom fields should be "Store-and-pass-back" fields, and the field name given to Chargehound should be the API name.

Workflow rules and automation

Chargehound has a number of workflow automation rules that can act on a dispute using its data. You can view those here. Instead of coding all of the logic to decide what to do with a dispute, it often makes more sense to send as much data as possible for a dispute, and then a dashboard user can manage the rules to automate the workflow. For example, instead of setting a template on each of your submit API calls, you can use the Template Select workflow rules in the dashboard. By using the rules, you can avoid writing and maintaining code when you need to make changes to your workflow or add a new template.

Queue settings

When you submit a dispute, you can set the queue flag to true so that the dispute is not submitted immediately. This gives your team time to review the evidence while being assured that every dispute will be addressed. You can configure when queued disputes will be submitted on the workflow tab of your team settings page here. Queued disputes will always be submitted before the due date.

Handling webhooks

In order to automatically submit responses whenever you get a dispute, you will need to set up a webhook handler and handle the dispute.created webhook notification.

Testing webhooks

You can create a test mode webhook in the Chargehound dashboard on the webhooks & API tab of your team settings page here. The webhook will only send notifications for disputes created in the Chargehound test mode. For testing locally, we recommend using a tool like ultrahook to forward the webhooks to a development machine. Once you have tested, remember to configure a live mode webhook.

Using a job queue

You do not need to immediately POST your evidence to the submit endpoint when you receive a dispute created event. This is a good time to use a job queue if you have one. Simply pass the dispute id and (if you need it) the charge id to the job. The task worker can then query your database for the needed evidence and POST the submit to Chargehound when it's ready.

Testing with generated disputes

It's possible to create disputes with randomly generated data in test mode. You can update and submit these disputes as normal, and you will be able to view the generated response. This is a good way to become familiar with Chargehound's API and dashboard.

You can create a dispute from the Chargehound dashboard when in test mode by clicking the "Create a Test Dispute" button: Chargehound test dashboard or simply visiting the create dispute page.

Testing with Stripe

1) Create a token for a card with the dispute trigger code.

curl https://api.stripe.com/v1/tokens \
  -u {{your_stripe_test_key}}: \
  -d card[number]=4000000000000259 \
  -d card[exp_month]=12 \
  -d card[exp_year]=2020 \
  -d card[cvc]=123
var stripe = require('stripe')(
  '{{your_stripe_test_key}}'
);

stripe.tokens.create({
  card: {
    number: '4000000000000259',
    exp_month: 12,
    exp_year: 2020,
    cvc: '123'
  }
}, function (err, token) {
  // ...
});
import stripe
stripe.api_key = '{{your_stripe_test_key}}'

stripe.Token.create(
  card={
    "number": "4000000000000259",
    "exp_month": 12,
    "exp_year": 2020,
    "cvc": "123"
  },
)
require 'stripe'
Stripe.api_key = '{{your_stripe_test_key}}'

Stripe::Token.create(
  :card => {
    :number => '4000000000000259',
    :exp_month => 4,
    :exp_year => 2020,
    :cvc => '314'
  },
)
stripe.Key = "{{your_stripe_test_key}}"

t, err := token.New(&stripe.TokenParams{
  Card: &stripe.CardParams{
        Number: "4000000000000259",
        Month:  "12",
        Year:   "2020",
        CVC:    "123",
    },
})
Stripe.apiKey = "{{your_stripe_test_key}}";

Map<String, Object> tokenParams = new HashMap<String, Object>();
Map<String, Object> cardParams = new HashMap<String, Object>();
cardParams.put("number", "4000000000000259");
cardParams.put("exp_month", 12);
cardParams.put("exp_year", 2020);
cardParams.put("cvc", "123");
tokenParams.put("card", cardParams);

Token.create(tokenParams);

2) Attach that token to a Stripe customer, for easy reuse later.

curl https://api.stripe.com/v1/customers \
  -u {{your_stripe_test_key}}: \
  -d description="Always disputes charges" \
  -d source={{token_from_step_1}}
var stripe = require('stripe')(
  '{{your_stripe_test_key}}'
);

stripe.customers.create({
  description: 'Always disputes charges',
  source: '{{token_from_step_1}}'
}, function (err, customer) {
  // ...
});
import stripe
stripe.api_key = '{{your_stripe_test_key}}'

stripe.Customer.create(
  description="Always disputes charges",
  source="{{token_from_step_1}}"
)
require 'stripe'
Stripe.api_key = '{{your_stripe_test_key}}'

Stripe::Customer.create(
  :description => 'Always disputes charges',
  :source => '{{token_from_step_1}}'
)
stripe.Key = "{{your_stripe_test_key}}"

customerParams := &stripe.CustomerParams{
  Desc: "Always disputes charges",
}
customerParams.SetSource("{{token_from_step_1}}")
c, err := customer.New(customerParams)
Stripe.apiKey = "{{your_stripe_test_key}}";

Map<String, Object> customerParams = new HashMap<String, Object>();
customerParams.put("description", "Always disputes charges");
customerParams.put("source", "{{token_from_step_1}}");

Customer.create(customerParams);

3) Create a charge that will trigger a dispute. You can view the resulting dispute in the Stripe dashboard.

curl https://api.stripe.com/v1/charges \
  -u {{your_stripe_test_key}}: \
  -d amount=701 \
  -d currency=usd \
  -d customer={{customer_from_step_2}} \
  -d description="Triggering a dispute"
var stripe = require('stripe')(
  '{{your_stripe_test_key}}'
);

stripe.charges.create({
  amount: 400,
  currency: 'usd',
  source: '{{customer_from_step_2}}', // obtained with Stripe.js
  description: 'Charge for test@example.com'
}, function (err, charge) {
  // ...
});
import stripe
stripe.api_key = '{{your_stripe_test_key}}'

stripe.Charge.create(
  amount=400,
  currency="usd",
  customer="{{customer_from_step_2}}",
  description="Triggering a dispute"
)
require 'stripe'
Stripe.api_key = '{{your_stripe_test_key}}'

Stripe::Charge.create(
  :amount => 701,
  :currency => 'usd',
  :customer => '{{customer_from_step_2}}',
  :description => 'Triggering a dispute'
)
stripe.Key = "{{your_stripe_test_key}}"

chargeParams := &stripe.ChargeParams{
  Amount: 400,
  Currency: "usd",
  Desc: "Triggering a dispute",
}
chargeParams.SetSource("{{customer_from_step_2}}")
ch, err := charge.New(chargeParams)
Stripe.apiKey = "{{your_stripe_test_key}}";

Map<String, Object> chargeParams = new HashMap<String, Object>();
chargeParams.put("amount", 400);
chargeParams.put("currency", "usd");
chargeParams.put("description", "Triggering a dispute");
chargeParams.put("source", "{{customer_from_step_2}}");

Charge.create(chargeParams);

4) Once the dispute is created in Stripe, you will see it mirrored in Chargehound.

curl https://api.chargehound.com/v1/disputes/{{dispute_from_step_3}} \
  -u {{your_chargehound_test_key}}:
var chargehound = require('chargehound')('{{your_chargehound_test_key}}');

chargehound.Disputes.retrieve('{{dispute_from_step_3}}', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = '{{your_chargehound_test_key}}'

chargehound.Disputes.retrieve('{{dispute_from_step_3}}')
require 'chargehound'
Chargehound.api_key = '{{your_chargehound_test_key}}'

Chargehound::Disputes.retrieve('{{dispute_from_step_3}}')
ch := chargehound.New("{{your_chargehound_test_key}}", nil)

params := chargehound.RetrieveDisputeParams{
  ID: "{{dispute_from_step_3}}",
}

dispute, err := ch.Disputes.Retrieve(&params)
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("{{your_chargehound_test_key}}");

chargehound.disputes.retrieve("{{dispute_from_step_3}}");

5) Using your test API key, you can then update and submit the dispute.

curl https://api.chargehound.com/v1/disputes/{{dispute_from_step_3}}/submit \
  -u {{your_chargehound_test_key}}:
var chargehound = require('chargehound')('{{your_chargehound_test_key}}');

chargehound.Disputes.submit('{{dispute_from_step_3}}', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = '{{your_chargehound_test_key}}'

chargehound.Disputes.submit('{{dispute_from_step_3}}')
require 'chargehound'
Chargehound.api_key = '{{your_chargehound_test_key}}'

Chargehound::Disputes.submit('{{dispute_from_step_3}}')
ch := chargehound.New("{{your_chargehound_test_key}}", nil)

params := chargehound.UpdateDisputeParams{
  ID: "{{dispute_from_step_3}}",
}

_, err := ch.Disputes.Submit(&params)
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("{{your_chargehound_test_key}}");

chargehound.disputes.submit("{{dispute_from_step_3}}");

Because Chargehound creates live mode disputes with webhooks from Stripe, testing end to end requires creating a dispute in Stripe. You can do this by creating a charge with a test card that simulates a dispute. If you have a test environment, you can create a charge there to simulate a dispute end to end in your system. You can also create a charge with a simple curl request, or via the Stripe dashboard.

Testing with Braintree

1) Create a transaction that will trigger a dispute. You can view the resulting dispute in the Braintree dashboard on the disputes page.

gateway.transaction.sale({
  amount: "10.00",
  creditCard: {
    'number': '4023898493988028',
    'expiration_date': '05/2020',
    'cvv': '222'
  },
  options: {
    submitForSettlement: true
  }
}, function (err, result) {
  if (result.success) {
    // See result.transaction for details
  } else {
    // Handle errors
  }
})
braintree.Transaction.sale({
  'amount': '10.00',
  'credit_card': {
      'number': '4023898493988028',
      'expiration_date': '05/2020',
      'cvv': '222'
  },
  'options': {
    'submit_for_settlement': True
  }
})
gateway.transaction.sale(
  :amount => '10.00',
  :credit_card => {
    :number => '4023898493988028',
    :expiration_date => '05/2020',
    :cvv => '222'
  },
  :options => {
    :submit_for_settlement => true
  }
)
TransactionRequest request = new TransactionRequest()
  .amount(new BigDecimal("10.00"))
  .creditCard()
    .number("4023898493988028")
    .expirationDate("05/2020")
    .cvv("222")
  .options()
    .submitForSettlement(true)
    .done();

Result<Transaction> result = gateway.transaction().sale(request);

2) Once the dispute is created in Braintree, you will see it mirrored in Chargehound.

var chargehound = require('chargehound')('{{your_chargehound_test_key}}');

chargehound.Disputes.retrieve('{{dispute_from_step_1}}', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = '{{your_chargehound_test_key}}'

chargehound.Disputes.retrieve('{{dispute_from_step_1}}')
require 'chargehound'
Chargehound.api_key = '{{your_chargehound_test_key}}'

Chargehound::Disputes.retrieve('{{dispute_from_step_1}}')
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("{{your_chargehound_test_key}}");

chargehound.disputes.retrieve("{{dispute_from_step_1}}");

3) Using your test API key, you can then update and submit the dispute.

var chargehound = require('chargehound')('{{your_chargehound_test_key}}');

chargehound.Disputes.submit('{{dispute_from_step_1}}', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = '{{your_chargehound_test_key}}'

chargehound.Disputes.submit('{{dispute_from_step_1}}')
require 'chargehound'
Chargehound.api_key = '{{your_chargehound_test_key}}'

Chargehound::Disputes.submit('{{dispute_from_step_1}}')
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("{{your_chargehound_test_key}}");

chargehound.disputes.submit("{{dispute_from_step_1}}");

If you have a Braintree sandbox, you can test your integration using Chargehound's test mode and Braintree's sandbox environment. First, you'll need to connect your Braintree sandbox to Chargehound, just as you did for your production Braintree environment. You can connect a Braintree sandbox account from the settings page here.

Because Chargehound creates live mode disputes with webhooks from Braintree, testing end to end requires creating a dispute in Braintree. You can do this by creating a transaction with a test card number that triggers a dispute. If you have a test environment, you can create a transaction there to simulate a dispute end to end in your system. You can also create a transaction using one of the Braintree SDKs, or via the Braintree dashboard.

Testing with PayPal

1) Use the Orders API to charge a test buyer account from the sandbox PayPal account that you connected to Chargehound.

curl https://api.sandbox.paypal.com/v2/checkout/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{your_paypal_access_key}}" \
-d '{
  "payer": {
    "email_address": "{{your_buyer_account_email_address}}"
  },
  "intent": "CAPTURE",
  "purchase_units": [
    {
      "amount": {
        "currency_code": "USD",
        "value": "100.00"
      }
    }
  ]
}'

2) As the Paypal buyer account, approve the payment using the link returned in the response from step 1. It is the "approve" link and should look like https://www.sandbox.paypal.com/checkoutnow?token={{token}}.

3) Using your Paypal facilitator API key, capture the payment.

curl-X POST https://api.sandbox.paypal.com/v2/checkout/orders/{{order_id_from_step_1}}/capture \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{your_paypal_access_key}}"

4) As the Paypal buyer account, find the transaction in your activity. Click "Report a problem". Click "I want to report unauthorized activity". Fill out any details, it's not important what they are. You can skip the change password step. You can view the resulting dispute in the resolution center.

5) You can fetch the dispute in Chargehound using the Paypal ID. Remember, it takes on average 3-5 hours for the dispute to appear in Chargehound.

curl https://api.chargehound.com/v1/disputes/{{dispute_from_step_4}} \
  -u {{your_chargehound_test_key}}:
var chargehound = require('chargehound')('{{your_chargehound_test_key}}');

chargehound.Disputes.retrieve('{{dispute_from_step_4}}', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = '{{your_chargehound_test_key}}'

chargehound.Disputes.retrieve('{{dispute_from_step_4}}')
require 'chargehound'
Chargehound.api_key = '{{your_chargehound_test_key}}'

Chargehound::Disputes.retrieve('{{dispute_from_step_4}}')
ch := chargehound.New("{{your_chargehound_test_key}}", nil)

params := chargehound.RetrieveDisputeParams{
  ID: "{{dispute_from_step_4}}",
}

dispute, err := ch.Disputes.Retrieve(&params)
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("{{your_chargehound_test_key}}");

chargehound.disputes.retrieve("{{dispute_from_step_4}}");

6) Using your test API key, you can then update and submit the dispute.

curl https://api.chargehound.com/v1/disputes/{{dispute_from_step_4}}/submit \
  -u {{your_chargehound_test_key}}:
var chargehound = require('chargehound')('{{your_chargehound_test_key}}');

chargehound.Disputes.submit('{{dispute_from_step_4}}', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = '{{your_chargehound_test_key}}'

chargehound.Disputes.submit('{{dispute_from_step_4}}')
require 'chargehound'
Chargehound.api_key = '{{your_chargehound_test_key}}'

Chargehound::Disputes.submit('{{dispute_from_step_4}}')
ch := chargehound.New("{{your_chargehound_test_key}}", nil)

params := chargehound.UpdateDisputeParams{
  ID: "{{dispute_from_step_4}}",
}

_, err := ch.Disputes.Submit(&params)
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("{{your_chargehound_test_key}}");

chargehound.disputes.submit("{{dispute_from_step_4}}");

If you have a Paypal sandbox, you can test your integration using Chargehound's test mode and Paypal's sandbox environment. First, you'll need to connect your Paypal sandbox to Chargehound, just as you did for your production Paypal environment. You can connect a Paypal sandbox account from the settings page here.

Testing end to end requires creating a dispute in Paypal. You can do this by creating a transaction from a sandbox PayPal buyer account and disputing the transaction. Be sure to follow the steps given here exactly. It is important that you choose the correct reason for filing a dispute. You want to create a Chargeback in Paypal. Some dispute reasons will create Paypal Inquiries rather than Chargebacks.

Be prepared to wait after creating the dispute in Paypal. Unfortunately, Chargehound cannot sync Paypal disputes in real time. Transaction data is not immediately available to us in the Paypal API we use. After a dispute is created in Paypal, you will have to wait between 3-5 hours before it is available in Chargehound. When testing with Paypal's sandbox, it can take even longer.

Testing with Checkout

1) Create a payment with a dispute trigger.

2) Once the dispute is created in Checkout, you will see it mirrored in Chargehound.

curl https://api.chargehound.com/v1/disputes/{{dispute_from_step_1}} \
  -u {{your_chargehound_test_key}}:
var chargehound = require('chargehound')('{{your_chargehound_test_key}}');

chargehound.Disputes.retrieve('{{dispute_from_step_1}}', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = '{{your_chargehound_test_key}}'

chargehound.Disputes.retrieve('{{dispute_from_step_1}}')
require 'chargehound'
Chargehound.api_key = '{{your_chargehound_test_key}}'

Chargehound::Disputes.retrieve('{{dispute_from_step_1}}')
ch := chargehound.New("{{your_chargehound_test_key}}", nil)

params := chargehound.RetrieveDisputeParams{
  ID: "{{dispute_from_step_1}}",
}

dispute, err := ch.Disputes.Retrieve(&params)
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("{{your_chargehound_test_key}}");

chargehound.disputes.retrieve("{{dispute_from_step_1}}");

3) Using your test API key, you can then update and submit the dispute.

curl https://api.chargehound.com/v1/disputes/{{dispute_from_step_1}}/submit \
  -u {{your_chargehound_test_key}}:
var chargehound = require('chargehound')('{{your_chargehound_test_key}}');

chargehound.Disputes.submit('{{dispute_from_step_1}}', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = '{{your_chargehound_test_key}}'

chargehound.Disputes.submit('{{dispute_from_step_1}}')
require 'chargehound'
Chargehound.api_key = '{{your_chargehound_test_key}}'

Chargehound::Disputes.submit('{{dispute_from_step_1}}')
ch := chargehound.New("{{your_chargehound_test_key}}", nil)

params := chargehound.UpdateDisputeParams{
  ID: "{{dispute_from_step_1}}",
}

_, err := ch.Disputes.Submit(&params)
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("{{your_chargehound_test_key}}");

chargehound.disputes.submit("{{dispute_from_step_1}}");

Because Chargehound creates live mode disputes with webhooks from Checkout, testing end to end requires creating a dispute in Checkout. You can do this by creating a charge with a test card that simulates a dispute. If you have a test environment, you can create a charge there to simulate a dispute end to end in your system. You can also create a charge with the Checkout API or from the Checkout dashboard.

Responding to your backlog

Before integrating with Chargehound you might have accrued a dispute backlog, but you can easily respond to all of those disputes by writing a simple script and running it as the final integration step.

curl https://api.chargehound.com/v1/disputes?state=warning_needs_response&state=needs_response \
  -u test_123
var chargehound = require('chargehound')(
  'test_123'
);

async function respondToBacklog (startingAfterId=null) {
  var params = {
    state: ['warning_needs_response', 'needs_response']
  };

  // Use the dispute ID to page.
  if (startingAfterId) {
    params['starting_after'] = startingAfterId;
  }

  var res = await chargehound.Disputes.list(params);

  await Promise.all(res.data.map(async function (dispute) {
    // Submit the dispute.
  });

  if (res.has_more) {
    // Recurse to address all of the open disputes.
    var startingAfterId = res.data[res.data.length - 1].id;
    await respondToBacklog(startingAfterId);
  }
}
import chargehound
chargehound.api_key = 'test_123'

def respond_to_backlog(starting_after_id=None):
  params = {
    'state': ['warning_needs_response', 'needs_response']
  }

  # Use the dispute ID to page.
  if starting_after_id:
    params['starting_after'] = starting_after_id

  res = chargehound.Disputes.list(**params)

  for dispute in res['data']:
    # Submit the dispute.

  if res['has_more']:
    # Recurse to address all of the open disputes.
    starting_after_id = res['data'][-1]['id']
    respond_to_backlog(starting_after_id)
require 'chargehound'
Chargehound.api_key = 'test_123'

def respond_to_backlog(starting_after_id)
  params = {
    state: %w[needs_response warning_needs_response]
  }

  # Use the dispute ID to page.
  if starting_after_id
    params['starting_after'] = starting_after_id
  end

  res = Chargehound::Disputes.list(params)
  res['data'].each { |dispute|
    # Submit the dispute.
  }

  if res['has_more']
    # Recurse to address all of the open disputes.
    starting_after_id = res['data'][-1]['id']
    respond_to_backlog(starting_after_id)
  end
end
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

func respondToBacklog (startingAfterId string) {
  params := chargehound.ListDisputesParams{
    State: []string{"warning_needs_response", "needs_response"},
    StartingAfter: startingAfterId
  }

  response, err := ch.Disputes.List(&params)

  for _, dispute := range response.Data {
    // Submit the dispute.
  }

  if response.HasMore == true {
    // Recurse to address all of the open disputes.
    nextStartingAfterId := response.Data[len(response.Data)-1].ID
    respondToBacklog(nextStartingAfterId)
  }
}
import com.chargehound.Chargehound;
import com.chargehound.models.DisputesList;
import com.chargehound.models.Dispute;

Chargehound chargehound = new Chargehound("test_123");

public void respondToBacklog(String startingAfterId) {
  DisputesList.Params.Builder paramsBuilder = new DisputesList.Params.Builder()
    .state("warning_needs_response", "needs_response");

  // Use the dispute ID to page.
  if (startingAfterId != null) {
    paramsBuilder = paramsBuilder.startingAfter(startingAfterId);
  }

  DisputesList.Params params = paramsBuilder.finish();

  DisputesList result = chargehound.Disputes.list(params);

  for (int i = 0; i < result.data.length; i++) {
    Dispute dispute = result.data[i]
    // Submit the dispute.
  }

  if (result.hasMore) {
    // Recurse to address all of the open disputes.
    String nextStartingAfterId = result.data[result.data.length - 1].id;
    respondToBacklog(nextStartingAfterId)
  }
}

Webhooks

Webhooks let you register a URL that Chargehound will notify when an event occurs. You might want to use webhooks to be notified when a dispute is created so that you can automatically submit a response. You can configure your webhook URLs on your settings page, clicking Add webhook URL on that page reveals a form to add a new URL for receiving webhooks. You can select what events you would like to receive a notification for. The events are dispute.created, dispute.updated, dispute.submitted, dispute.closed and dispute.response.generated.

Static IP addresses

If you need to allowlist individual IP addresses in your firewall you can opt to have webhook calls sent from a fixed range of IP addresses on your settings page.

Webhook calls will then be sent from one of the following IP addresses if you opt to use a static IP:

3.211.115.112
3.212.160.248
3.212.186.185
34.194.118.97
34.200.90.111

Responding to a webhook

To acknowledge successful receipt of a webhook, your endpoint should return a 2xx HTTP status code. Any other information returned in the request headers or request body is ignored. All response codes outside this range, including 3xx codes, will be treated as a failure. If a webhook is not successfully received for any reason, Chargehound will continue trying to send the webhook once every half hour for up to 3 days.

Test webhook

A test webhook can be triggered from your settings page when adding or editing a webhook. The test webhook is intended to help you verify your webhook URL, test webhooks will only be sent when you trigger them. The test webhook "type" will always be "test", "livemode" will match the mode of the webhook, and the ID will be randomly generated.

Example request:

{
  "id": "wh_123",
  "type": "test",
  "object": "webhook",
  "livemode": true
}

The test webhook object is:

Field Type Description
id string A unique identifier for the webhook request.
type string The event type.
livemode boolean Is this a test or live mode webhook.

Dispute created

Notification that Chargehound has received a new dispute from your payment processor.

Example request:

{
  "id": "wh_123",
  "type": "dispute.created",
  "object": "webhook",
  "livemode": true,
  "dispute": "dp_123"
}

The webhook object is:

Field Type Description
id string A unique identifier for the webhook request.
type string The event type.
livemode boolean Is this a test or live mode dispute.
dispute string The id of the dispute.

Dispute updated

Notification that a dispute has been updated or edited in Chargehound.

Example request:

{
  "id": "wh_123",
  "type": "dispute.updated",
  "object": "webhook",
  "livemode": true,
  "dispute": "dp_123"
}

The webhook object is:

Field Type Description
id string A unique identifier for the webhook request.
type string The event type.
livemode boolean Is this a test or live mode dispute.
dispute string The id of the dispute.

Dispute submitted

Notification that a dispute has been submitted by Chargehound.

Example request:

{
  "id": "wh_123",
  "type": "dispute.submitted",
  "object": "webhook",
  "livemode": true,
  "dispute": "dp_123"
}

The webhook object is:

Field Type Description
id string A unique identifier for the webhook request.
type string The event type.
livemode boolean Is this a test or live mode dispute.
dispute string The id of the dispute.

Dispute closed

Notification that a dispute was closed (won, lost, charge_refunded, or warning_closed).

Example request:

{
  "id": "wh_123",
  "type": "dispute.closed",
  "object": "webhook",
  "livemode": true,
  "dispute": "dp_123"
}

The webhook object is:

Field Type Description
id string A unique identifier for the webhook request.
type string The event type.
livemode boolean Is this a test or live mode dispute.
dispute string The id of the dispute.

Dispute response ready

Notification that Chargehound has generated a response for a dispute. This event is typically used for standalone integrations, where you are responsible for uploading the response evidence document yourself.

Example request:

{
  "id": "wh_123",
  "type": "dispute.response.generated",
  "object": "webhook",
  "livemode": true,
  "dispute": "dp_123",
  "charge": "ch_123",
  "account_id": null,
  "evidence": {
    "customer_name": "Susie Chargeback"
  },
  "response_url": "https://chargehound.s3.amazonaws.com/XXX.pdf?Signature=XXX&Expires=XXX&AWSAccessKeyId=XXX"
}

The webhook object is:

Field Type Description
id string A unique identifier for the webhook request.
type string The event type.
livemode boolean Is this a test or live mode dispute.
dispute string The id of the dispute.
charge string The id of the disputed charge.
response_url string The URL of the generated response PDF. This URL is a temporary access URL.
evidence dictionary Key value pairs for the dispute response evidence object.
account_id string The account id for Connected accounts that are charged directly through Stripe (if any). (See Stripe charging directly for details.)

Standalone Integration

In typical connected integrations Chargehound has third party access to your payment processor. This allows Chargehound to automatically sync your disputes as they are created, update your disputes with relevant information, and upload the response to your payment processor after you submit a dispute. A connected integration is the least effort for you, however, in some cases a connected integration may not be possible or desired.

A standalone integration gives you the responsibilty and control over creating disputes in Chargehound and uploading the generated response to your payment processor when it is ready. You will create a dispute via API and when the response is ready you will receive a dispute.response.generated webhook notification from Chargehound. You can then fetch the response information, including the PDF document generated from your template, and upload the response to your payment processor.

Creating a dispute via API

In a standalone integration, you will need to create a dispute in Chargehound when you receive a notification from your payment processor.

Definition:

POST /v1/disputes
chargehound.Disputes.create();
chargehound.Disputes.create()
Chargehound::Disputes.create
ch.Disputes.Create(*chargehound.CreateDisputeParams)
chargehound.disputes.create();

Example request:

curl -X POST https://api.chargehound.com/v1/disputes?submit=true \
  -u test_123: \
  -d template=unrecognized \
  -d fields[customer_name]="Susie Chargeback" \
  -d id=dp_123 \
  -d charge=ch_123 \
  -d customer=cus_123 \
  -d processor=stripe \
  -d reason=unrecognized \
  -d charged_at="2016-10-01T22:20:53" \
  -d disputed_at="2016-10-01T22:20:53" \
  -d due_by="2016-12-01T22:20:53" \
  -d currency=usd \
  -d amount=500 \
  -d reversal_currency=usd \
  -d fee=1500 \
  -d reversal_amount=500
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.create({
  template: 'unrecognized',
  fields: {
    customer_name: 'Susie Chargeback'
  },
  id: 'dp_123',
  charge: 'ch_123',
  customer: 'cus_123',
  processor: 'stripe',
  reason: 'unrecognized',
  charged_at: '2016-10-01T22:20:53',
  disputed_at: '2016-10-01T22:20:53',
  due_by: '2016-12-01T22:20:53',
  currency: 'usd',
  amount: 500,
  reversal_currency: 'usd',
  fee: 1500,
  reversal_amount: 500
}, function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.create(
  template = 'unrecognized',
  fields = {
    customer_name: 'Susie Chargeback'
  },
  id = 'dp_123',
  charge = 'ch_123',
  customer = 'cus_123',
  processor = 'stripe',
  reason = 'unrecognized',
  charged_at = '2016-10-01T22 =20 =53',
  disputed_at = '2016-10-01T22 =20 =53',
  due_by = '2016-12-01T22 =20 =53',
  currency = 'usd',
  amount = 500,
  reversal_currency = 'usd',
  fee = 1500,
  reversal_amount = 500
)
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.create(
  template: 'unrecognized',
  fields: {
    customer_name => 'Susie Chargeback'
  },
  id: 'dp_123',
  charge: 'ch_123',
  customer: 'cus_123',
  processor: 'stripe',
  reason: 'unrecognized',
  charged_at: '2016-10-01T22:20:53',
  disputed_at: '2016-10-01T22:20:53',
  due_by: '2016-12-01T22:20:53',
  currency: 'usd',
  amount: 500,
  reversal_currency: 'usd',
  fee: 1500,
  reversal_amount: 500
)
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.CreateDisputeParams{
  Template: "unrecognized",
  Fields: map[string]interface{}{
    "customer_name": "Susie Chargeback",
  },
  ID: "dp_123",
  Charge: "ch_123",
  Customer: "cus_123",
  Processor: "stripe",
  Reason: "unrecognized",
  ChargedAt: "2016-10-01T22:20:53",
  DisputedAt: "2016-10-01T22:20:53",
  DueBy: "2016-12-01T22:20:53",
  Currency: "usd",
  Amount: 500,
  ReversalCurrency: "usd",
  Fee: 1500,
  ReversalAmount: 500,
}

dispute, err := ch.Disputes.Create(&params)
import com.chargehound.Chargehound;
import com.chargehound.models.Dispute;

Chargehound chargehound = new Chargehound("test_123");

Map<String, Object> fields = new HashMap<String, Object>();
fields.put("customer_name", "Susie Chargeback");

chargehound.disputes.create(
  new Dispute.CreateParams.Builder()
    .template("unrecognized")
    .fields(fields)
    .id("dp_123")
    .charge("ch_123")
    .customer("cus_123")
    .processor("stripe")
    .reason("general")
    .chargedAt("2016-10-01T22:20:53")
    .disputedAt("2016-10-01T22:20:53")
    .dueBy("2016-12-01T22:20:53")
    .currency("usd")
    .amount(500)
    .reversalCurrency("usd")
    .fee(1500)
    .reversalAmount(500)
    .finish()
);

Example response:

{
  "customer": "cus_123",
  "livemode": false,
  "currency": "usd",
  "missing_fields": {},
  "address_zip_check": "pass",
  "id": "dp_123",
  "customer_name": "Susie Chargeback",
  "fee": 1500,
  "reversal_amount": 500,
  "due_by": "2016-12-01T22:20:53",
  "state": "needs_response",
  "statement_descriptor": null,
  "source": "api",
  "charge": "ch_123",
  "reference_url": null,
  "template": "unrecognized",
  "is_charge_refundable": false,
  "cvc_check": "unavailable",
  "customer_email": null,
  "account_id": null,
  "address_line1_check": "pass",
  "object": "dispute",
  "customer_purchase_ip": null,
  "disputed_at": "2016-10-01T22:20:53",
  "submitted_count": 0,
  "reason": "unrecognized",
  "reversal_total": 2000,
  "charged_at": "2016-10-01T22:20:53",
  "reversal_currency": "usd",
  "address_zip": null,
  "url": "/v1/disputes/dp_123",
  "fields": {
    "customer_name": "Susie Chargeback"
  },
  "amount": 500,
  "products": [],
  "processor": "stripe"
}

Parameters

Parameter Type Required? Description
id string required The id of the dispute in your payment processor.
charge string required The id of the disputed charge in your payment processor.
customer string optional The id of the charged customer in your payment processor.
reason string required The bank provided reason for the dispute. One of general, fraudulent, duplicate, subscription_canceled, product_unacceptable, product_not_received, unrecognized, credit_not_processed, incorrect_account_details, insufficient_funds, bank_cannot_process, debit_not_authorized, goods_services_returned_or_refused, goods_services_cancelled, transaction_amount_differs, retrieved.
charged_at string required ISO 8601 timestamp - when the charge was made.
disputed_at string required ISO 8601 timestamp - when the charge was disputed.
due_by string required ISO 8601 timestamp - when dispute evidence needs to be disputed by.
currency string required The currency code of the disputed charge. e.g. 'USD'.
amount integer required The amount of the disputed charge. Amounts are in cents (or other minor currency unit.)
processor string optional The payment processor for the charge. One of braintree, vantiv, adyen, worldpay or stripe.
state string optional The state of the dispute. One of needs_response, warning_needs_response.
reversal_currency string optional The currency code of the dispute balance withdrawal. e.g. 'USD'.
fee integer optional The amount of the dispute fee. Amounts are in cents (or other minor currency unit.)
reversal_amount integer optional The amount of the dispute balance withdrawal (without fee). Amounts are in cents (or other minor currency unit.)
reversal_total integer optional The total amount of the dispute balance withdrawal (with fee). Amounts are in cents (or other minor currency unit.)
is_charge_refundable boolean optional Is the disputed charge refundable.
submitted_count integer optional How many times has dispute evidence been submitted.
address_line1_check string optional State of address check (if available). One of pass, fail, unavailable, unchecked.
address_zip_check string optional State of address zip check (if available). One of pass, fail, unavailable, unchecked.
cvc_check string optional State of cvc check (if available). One of pass, fail, unavailable, unchecked.
template string optional The id of the template to use.
fields dictionary optional Key value pairs to hydrate the template's evidence fields.
products array optional List of products the customer purchased. (See Product data for details.)
correspondence array optional A list of communications with the customer. (See Customer correspondence for details.)
past_payments array optional History of the customer's valid, non-disputed transactions using the same card. (See Past payments for details.)
reference_url string optional Custom URL with dispute information, such as the dispute or charge in your company dashboard.
account_id string optional Set the account id for Connected accounts that are charged directly through Stripe. (See Stripe charging directly for details.)
kind string optional Type of dispute (if available). One of chargeback, retrieval, pre_arbitration.
submit boolean optional Submit dispute evidence immediately after creation.
queue boolean optional Queue the dispute for submission on its due date. (See Queuing for submission for details.)
force boolean optional Skip the manual review filters or submit a dispute in manual review. (See Manual review for details.)

Possible errors

Error code Description
400 Bad Request Dispute is missing data, or is missing fields required by the template.

Retrieving a dispute response

Once the response is generated, you can fetch the response data from the Chargehound API.

Definition:

GET /v1/disputes/{{dispute_id}}/response
chargehound.Disputes.response();
chargehound.Disputes.response()
Chargehound::Disputes.response
ch.Disputes.Response(*chargehound.RetrieveDisputeParams)
chargehound.disputes.response();

Example request:

curl https://api.chargehound.com/v1/disputes/dp_123/response \
  -u test_123:
var chargehound = require('chargehound')(
  'test_123'
);

chargehound.Disputes.response('dp_123', function (err, res) {
  // ...
});
import chargehound
chargehound.api_key = 'test_123'

chargehound.Disputes.response('dp_123')
require 'chargehound'
Chargehound.api_key = 'test_123'

Chargehound::Disputes.response('dp_123')
import (
  "github.com/chargehound/chargehound-go"
)

ch := chargehound.New("test_123", nil)

params := chargehound.RetrieveDisputeParams{
  ID: "dp_123",
}

response, err := ch.Disputes.Response(&params)
import com.chargehound.Chargehound;

Chargehound chargehound = new Chargehound("test_123");

chargehound.disputes.response("dp_123");

Example response:

{
  "object": "response",
  "livemode": true,
  "dispute": "dp_123",
  "external_identifier": "ch_123",
  "account_id": null,
  "evidence": {
    "customer_name": "Susie Chargeback"
  },
  "response_url": "https://chargehound.s3.amazonaws.com/XXX.pdf?Signature=XXX&Expires=XXX&AWSAccessKeyId=XXX"
}

The response object is:

Field Type Description
dispute string The id of the dispute.
charge string The id of the disputed charge.
response_url string The URL of the generated response PDF. This URL is a temporary access URL.
evidence dictionary Key value pairs for the dispute response evidence object.
account_id string The account id for Connected accounts that are charged directly through Stripe (if any). (See Stripe charging directly for details.)

Braintree Direct

In typical integrations with Chargehound you supply evidence and respond to disputes using the Chargehound API; however, in some cases supporting another third party integration may not be possible or desired.

With a Braintree Direct integration you supply evidence and respond to disputes with Chargehound, but you do so using the Braintree API.

There are 3 simple steps to a Braintree Direct integration:

1) When a dispute is created in Braintree, you'll handle Braintree's "Dispute Opened" webhook notification.

2) You'll collect the evidence needed by your Chargehound template(s).

3) You'll send the evidence fields to the Braintree API. You'll do this by updating the custom fields of the disputed transaction in Braintree. Chargehound will take it from there.

Setting up webhooks

You'll need to handle Braintree's "Dispute Opened" webhook notification. You can configure your Braintree webhooks in your Braintree dashboard. If you haven't defined any webhooks yet, follow the instructions for how to create a webhook here.

Setting up custom fields

You'll need to define the evidence fields used in your template(s) as Braintree custom fields. Follow the instructions for how to create custom fields here. The custom fields will need to be "Store and Pass Back" fields.

In addition to your template evidence fields, you'll need to define a few custom fields that will be used to take actions in Chargehound.

chargehound_template This field can be used to set the template used by Chargehound. Set this field to a template ID.

chargehound_submit Setting this field to "true" will tell Chargehound to submit the dispute.

chargehound_queue Setting this field to "true" will tell Chargehound to queue the dispute for later submission. (See Queuing for submission for details.)

chargehound_force Setting this field to "true" will tell Chargehound to override any manual review rules. (See Manual review for details.)

chargehound_version This field can be used to override the Chargehound API version. (See Versioning for details.)

Updating custom fields

mutation UpdateTransactionCustomFields($input: UpdateTransactionCustomFieldsInput!) {
     updateTransactionCustomFields(input: $input) {
    clientMutationId,
    customFields {
        name
        value
      }
  }
}
{
  "input": {
    "transactionId": "ch_123",
    "clientMutationId": "TEST EXAMPLE",
    "customFields": [
      {
        "name": "chargehound_template",
        "value": "unrecognized"
      },
      {
        "name": "chargehound_submit",
        "value": "true"
      },
      {
        "name": "customer_name",
        "value": "Susie Chargeback"
      }
    ]
  }
}

After you handle the "Dispute Opened" webhook notification, you'll gather the response evidence and update the Braintree custom fields. You'll use Braintree's GraphQL API to update the custom fields of the disputed transaction. If you encounter an error like "Custom field is invalid" you may need to create the custom field, follow the instructions for setting up custom fields here.

Braintree custom fields only support strings, but Chargehound will convert amounts or numbers from strings when needed. See the guidelines for formatting fields here.

Verifying and debugging

While with a Braintree Direct integration you only interact with the Braintree API, you'll still want to check on the disputes in Chargehound to ensure that the evidence fields you are sending are correct and that the response is submitted.

You can easily find the dispute in Chargehound using the same ID used by Braintree. By clicking "View Logs" on the dispute page you will be able to see the updates made to the dispute by the Braintree Direct integration, this can help you spot and debug any issues.

Data Requests

You can use the API to request to retrieve or remove the data in Chargehound for a particular person, identified by name or email.

Retrieve Data

Definition:

POST /v1/personal-data/retrieve

Example request:

curl https://api.chargehound.com/v1/personal-data/retrieve \
  -u test_123: \
  -d email="susie@example.com" \
  -d name="Susie Chargeback" \
  -d notification_email="your_email@example.com"

Example response:

{
  "success": {
    "message": "Data retrieval request submitted."
  },
  "url": "/v1/personal-data/retrieve",
  "livemode": false
}

Retrieve the data in Chargehound for a particular person.

Parameters

Parameter Type Required? Description
email string required The email of the person whose data is to be retrieved.
name string required The name of the person whose data is to be retrieved.
notification_email string required Once the data request is fulfilled, the data will be sent to this email.

Possible errors

Error code Description
400 Bad Request Missing or invalid parameters.

Remove Data

Definition:

POST /v1/personal-data/remove

Example request:

curl https://api.chargehound.com/v1/personal-data/remove \
  -u test_123: \
  -d email="susie@example.com" \
  -d name="Susie Chargeback" \
  -d notification_email="your_email@example.com"

Example response:

{
  "success": {
    "message": "Data removal request submitted."
  },
  "url": "/v1/personal-data/remove",
  "livemode": false
}

Remove the data in Chargehound for a particular person.

Parameters

Parameter Type Required? Description
email string required The email of the person whose data is to be removed.
name string required The name of the person whose data is to be removed.
notification_email string optional Once the data removal is complete, a confirmation can be sent to this email.

Possible errors

Error code Description
400 Bad Request Missing or invalid parameters.