Availability

Galileo's Dispute API is still under development. This guide will continue to change to reflect updated functionality.

This guide explains how to use the <a href="ref:api-reference-about-the-dispute-api" target="_blank">Dispute API</a> endpoints to initiate and submit a dispute. You might want to read these guides along with this one:

  • <a href="doc:about-disputes" target="_blank">**About Disputes**</a> — General explanation of the dispute process from inception to verdict.

  • <a href="doc:disputes-at-galileo" target="_blank">**Disputes at Galileo**</a> — What Galileo offers with its dispute service.

  • <a href="doc:managing-disputes" target="_blank">**Managing Disputes**</a> — Instructions for managing dispute cases after they complete the intake flow.

With Galileo's Dispute API endpoints, you can integrate the dispute process into your mobile app or website to provide account holders with a seamless dispute experience. The account holder's experience might be as simple as this:

  1. Click a "dispute transaction" button or link.

  2. Select one or more transactions to dispute.

  3. Answer a series of questions about the transactions.

  4. Fill out additional documents, if required.

  5. Fill out contact information and submit the dispute.

  6. If later adjustments need to be made to the dispute, such as attaching more documents, edit the dispute.

  7. Track the status of the dispute until completion.

Using the Dispute API endpoints also ensures that disputes are made in compliance with card network requirements and regulations such as Regulation E and Regulation Z. Any updates to the requirements are accounted for on the backend, without disrupting your workflow.

Galileo has developed a conversational API for its disputes function. A "conversational" API is a series of calls that are made in a certain order, with the response from one call providing the data for the next call. By using a conversational API, Galileo makes it possible to tailor the user experience according to the nature of a given dispute and also to conform to regulations governing disputes. For example, if an account holder indicates that a disputed transaction is a duplicate, you can provide follow-up questions that are specific to duplicate charges, whereas an account holder who indicates suspected fraud will get questions that are related to fraud.

## Result of following this procedure

When the full dispute-intake procedure has been successfully completed, a dispute case is entered into the dispute system. The information gathered and submitted for the case conforms to either Reg E or Reg Z, depending on the characteristics of the account and account holder.

## UI requirements

For your mobile app or web site, create a user interface that permits account holders to initiate and submit a dispute case.

  • The case-creation process involves multiple steps that must be performed in the order shown in the numbered steps below.

  • The UI must be flexible enough to display dynamic responses from the endpoints, which are returned depending on the characteristics of the dispute that were indicated in earlier endpoints calls. Some responses from the account holder will trigger further displays, and so on.

  • You should include an interface for uploading files.

## Endpoint workflows

All of the endpoint sequences are on the <a href="doc:dispute-api-workflows" target="_blank">Dispute API Workflows</a> page. Use the links below to get to the specific sequence that you want, according to the type of dispute.

Warning

You **must** call the endpoints in the order shown for each dispute type. Failure to follow the sequence will prevent you from completing the intake flow.

### Fraud

"I did not authorize this transaction. I suspect fraud."

  • <a href="doc:dispute-api-workflows#fraud-workflow" target="_blank">`CardLost`</a> — "I lost my card."

  • <a href="doc:dispute-api-workflows#fraud-workflow" target="_blank">`CardStolen`</a> — "My card was stolen."

  • <a href="doc:dispute-api-workflows#fraud-workflow" target="_blank">`CardNotReceived`</a> — "I did not receive my card."

  • <a href="doc:dispute-api-workflows#fraud-workflow" target="_blank">`CardSecure`</a> — "I didn't make the purchase, but I still have my card."

### NonFraud

