> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spade.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error reporting guide

> Report potential enrichment errors and receive updates via callbacks

## Overview

If you believe an enrichment response may be inaccurate, you can submit a report using the [**/transactions/report**](https://docs.spade.com/api-reference/feedback-and-reporting/report-a-card-enrichment-as-incorrect) endpoint. Our team will review your report and determine whether a correction is needed. If a correction is made, we'll send the returned enrichment data to your callback URL so you can update your records automatically.

## Prerequisites

Before submitting error reports, you'll need:

1. **A callback URL** — Provide an HTTPS endpoint to your Spade representative where we can deliver returned enrichments. Contact [support@spade.com](mailto:support@spade.com) to configure this.
2. **A callback token** — Your Spade representative will provide you with a token to validate that incoming callbacks are from Spade. Store this token securely on your server.
3. **An enrichment ID** — The `enrichmentId` from the enrichment response you want to report.

<Warning>
  Your callback token is a shared secret between your system and Spade. Do not expose it in client-side code, public repositories, or logs. Store it in a secure secrets manager with restricted access.
</Warning>

## Submitting an error report

Send a POST request to the `/transactions/report` endpoint with the `enrichmentId` of the enrichment you want to report and a description of what you believe may be inaccurate.

### Request fields

| Field                                | Required | Type    | Description                                                                   |
| :----------------------------------- | :------- | :------ | :---------------------------------------------------------------------------- |
| **enrichmentId**                     | required | string  | The `enrichmentId` from the enrichment response                               |
| **errorDescription**                 | required | string  | A description of the potential issue (max 1024 characters)                    |
| **incorrectCounterparty**            | optional | boolean | Set to `true` if you believe the counterparty information may be inaccurate   |
| **incorrectCounterpartyDescription** | optional | string  | Details about the suspected counterparty issue (max 1024 characters)          |
| **incorrectLocation**                | optional | boolean | Set to `true` if you believe the location information may be inaccurate       |
| **incorrectLocationDescription**     | optional | string  | Details about the suspected location issue (max 1024 characters)              |
| **incorrectCategory**                | optional | boolean | Set to `true` if you believe the category/industry may be inaccurate          |
| **incorrectCategoryDescription**     | optional | string  | Details about the suspected category issue (max 1024 characters)              |
| **incorrectChannel**                 | optional | boolean | Set to `true` if you believe the channel (physical/digital) may be inaccurate |
| **incorrectChannelDescription**      | optional | string  | Details about the suspected channel issue (max 1024 characters)               |

<Tip>
  Setting the optional boolean fields and providing detailed descriptions helps our team investigate your report more efficiently. Be as specific as possible in your descriptions.
</Tip>

### Example request

<CodeGroup>
  ```bash shell theme={null}
  curl --request POST \
  --url https://east.sandbox.spade.com/transactions/report \
  --header 'content-type: application/json' \
  --header 'X-Api-Key: SPADE-API-KEY' \
  --data '{
    "enrichmentId": "050d3a73-c212-4f89-b9c0-0e75da0efeea",
    "errorDescription": "Location returned does not match the physical store location",
    "incorrectLocation": true,
    "incorrectLocationDescription": "Location returned is for Dunlawton Ave, but the actual store is on Taylor Rd"
  }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://east.sandbox.spade.com/transactions/report",
      json={
          "enrichmentId": "050d3a73-c212-4f89-b9c0-0e75da0efeea",
          "errorDescription": "Location returned does not match the physical store location",
          "incorrectLocation": True,
          "incorrectLocationDescription": "Location returned is for Dunlawton Ave, but the actual store is on Taylor Rd",
      },
      headers={"X-Api-Key": "<Your API Key Here>"},
  )

  print(response.json())
  ```
</CodeGroup>

### Example response

A successful report returns an HTTP 200 response:

```json theme={null}
{
  "details": "Enrichment successfully reported."
}
```

If validation fails, you'll receive an HTTP 400 with details about which fields are invalid:

```json theme={null}
{
  "enrichmentId": [
    "Must be a valid UUID."
  ]
}
```

## Receiving returned enrichments

If our team determines that a correction is warranted after reviewing your report, we'll send the returned enrichment data to the callback URL you configured with your Spade representative.

### Callback format

The callback is a POST request to your callback URL containing the returned enrichment response in the same format as the original [card enrichment response](https://docs.spade.com/api-reference/card-enrichment/enrich-a-card-transaction). The request includes an `X-Webhook-Token` header that you should validate against the callback token provided by your Spade representative.

### Validating the callback

You must verify the `X-Webhook-Token` header matches the token provided to you by Spade before processing the returned enrichment. This ensures the callback is genuinely from Spade and has not been tampered with.

<Warning>
  Always validate the `X-Webhook-Token` before processing any callback data. Reject requests with missing or mismatched tokens.
</Warning>

### Example callback handler

<CodeGroup>
  ```bash shell theme={null}
  # Example of what the callback request from Spade looks like:
  # POST https://your-domain.com/spade/corrections
  # Headers:
  #   Content-Type: application/json
  #   X-Webhook-Token: your-callback-token-from-spade
  # Body: returned card enrichment response JSON

  # You can test your callback endpoint with curl:
  curl --request POST \
  --url https://your-domain.com/spade/corrections \
  --header 'content-type: application/json' \
  --header 'X-Webhook-Token: your-callback-token-from-spade' \
  --data '{
    "transactionInfo": {
      "type": "spending",
      "display": {
        "name": "Walmart Neighborhood Market",
        "categoryName": "Grocery Stores"
      }
    },
    "enrichmentId": "050d3a73-c212-4f89-b9c0-0e75da0efeea"
  }'
  ```

  ```python Python theme={null}
  from flask import Flask, request, jsonify

  app = Flask(__name__)

  @app.route('/spade/corrections', methods=['POST'])
  def handle_returned_enrichment():
      # Validate the webhook token
      webhook_token = request.headers.get('X-Webhook-Token')
      expected_token = "your-callback-token-from-spade"  # Store this securely

      if not webhook_token or webhook_token != expected_token:
          return jsonify({"error": "Invalid token"}), 403

      # Process the returned enrichment
      returned_enrichment = request.json
      enrichment_id = returned_enrichment["enrichmentId"]

      # Update your records with the returned data
      update_enrichment_in_database(enrichment_id, returned_enrichment)

      return jsonify({"status": "received"}), 200

  def update_enrichment_in_database(enrichment_id, returned_enrichment):
      # Save the changes to your systems as necessary
      print(f"Saving Enrichment {enrichment_id}: {returned_enrichment}")
  ```
</CodeGroup>

<Info>
  The Python example above uses Flask for illustrative purposes only. You can implement your callback handler using any web framework or language that can receive HTTP POST requests.
</Info>

<Note>
  The returned enrichment callback body uses the same schema as the [card enrichment response](https://docs.spade.com/api-reference/card-enrichment/enrich-a-card-transaction). Refer to the API reference for the full response object documentation.
</Note>

## Workflow summary

1. You enrich a transaction and receive a response with an `enrichmentId`
2. You believe the enrichment may be inaccurate and submit a report to `/transactions/report`
3. Spade's team reviews the report and determines whether a correction is needed
4. If a correction is made, Spade sends the returned enrichment to your callback URL with the `X-Webhook-Token` header
5. Your server validates the token and updates your records

## Error handling

| Status Code | Description                                                              |
| :---------- | :----------------------------------------------------------------------- |
| **200**     | Report submitted successfully                                            |
| **400**     | Validation error — check the response body for details on invalid fields |
| **403**     | Authentication failed — verify your API key                              |
| **500**     | Internal server error — retry the request after a brief delay            |

<Info>
  For questions about error reporting or to set up your callback URL, contact [support@spade.com](mailto:support@spade.com).
</Info>
