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

# Merchants

> Browse, filter, and retrieve the merchants supported by Henry - with per-method coverage statuses

## Overview

Every product `link` belongs to a merchant `host` (e.g. `nike.com`). The `merchants` resource lets you:

* `merchants.list` - browse all merchants enabled for your application, with filters
* `merchants.retrieve` - fetch a single merchant by host

Each merchant comes with its **per-method coverage statuses** (checkout, checkoutDetails, productDetails, productSearch) - so you can pick the right merchants for your catalog and gate features per capability.

***

## Prerequisites

```typescript theme={null}
import HenrySDK from '@henrylabs/sdk';

const henry = new HenrySDK({
	apiKey: process.env.HENRY_SDK_API_KEY!,
});
```

***

## List merchants

Call `merchants.list` to retrieve all merchants available to your app.

```typescript theme={null}
const { data: merchants } = await henry.merchants.list({
	limit: 40,
});

for (const merchant of merchants) {
	console.log(merchant.name, merchant.host, merchant.coverage.checkout);
	// → "Nike" "nike.com" "supported"
}
```

***

## Retrieve a single merchant

When you already know the `host`, `merchants.retrieve` fetches that merchant directly - no filtering, no pagination.

```typescript theme={null}
const { data: nike } = await henry.merchants.retrieve('nike.com');

console.log(nike.name, nike.coverage.checkout);
// → "Nike" "supported"
```

Returns `404 Not Found` if the host isn't enabled for your app.

***

## Filter merchants

<Steps>
  <Step title="Filter by host">
    Look up a specific merchant by domain:

    ```typescript theme={null}
    const { data } = await henry.merchants.list({
      host: 'nike.com',
    });

    const nike = data[0];
    console.log(nike.name, nike.description);
    console.log(nike.categories);   // ["fashion_and_accessories", "sports_and_outdoor"]
    console.log(nike.website.urls); // [{ value: "https://nike.com", type: "landing" }]
    console.log(nike.logo.urls);    // [{ value: "https://..." }]
    ```

    <Tip>If you already know the host, prefer [`merchants.retrieve`](#retrieve-a-single-merchant) - it's a direct lookup instead of a filtered list.</Tip>
  </Step>

  <Step title="Filter by name">
    Partial-match search on merchant display name:

    ```typescript theme={null}
    const { data } = await henry.merchants.list({
      name: 'nike', // case-insensitive partial match
    });
    ```
  </Step>

  <Step title="Filter by coverage">
    Restrict results to merchants Henry actively supports (vs. still being onboarded), per method:

    ```typescript theme={null}
    // Merchants where checkout purchases are supported
    const { data } = await henry.merchants.list({
      checkoutCoverage: 'supported',
      limit: 100,
    });

    // Filters combine: searchable AND checkout-supported
    const { data: searchable } = await henry.merchants.list({
      productSearchCoverage: 'supported',
      checkoutCoverage: 'supported',
      limit: 100,
    });
    ```

    One filter per method: `checkoutCoverage`, `checkoutDetailsCoverage`, `productDetailsCoverage`, `productSearchCoverage`.

    <Note>`coverageStatus` is a deprecated alias of `checkoutCoverage` and is ignored when `checkoutCoverage` is also provided.</Note>
  </Step>

  <Step title="Filter by category">
    Find all merchants in one or more categories:

    ```typescript theme={null}
    const { data } = await henry.merchants.list({
      categories: ['fashion_and_accessories', 'sports_and_outdoor'],
      limit: 100,
    });

    console.log(data.map(m => m.name));
    // → ["Nike", "Adidas", "New Balance", ...]
    ```
  </Step>
</Steps>

***

## Coverage

Every merchant record includes per-method coverage statuses. Use them to gate features per-merchant and pick the right merchants for each capability.

```typescript theme={null}
const { data: nike } = await henry.merchants.retrieve('nike.com');

// Per-method coverage: "supported" | "testing" | "unsupported"
nike.coverage.checkout;        // checkout purchases
nike.coverage.checkoutDetails; // checkout details (shipping/tax estimates)
nike.coverage.productDetails;  // product detail lookups
nike.coverage.productSearch;   // merchant-scoped product search

// Deprecated alias of coverage.checkout - always the same value
nike.coverageStatus;
```

***

## Filter reference (`merchants.list`)

| Parameter                 | Type       | Default | Description                                                             |
| ------------------------- | ---------- | ------- | ----------------------------------------------------------------------- |
| `limit`                   | `number`   | `20`    | Results per page (1–100)                                                |
| `cursor`                  | `string`   | -       | Pagination cursor from previous response                                |
| `host`                    | `string`   | -       | Exact domain match (e.g. `"nike.com"`)                                  |
| `name`                    | `string`   | -       | Partial name match (e.g. `"nike"`)                                      |
| `checkoutCoverage`        | `string`   | -       | Checkout coverage: `supported`, `testing`, or `unsupported`             |
| `checkoutDetailsCoverage` | `string`   | -       | Checkout-details coverage: `supported`, `testing`, or `unsupported`     |
| `productDetailsCoverage`  | `string`   | -       | Product-details coverage: `supported`, `testing`, or `unsupported`      |
| `productSearchCoverage`   | `string`   | -       | Product-search coverage: `supported`, `testing`, or `unsupported`       |
| `coverageStatus`          | `string`   | -       | **Deprecated.** Alias of `checkoutCoverage`; ignored when both are sent |
| `categories`              | `string[]` | -       | Filter by one or more merchant categories                               |

### Available categories

`automotive`, `baby_and_kids`, `ecommerce`, `electronics_and_gadgets`, `fashion_and_accessories`, `finance`, `food`, `health_and_beauty`, `home_and_living`, `lifestyle_and_entertainment`, `other`, `sports_and_outdoor`, `travel`, `education`

***

## Error handling

| Error              | Cause                                                       |
| ------------------ | ----------------------------------------------------------- |
| `401 Unauthorized` | Invalid API key                                             |
| `400 Bad Request`  | Invalid `limit` or malformed `categories`                   |
| `404 Not Found`    | `merchants.retrieve` called with an unknown / disabled host |
| Empty `data` array | No merchants match the filters (`merchants.list`)           |

***

## Next steps

<CardGroup cols={2}>
  <Card title="Product Discovery" icon="magnifying-glass" href="/v1/sdk/server/guides/product-discovery">
    Search products from a specific merchant using the `merchant` filter
  </Card>

  <Card title="Universal Cart" icon="cart-shopping" href="/v1/sdk/server/guides/universal-cart">
    Add product links from supported merchants to a cart
  </Card>
</CardGroup>