"I made this purchase, but there is a problem and I need to dispute it."

  • <a href="doc:dispute-api-workflows#merchant-duplicate" target="_blank">`MerchantDuplicate`</a> — "I was charged more than once."

  • <a href="doc:dispute-api-workflows#merchant-credit-not-issued" target="_blank">`MerchantCreditNotIssued`</a> — _Mastercard only_. "I canceled or returned the merchandise or service and have not received the expected credit."

  • <a href="doc:dispute-api-workflows#other-reasons" target="_blank">`MerchantNotProvided`</a> — "I haven't received merchandise or a service I purchased."

  • <a href="doc:dispute-api-workflows#other-reasons" target="_blank">`MerchantRecurring`</a> — "I have an issue with a recurring transaction on my account."

  • <a href="doc:dispute-api-workflows#other-reasons" target="_blank">`MerchandiseServiceIssue`</a> — "I am dissatisfied with merchandise or a service I received."

  • <a href="doc:dispute-api-workflows#other-reasons" target="_blank">`ChargedCreditedIncorrect`</a> — "I was charged or credited incorrectly."

## Case-creation workflow

This section shows all possible steps as one continuous flow. Be sure that you follow the specific <a href="doc:dispute-api-workflows" target="_blank">endpoint workflow</a> for your use case.

### 1. Initiate the case and obtain the case reason

Initiate the case, obtain the case reason from the account holder, and send it back to Galileo.



<!--dispute-api-swimlanes-1.png.................-->

  1. The account holder initiates a dispute case on your mobile app or website by clicking an "initiate dispute" control.

  2. You call the <a href="ref:dispute_post_createcase" target="_blank">Create Case</a> endpoint with the <<glossary:PRN>>, <<glossary:PAN>>, or <<glossary:CAD>> of the account.

  3. Galileo returns the `caseId`. You pass `caseId` for all subsequent calls for the case.

  4. You call <a href="ref:dispute_post_getcasereasons" target="_blank">Get Case Reasons</a> with the `caseId`.

  5. Galileo returns a JSON containing the case reason types and case reasons. The response varies depending on the account and user type. For example, a consumer debit account might get a different response than a business credit account.

  6. You present the case reasons to the account holder. See [Presenting the case reasons](🔗) for instructions.

  7. The account holder selects the category and reason.

  8. You pass the category and reason back to Galileo in the <a href="ref:dispute_post_addcasereasons" target="_blank">Add Case Reasons</a> call. See [Returning the case reasons](🔗) for more information.

  9. The endpoint returns `status_code: 0`.

#### Presenting the case reasons

Use the response from the Get Case Reasons endpoint to populate a screen that prompts two interactions with the account holder. First, the account holder selects a case reason type (`ClaimReasonType`) and then selects a case reason (`ClaimReason`).

The JSON in the response is structured as `answerList` levels nested inside `questionList` levels. The first level contains the case reason type in the top level, and then when the account holder selects one of the types, you present the corresponding case reasons in the next level down.

<!--Open the Recipe below to see an explanation of the Get Case Reasons response. insert recipe.................-->

This is an example of the first screen to present. The values in parentheses are `identifier` values in the Get Case Reasons response. You may get a different set of fields in the response depending on the account and account holder types.

Which of the following would you like to report? (`ClaimReasonType`)

  • I made this purchase, but there is a problem and I need to dispute it. (`NonFraud`)

  • I did not authorize this transaction. I suspect fraud. (`Fraud`)

    <!-- -->

When the account holder selects a case reason type, present the case reasons that are nested in the corresponding `answerList`. The case reasons should have radio-button controls so that the account holder can select only one case reason. For example, if the account holder selects `NonFraud`, present these options:

Which of the following best describes the reason for your dispute? (`ClaimReason`)

  • I was charged or credited incorrectly. (`ChargedCreditedIncorrect`)

  • I am dissatisfied with the merchandise or a service I received. (`MerchandiseServiceIssue`)

  • I continue to be charged for a recurring transaction after I canceled. (`MerchantRecurring`)

  • I canceled or returned the merchandise or service and have not received the expected credit. (`MerchantCreditNotIssued`)

  • I haven't received merchandise or a service I purchased. (`MerchantNotProvided`)

  • I was charged more than once. (`MerchantDuplicate`)

#### Returning the case reasons

