> ## 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.

# Batch merchant matching guide

> Merchant matching is not enabled by default. To request access, please contact us at .

***

## Overview

Batch merchant matching allows you to efficiently match a large volume of merchants to Locations and Counterparties in Spade's Database. You can submit up to `50,000` merchants in a single request and retrieve the matching results once processing is complete. In this guide, we'll use the `/batches/merchants/match` `POST` endpoint to submit a batch of merchants, the `/batches/{batchId}` `GET` endpoint to check the batch status, and the `/batches/{batchId}/results` `GET` endpoint to retrieve the results.

### 1. **Submit Your Batch of Merchants**

<CodeGroup>
  ```bash bash theme={null}
  import requests

  merchants = [
      {
          "requestId": "unique_id_123",
          "merchantName": "Amazon",
          "address": "1234 W 5th Ave",
          "city": "New York",
          "region": "NY",
          "country": "USA",
          "postalCode": "10001",
          "level": "location"
      },
      # ... more merchants ...
  ]

  response = requests.post(
      "https://east.sandbox.spade.com/batches/merchants/match",
      json={"merchants": merchants},
      headers={"X-Api-Key": "<Your API Key Here>"}
  )

  batch_id = response.json()["batchId"]
  print(f"Batch submitted with ID: {batch_id}")
  ```
</CodeGroup>

> **`level` field:** Use `"corporation"` when you want brand-level information (e.g. Costco in general) or `"location"` when you want information about a specific physical location (e.g. one specific Costco location). Defaults to `"location"` if not specified.

### 2. **Receive Completion Notification or Check Status**

You have two options to determine when your batch is complete:

* **Option A: Receive a callback notification (recommended)** Include a `callbackUrl` in your batch submission to receive an automated notification when processing completes.

* **Option B: Poll for status** Periodically check the batch status endpoint.

For detailed implementation of both methods, including callback authentication and handling, refer to the [Batch Enrichment Guide](/reference/batch-enrichment-guide#/). Both batch endpoints use the same callback mechanism.

### 3. **Retrieve the Results**

Once the batch is complete, retrieve the results.

<CodeGroup>
  ```bash bash theme={null}
  response = requests.get(
      f"https://east.sandbox.spade.com/batches/{batch_id}/results",
      headers={"X-Api-Key": "<Your API Key Here>"}
  )

  results = response.json()["matches"]

  for match in results:
      print(f"Request ID: {match['requestId']}")
      print(f"Counterparty Name: {match['counterparty']['name']}")
      print(f"Spade's Counterparty ID: {match['counterparty']['id']}")
      print(f"Merchant Similarity Score: {match['counterparty']['similarity']}")
      print(f"Location Similarity Score: {match['location']['similarity']}")
  ```
</CodeGroup>

## Using the Similarity Scores

We provide two similarity scores for each match; a `counterparty.similarity` and `location.similarity`. The `counterparty.similarity` score is a measure of how similar the merchant name in the request is to the counterparty name in the response. The `location.similarity` score is a measure of how similar the merchant address in the request is to the location address in the response.

The scores are between 75 and 100, where 100 is a perfect match. We recommend experimenting with the threshold for what constitutes a "good" match for your use case.

## Error Handling

There are two classes of errors you will want to handle. The first is the errors you may encounter when submitting the batch via the `/batches/transactions/cards/enrich` endpoint. The second class of errors can be returned as individual payloads in the `results` array of the `/batches/{batchId}/results` endpoint. For example, you may see a 400 in the `statusCode` for a single request in the batch if the request body was missing a required field, while other requests in the batch return a 200 `statusCode`. In the event that a request resulted in an error, the correspond entry in the `results` array will contain an `errors` object. The `errors` object contains an array of objects explaining what caused the error to occur. Here's an example of what the `errors` object could look like:

```
errors:
    {
        'merchantName': ['This field is required.']
    }
```

Note that even in the event of an error, the result will still contain the `merchantId` key. You can use the `merchantId` to determine which payload within your input batch resulted in an error.. See our [enrichment guide](/reference/getting-started#implementation-notes) for more details on handling errors from our API.

## Handling Non-Matches

It's possible that there is either no `counterparty` and/or `location` match for a merchant given the provided input. In these cases, you can still expect a response object in the `matches` array. However, the `counterparty` and `location` will be `null` for the corresponding merchant.

## Best Practices

For best practices regarding unique IDs, status polling, timeouts, and error handling, please refer to the [Batch Enrichment Guide](/reference/batch-enrichment-guide#/).