When the account holder selects the case reason type, case reason and other information, pass it back to Galileo by calling the <a href="ref:dispute_post_addcasereasons" target="_blank">Add Case Reasons</a> call. The `questionnaire` parameter accepts a JSON list (`questionList`) that contains `identifier`/`answerValue` pairs: `identifier` contains the `identifier` for the question in the Get Case Reasons response and `answerValue` contains the response that the account holder selected or entered.

At minimum, you will include the `ClaimReasonType` and a `ClaimReason`. These are the valid combinations for the example shown above.

`ClaimReasonType``ClaimReason`
`NonFraud``MerchantDuplicate`<br>`MerchantNotProvided`<br>`MerchantCreditNotIssued`<br>`MerchantRecurring`<br>`MerchandiseServiceIssue`<br>`ChargedCreditedIncorrect`
`Fraud``CardLost`<br>`CardStolen`<br>`CardNotReceived`<br>`CardSecure`

For example, you would populate `questionnaire` like this:



### 2. Select transactions

Present a list of eligible transactions for the account holder to select and pass the transactions back to Galileo.



<!--dispute-api-swimlanes-2.png.................-->

  1. You call <a href="ref:dispute_post_gettransactions" target="_blank">Get Transactions</a> with the `caseId`. You pass start and end dates and optionally the amount and merchant name as filters.

  2. Galileo returns a list of transactions that are eligible for dispute and that fit the filter criteria.

  3. You present the list of transactions to the account holder. The list should have check-box controls to select multiple transactions. See [Transaction entries](🔗) for more information.

  4. You submit the transaction IDs of the selected transaction(s) in the <a href="ref:dispute_post_addtransactions" target="_blank">Add Transactions</a> call. See [Submitting the transactions](🔗) for the restrictions on this call.

  5. The endpoint returns `status_code: 0`.

#### Transaction entries

Each entry that is returned by <a href="ref:dispute_post_gettransactions" target="_blank">Get Transactions</a> contains these metadata fields:

  • `authorizationStatus` — The only valid value is `Posted`.

  • `debitCredit` — Whether the transaction debits or credits the account:

    • `Debit`

    • `Credit`

  • `transactionType` — The type of transaction. Possible values:

    • `ACH` — ACH transaction

    • `ATMWD` — ATM withdrawal

    • `CardPinless` — Card transaction without PIN (signature)

    • `CardPinned` — Card transaction with PIN

    • `P2P` — Peer-to-peer transfer

  • `description` — The description of the transaction

  • `amount` — Transaction amount; unsigned

  • `cardNumberEndingIn` — Last 4 digits of the PAN

  • `date` — Date of the transaction: `YYYYMMDD`

  • `transactionId` — Identifier assigned by the disputes platform

You may need to record each disputed transaction with its metadata so that you can make the correct decision if you are awarding provisional credit. See <a href="doc:about-disputes#provisional-credit" target="_blank">Provisional credit</a> in _About Disputes_ for more information.

#### Submitting the transactions

When submitting the transactions using the <a href="ref:dispute_post_addtransactions" target="_blank">Add Transactions</a> endpoint, you must follow these rules, depending on the `ClaimReasonType` that you submitted with the <a href="ref:dispute_post_addcasereasons" target="_blank">Add Case Reasons</a> call:

  • If `ClaimReasonType` != Fraud, all transactions submitted in an Add Transactions call must be from the same merchant. If the account holder has selected transactions from multiple merchants, send multiple Add Transaction calls with the transactions from the same merchant bundled together.

  • If `ClaimReasonType` = Fraud, the transactions in the same call can be from different merchants.

Every time you call Add Transaction, you create a "dispute." Every case contains one or more disputes. This distinction between a case and a dispute will be important when you receive the event webhooks after you [finalize the case](🔗).

If you send Add Transactions multiple times with different but overlapping values, the last request is honored. For example, if you send transactions 1111 and 2222, and then soon after send 2222 and 3333, transactions 2222 and 3333 are submitted—1111 is not.

### 3. Get follow-up questionnaire answers

According to the `CaseReason` that the account holder returned, present the follow-up questions.



<!--dispute-api-swimlanes-3.png.................-->

  1. You call <a href="ref:dispute_post_getquestionnaire" target="_blank">Get Questionnaire</a> with the `caseId`.

  2. Galileo returns a JSON of the questionnaire.

  3. You present the questionnaire to the account holder, according to the contents of the response. See [Presenting the questionnaire](🔗) for instructions.

  4. The account holder answers the questions.

  5. You pass the answers back to Galileo with the <a href="ref:dispute_post_addquestionnaire" target="_blank">Add Questionnaire</a> call. See [Returning the answers to the questionnaire](🔗) for instructions.

  6. The endpoint returns `status_code: 0`.

#### Presenting the questionnaire

The questions that you receive in the response to Get Questionnaire will vary according to the `CaseReason` that you passed in the <a href="ref:dispute_post_addcasereasons" target="_blank">Add Case Reasons</a> call as well as the network. The response may contain many dozens of lines of JSON formatting.

Note

Every questionnaire is subject to change over time as network requirements change, so you should not cache the questionnaires. Your interface must be able to handle truly dynamic responses.

As with the JSON in the <a href="ref:dispute_post_getcasereasons" target="_blank">Get Case Reasons</a> response, there are `answerList` levels nested inside `questionList` levels. However, instead of only two levels of questions, the number of levels that you will use depends on the answers that the account holder provides in each level.

For example, if you submitted `ClaimReasonType: Fraud` and `ClaimReason: CardSecure` ("I didn't make the purchase, but I still have my card.") in the Add Case Reasons call, the questionnaire that Get Questionnaire returns is called `FraudCardSecure`. See <a href="page:dispute-questionnaire-fraudcardsecure" target="_blank">Dispute Questionnaire: FraudCardSecure</a> for an example response, keeping in mind that this is an example only, and your response may be different.

The next level down is a `questionList` called `EverDoneBusiness` that contains one question:



Nested inside that `questionList` level is the `answerList` with two possible answers, Yes and No, and nested inside the Yes answer are follow-up questions that you display depending on which answer the account holder selects. If the account holder selects **No** then there are no further questions to display for that answer. If the account holder selects **Yes**, then you display the next question:



There are no more questions nested in that level, so you move to the next set of questions, which begins with this one:



If the account holder answers **No**, present the next set of questions, starting with:



As the account holder answers the questions, present any follow-up questions that are nested inside the answers until you reach the end of the node, and then go to the next question in that level. Capture the identifier and the answer for each question answered to return in Add Questionnaire, as described in the next step.

Note

If you returned `ClaimReason: MerchantDuplicate` or `ClaimReason:MerchantCreditNotIssued` in the Add Case Reasons call in Step 1, go to [Calling endpoints in the questionnaire](🔗) for additional instructions.

This is one possible sequence of answers for the `FraudCardSecure` questionnaire. The `identifier` for the question is shown in parentheses:

  • Have you ever done business with any of these disputed merchants? (`EverDoneBusiness`)

    • Yes

    • Is it possible that this is a planned, recurring transaction, such as a monthly or yearly subscription? (`RecognizeDisputedMerchant`)

      • No

        • Do you always have possession of the card? (`CardPossessionInd`)

          • No

            • Where is the card usually kept? (`CardLocation`)

              • "In my purse"

            • In what circumstances do you not have the card in your possession? (`CardNoPossession`)

              • "When I go to the gym"

            • Have you ever authorized another person to use your card? (`HasAuthorizedOthers`)

              • No

            • Have you ever shared your Personal Identification Number (PIN)? (`HasSharedPIN`)

              • No

            • Where do you keep your PIN? (`WherePinKept`)

              • In memory (`InMemory`)

After presenting the main parts of the questionnaire, you display the `postQuestionnaire` questions, which permit the account holder to add information such as comments or to attach further documents.

  • Do you have any additional information to provide about this dispute? (`AddlInfo`)

    • No

#### Returning the answers to the questionnaire

The `questionnaire` parameter in the <a href="ref:dispute_post_addquestionnaire" target="_blank">Add Questionnaire</a> endpoint accepts a JSON list (`questionList`) that contains `identifier`/`answerValue` pairs. `identifier` contains the `identifier` for the question in the Get Questionnaire response and `answerValue` contains the response that the account holder selected or entered.

This example shows what you would return for the questions in the example section, above:



#### Adding `List` answers

When the questionnaire includes an item that has `"DataType":"List"`, you can return two or more items that have the same `identifier` value. For example:



#### Calling endpoints in the questionnaire

Some of the questionnaires include endpoint calls to make depending on how an account holder answers the questions. This type of questionnaire is returned when `ClaimReason` is:

  • `MerchantDuplicate` (I was charged more than once)

  • `MerchantCreditNotIssued` (I canceled or returned the merchandise or service and have not received the expected credit.)

The questions with endpoints are `type: Section` and include `APIDocumentationList`.



<!--

Note

To see code samples and UI mock-ups for calling these endpoints within the questionnaire, see <a href="page:implementing-endpoint-calls-in-the-dispute-questionnaire" target="_blank">Implementing Endpoint Calls in the Dispute Questionnaire</a>.

-->

##### `MerchantDuplicate` sequence


**Question:** "Is the valid transaction on this same account?" (`BothTransactionsOnSameAcctNumberInd`)

  • **Yes** — Call <a href="ref:dispute_post_getsimilartransactions" target="_blank">Get Similar Transactions</a> with search criteria such as amount or merchant name. You can also present a "change search criteria" control.

    • The endpoint returns similar transaction(s), which you can present on the interface with "Please select a valid transaction." (`SelectedValidTransaction`)

    • When the account holder selects the transaction, call <a href="ref:dispute_post_addsimilartransactions" target="_blank">Add Similar Transactions</a> to add the transaction(s) to the case.

  • **No** — Present the question "Is the other transaction on a [your brand] Card?" (`IssuerOrCardholderOtherAcctWithDiff[MC|Visa]CardInd`)

    • **Yes** — Call <a href="ref:dispute_post_getotheraccounts" target="_blank">Get Other Accounts</a>.

    • The endpoint returns other accounts belonging to the account holder.

    • You present the list with "Select the account the charge(s) appear on." (`SelectedValidAccount`)

    • The account holder selects the account.

    • You call Get Similar Transactions using the selected account number for `accountNo`.

    • The endpoint returns the other account's transaction(s), which you present on the interface with "Select the duplicate charge" (`SelectedValidTransaction`).

    • When the account holder selects the valid transaction(s), call Add Similar Transactions to add the transaction(s) to the case.

    • When Galileo returns success, return to the next question in the questionnaire.

    • **No** — Present the question "What was the other form of payment?" (`OtherMeansPaymentForm`)

    • The account holder chooses from among the options: Another [Mastercard | Visa], Other Card, Check, Cash, or Other.

##### `MerchantCreditNotIssued` sequence

**Question**: Were you issued a partial credit? (`IssuedPartialCredit`)

  • **No** — Return to the next question in the questionnaire.

  • **Yes** — Call <a href="ref:dispute_post_getcredittransactions" target="_blank">Get Credit Transactions</a>.

    • The endpoint returns transaction(s) that credit the account, which you can present on the interface with "Please select a valid transaction." (`SelectedValidTransaction`)

    • When the account holder selects the transaction, call <a href="ref:dispute_post_addsimilartransactions" target="_blank">Add Similar Transactions</a> to add the transaction(s) to the case.

### 4. Attach documents

Depending on the case reasons and the transactions selected, the account holder may need to fill out a form.

Note

This step is optional. However, if you call these endpoints (Get Doc Requirements and Add Required Docs), you must call them during the intake flow. You cannot call them after you have submitted the case.



<!--dispute-api-swimlanes-4.pnggggggggggggggggg-->

  1. You call <a href="ref:dispute_post_getdocrequirements" target="_blank">Get Doc Requirements</a>.

  2. Galileo returns one of two options:

    • A message saying that no further documents are required.

    • A base64-encoded PDF (`templateDocumentationStream`) that the account holder must fill out and return. When the account holder has filled out the form, you call <a href="ref:dispute_post_addrequireddocs" target="_blank">Add Required Docs</a> to send the completed form to Galileo.

Note

If the account holder does not fill out and return the required PDF before submitting the case, you can add the PDF form later using <a href="ref:dispute_post_addattachments" target="_blank">Add Attachments</a>. Make sure you keep track of which required documents have not yet been submitted.

### 5. Finalize the case

The account holder reviews the case details, and then clicks "Submit" at the end of the process.



<!--dispute-api-swimlanes-5.pnggggggggggggggggg-->

  1. At the end of the intake flow, you can call <a href="ref:dispute_post_getcasesummary" target="_blank">Get Case Summary</a> to display the case details to the cardholder for review. This endpoint also returns questions for the account holder to fill out regarding contact information, so that the dispute investigators can contact the account holder if needed. If the endpoint returns `CustomerContactOverrideDate`, do not display it to account holders in your interface.

  2. The account holder fills out the questions and clicks a "submit" control to signal that they have finished inputting information for the case.

  3. You call <a href="ref:dispute_post_submitcase" target="_blank">Submit Case</a>. The [Requirements for submission](🔗) must be fulfilled.

    • The `questionnaire` parameter accepts a JSON list (`questionList`) that contains `identifier`/`answerValue` pairs. `identifier` contains the `identifier` for the question in the Get Case Summary response, and `answerValue` contains the response that the account holder selected or entered. Use the same format that you used for [Add Questionnaire](🔗).

  4. Galileo returns success and then sends the following event messages:

    • <a href="ref:api-reference-events-api-case-created" target="_blank">`CSCT: case_created`</a> — The message contains the `case_no` and specifies which disputed `transactionId`s (`dispute_id`s) are included in the case.

    • <a href="ref:api-reference-events-api-dispute-created" target="_blank">`DSCT: dispute_created`</a> — One for each time that you called Add Transactions. The message indicates the `case_no` that the disputed transaction belongs to.

#### Requirements for submission

Before you can call Submit Case, these minimum requirements must be fulfilled:

  1. The case number was created. (Create Case)

  2. The case-reason category and reason were submitted. (Add Case Reasons)

  3. One or more transactions were submitted. (Add Transactions)

  4. The questionnaire answers were submitted. (Add Questionnaire)

Note

If the account holder begins the dispute process but does not complete it, the case that was created remains in the dispute system for eight hours and then times out. If the account holder decides to return to a case that has timed out, you have to start over with Create Case to create a new `caseId`.

## After submitting the dispute

After you have successfully called <a href="ref:dispute_post_submitcase" target="_blank">Submit Case</a>, you can optionally call <a href="ref:dispute_post_getcaseconfirmation" target="_blank">Get Case Confirmation</a> to retrieve a confirmation number and PDF that you can present to the account holder.

Before the verdict arrives, if the account holder wants to add more documents to the case, or if the account holder needs to return the required PDF form, call <a href="ref:dispute_post_addattachments" target="_blank">Add Attachments</a> with the case ID to attach the documents.

  • Supported file types: JPG, JPEG, TIFF, PNG and PDF

  • File size maximum:

    • **Mastercard** — 20 MB

    • **Visa** — 10 MB

For more information on what happens to a dispute case after it is submitted, begin with <a href="doc:disputes-at-galileo#post-intake-processing" target="_blank">Post-intake processing</a> in _Disputes at Galileo_ or consult the <a href="doc:about-disputes#card-transaction-dispute-lifecycle" target="_blank">Card-transaction dispute lifecycle</a> in _About Disputes_.

To manage dispute cases after they have been submitted, go to <a href="doc:managing-disputes" target="_blank">Managing Disputes</a>.