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

# GET /v1/merchants — list and search merchants

> Retrieve a paginated list of merchants across affiliate networks. Each merchant object includes per-provider links and your standing, canonical records, categories, and more.

The `GET /v1/merchants` endpoint returns a paginated list of merchants from across all affiliate networks. A single brand may appear on multiple rows when it is carried by more than one network — each row represents that merchant through a specific network.

<Warning>
  Five networks require additional credentials before their products will sync: **Adservice**, **Belboon**, **Effiliation**, **Partnerize**, and **The Affiliate Gateway**. Without these credentials, the API returns `422` and products remain unavailable. Configure them under Pools → Sources on the relevant pool.
</Warning>

## Endpoint

```
GET /v1/merchants
```

## Query parameters

<Note>
  **Pass `extended=1` on every request.** Whether the extended fields come back by default depends on your account, so don't assume they will. `extended=1` is what returns `providers`, `canonical`, `categories`, `countries`, `currencies`, `supports`, `supports_deeplinking`, `cookie_duration`, `home_url`, `object_id`, and `slug` — and it's harmless if your account already returns them. If a response is missing `providers` or commissionable links, add the flag.
</Note>

### Base parameters

<ParamField query="extended" type="integer">
  Set to `1` to return the extended merchant object — `providers`, `canonical`, `categories`, `countries`, `currencies`, `supports`, `supports_deeplinking`, `cookie_duration`, `home_url`, `object_id`, and `slug`. Use the integer `1`, not `true`. Some accounts return these fields by default; passing the flag guarantees it. Several filters (`relationship_status`, `credential_id`) require it, and the set of values accepted by `fields` differs between the standard and extended responses.
</ParamField>

<ParamField query="fields" type="string">
  Comma-separated list of fields to include in each merchant object. Omit to return all fields.
</ParamField>

<ParamField query="page" type="integer">
  Page number. Defaults to `1`.
</ParamField>

<ParamField query="per_page" type="integer">
  Results per page. Defaults to `100`.
</ParamField>

<ParamField query="search" type="string">
  Search by merchant name (e.g. `Walmart`) or merchant ID in `nmer_` format (e.g. `nmer_01kmrf...`).
</ParamField>

<ParamField query="network_ids" type="string">
  Comma-separated numeric network IDs to filter results.
</ParamField>

<ParamField query="origin_ids" type="string">
  Comma-separated origin IDs from the source network.
</ParamField>

<ParamField query="type" type="string">
  Record types to filter by (array form, e.g. `type[]=service&type[]=products`). Values: `products`, `service`, `promotions` (alias `coupons`), plus special values `all`, `both`, `none`. A merchant matches if it has **any** of them.
</ParamField>

<ParamField query="country_ids" type="string">
  Comma-separated country codes to filter by.
</ParamField>

<ParamField query="product_count_min" type="integer">
  Return only merchants with at least this many products.
</ParamField>

<ParamField query="product_count_max" type="integer">
  Return only merchants with at most this many products.
</ParamField>

### Filter parameters

<ParamField query="relationship_status" type="string">
  Filter by the workspace's relationship status with the merchant. Values: `approved`, `pending`, `rejected`, `terminated`, `available`, `unavailable`, `unknown`. Requires `extended=1` and a valid API key.
</ParamField>

<Note>
  `relationship_status` reads from **merchant sync** — the process that refreshes your approval records from your connected network credentials. With sync enabled, results reflect an update from within the last 24 hours. Without it, the filter returns an empty set rather than an error.
</Note>

<ParamField query="credential_id" type="string">
  Network credential ULID. When combined with `relationship_status`, restricts the approval lookup to that specific credential. Requires `extended=1`.
</ParamField>

<ParamField query="canonical_ids" type="string">
  Comma-separated canonical merchant IDs (`mer_` ULID format).
</ParamField>

<ParamField query="category_ids" type="string">
  Comma-separated category IDs (`cat_` ULID format).
</ParamField>

<ParamField query="category_name" type="string">
  Filter by category name. Max 255 characters.
</ParamField>

<ParamField query="countries" type="string">
  Comma-separated ISO 3166-1 alpha-2 country codes the merchant operates in.
</ParamField>

<ParamField query="countries_origin" type="string">
  Comma-separated country codes for the merchant's origin country.
</ParamField>

<ParamField query="countries_market" type="string">
  Comma-separated country codes for the merchant's market countries.
</ParamField>

<ParamField query="currencies" type="string">
  Comma-separated ISO 4217 currency codes (3-character).
</ParamField>

<ParamField query="feed_languages" type="string">
  Comma-separated ISO 639-1 language codes (2-character).
</ParamField>

<ParamField query="merchant_types" type="string">
  Comma-separated merchant types. Values: `standard`, `asn`.
</ParamField>

<ParamField query="link_services[shopnomix]" type="string">
  Filter by Shopnomix availability. Values: `direct`, `indirect`, `verified`, `any`, `none`.
</ParamField>

<ParamField query="promotion_count_min" type="integer">
  Return only merchants with at least this many promotions.
</ParamField>

<ParamField query="promotion_count_max" type="integer">
  Return only merchants with at most this many promotions.
</ParamField>

<ParamField query="has_commissionable_url" type="integer">
  Set to `1` to return only merchants that have a commissionable link (a provider with a `url` or `template`).
</ParamField>

## Example request

```bash cURL theme={null}
curl --request GET \
  'https://api.affiliate.com/v1/merchants?extended=1&relationship_status=approved&countries=US&per_page=10' \
  --header 'Authorization: Bearer YOUR_API_KEY'
```

## Response

```json theme={null}
{
  "data": [
    {
      "id": 96521,
      "object_id": "nmer_01khfmzfac2zqmar3mas46gj2g",
      "slug": "nmer_as46gj2g",
      "origin_id": "21291",
      "name": "&Keep",
      "description": "At &Keep, we only have forever in mind - eco-friendly, sustainable, reusable.",
      "domains": ["https://andkeep.com"],
      "home_url": "https://andkeep.com",
      "icon_url": "https://img.affiliate.com/logos/canonical_merchants/01kkkm539pyetxf1f8ab5f8w7n/icon.png",
      "logo_url": "https://img.affiliate.com/logos/canonical_merchants/01kkkm539pyetxf1f8ab5f8w7n/logo.png",
      "product_count": 927,
      "promotion_count": 0,
      "has_content": true,
      "cookie_duration": null,
      "supports_deeplinking": null,
      "categories": [
        {
          "id": "cat_01kkgcmxh2b6me7vfp027sm323",
          "breadcrumb": "Uncategorized",
          "name": "Uncategorized",
          "shopify_id": "na",
          "google_id": null
        }
      ],
      "countries": ["GB"],
      "currencies": ["GBP"],
      "supports": { "products": true, "services": false, "promotions": false },
      "providers": [
        {
          "provider": "network",
          "status": "available",
          "status_changed_at": "2026-03-12T07:21:16+00:00",
          "credential_id": "01kkgc7xxw8gg7y7f6wrnpgepv",
          "url": null,
          "template": "https://www.awin1.com/awclick.php?mid=21291&id={AFF_ID}",
          "outclick": "https://outclick.co/a/2.NetworkOpaqueToken?affiliate_id={AFF_ID}&sub_id={SUB_ID}",
          "supports_deeplinking": null,
          "deeplink": null,
          "approval": null
        },
        {
          "provider": "shopnomix",
          "status": "approved",
          "status_changed_at": "2026-03-18T14:02:55+00:00",
          "credential_id": "01j8z3example000credential",
          "url": "https://r.v2i8b.com/api/v1/bid/redirect?url=https%3A%2F%2Fandkeep.com&campaign_id=01J8Z3K9QW7RT2VN5XB6MC4FDH&source={SUB_ID}",
          "template": "https://r.v2i8b.com/api/v1/bid/redirect?url=https%3A%2F%2Fandkeep.com&campaign_id={AFF_ID}&source={SUB_ID}",
          "outclick": "https://outclick.co/a/2.ShopnomixOpaqueToken?affiliate_id={AFF_ID}&sub_id={SUB_ID}",
          "supports_deeplinking": true,
          "deeplink": {
            "domain": "andkeep.com",
            "template": "https://r.v2i8b.com/api/v1/bid/redirect?url={target_url}&campaign_id=01J8Z3K9QW7RT2VN5XB6MC4FDH&source={SUB_ID}"
          },
          "approval": null
        }
      ],
      "network": {
        "id": 10,
        "slug": "rnet_mm87vz0t",
        "name": "Awin",
        "region": "GB",
        "url": "https://www.awin.com",
        "logo_url": "https://img.affiliate.com/logos/groups/10006/64x64.png",
        "icon_url": "https://img.affiliate.com/logos/groups/10006/64x64.png",
        "canonical_id": "net_01kkgbymywvbf5qjdcdwchxdh2",
        "links": {
          "self": "https://api.affiliate.com/v1/networks/rnet_01kkgbyn1qwj89esa7mm87vz0t",
          "canonical": "https://api.affiliate.com/v1/networks/net_01kkgbymywvbf5qjdcdwchxdh2"
        }
      },
      "canonical": {
        "id": "mer_01kkkm539pyetxf1f8ab5f8w7n",
        "slug": "mer_ab5f8w7n",
        "name": "&Keep",
        "site_url": "https://andkeep.com",
        "logo_url": "https://img.affiliate.com/logos/canonical_merchants/01kkkm539pyetxf1f8ab5f8w7n/logo.png",
        "icon_url": "https://img.affiliate.com/logos/canonical_merchants/01kkkm539pyetxf1f8ab5f8w7n/icon.png",
        "domains": { "andkeep.com": "mer_01kkkm539pyetxf1f8ab5f8w7n" },
        "domain_canonical_id": null,
        "links": {
          "self": "https://api.affiliate.com/v1/merchants/mer_01kkkm539pyetxf1f8ab5f8w7n",
          "domain_canonical": null
        }
      },
      "merchant_types": ["standard"],
      "link_services": { "shopnomix": "indirect" }
    }
  ]
}
```

## Response fields

### `meta` object

<ResponseField name="total" type="integer">Total matching merchants.</ResponseField>
<ResponseField name="from" type="integer">Index of the first result on this page.</ResponseField>
<ResponseField name="to" type="integer">Index of the last result on this page.</ResponseField>
<ResponseField name="current_page" type="integer">Current page number.</ResponseField>
<ResponseField name="last_page" type="integer">Total pages available.</ResponseField>
<ResponseField name="per_page" type="integer">Results per page.</ResponseField>
<ResponseField name="fields" type="array">Fields included in each merchant object.</ResponseField>
<ResponseField name="trace_id" type="string">Request trace ID for support use.</ResponseField>

### Merchant object

<ResponseField name="id" type="integer">
  Numeric merchant ID (legacy). Use `object_id` for new integrations.
</ResponseField>

<ResponseField name="object_id" type="string">
  Unique identifier in `nmer_ULID` format. Represents this merchant on a specific network.
</ResponseField>

<ResponseField name="slug" type="string">
  Short-form identifier (e.g. `nmer_as46gj2g`).
</ResponseField>

<ResponseField name="origin_id" type="string">
  The merchant's ID in the originating network. May be `null`.
</ResponseField>

<ResponseField name="name" type="string">Merchant display name.</ResponseField>
<ResponseField name="description" type="string">Merchant description. May be `null`.</ResponseField>
<ResponseField name="domains" type="array">Canonical domain(s) for the merchant.</ResponseField>

<ResponseField name="home_url" type="string">
  Merchant homepage URL.
</ResponseField>

<ResponseField name="icon_url" type="string">Merchant icon URL.</ResponseField>
<ResponseField name="logo_url" type="string">Merchant logo URL.</ResponseField>
<ResponseField name="product_count" type="integer">Products available from this merchant.</ResponseField>

<ResponseField name="promotion_count" type="integer">
  Promotions available from this merchant.
</ResponseField>

<ResponseField name="has_content" type="boolean">
  Whether the merchant has any associated content.
</ResponseField>

<ResponseField name="cookie_duration" type="string">
  Cookie window as ISO 8601 duration (e.g. `P1M2D`). `null` if not reported.
</ResponseField>

<ResponseField name="supports_deeplinking" type="boolean">
  Whether the merchant supports deep linking. `null` if unknown.
</ResponseField>

<ResponseField name="categories" type="array">
  Product categories. Each item has `id`, `breadcrumb`, `name`, `shopify_id`, `google_id`.
</ResponseField>

<ResponseField name="countries" type="array">
  ISO 3166-1 alpha-2 country codes where this merchant operates.
</ResponseField>

<ResponseField name="currencies" type="array">
  ISO 4217 currency codes supported.
</ResponseField>

<ResponseField name="supports" type="object">
  What the merchant monetizes: `products`, `services`, `promotions` (booleans).
</ResponseField>

<ResponseField name="providers" type="array">
  The ways you can earn commission on this merchant — one entry per network/subnetwork. May be empty. See [Outclick links](#outclick-links) for how the tracked `outclick` link works.

  <Expandable title="provider fields">
    <ResponseField name="provider" type="string">The channel — `network` (the affiliate network the merchant belongs to) or `shopnomix` (the Shopnomix link subnetwork).</ResponseField>
    <ResponseField name="status" type="string">Your standing on this channel: `approved`, `pending`, `rejected`, `terminated`, `available`, `unavailable`, `unknown`, or `null` when you have no approval record.</ResponseField>
    <ResponseField name="status_changed_at" type="string">ISO 8601 timestamp of the last status change.</ResponseField>
    <ResponseField name="credential_id" type="string">Network credential your standing/link is tied to.</ResponseField>
    <ResponseField name="url" type="string">Ready-to-use link built with your credentials — goes **straight to the provider** (not recorded by Affiliate.com). `null` until you're approved.</ResponseField>
    <ResponseField name="template" type="string">Shareable placeholder link (`{AFF_ID}` = affiliate/campaign ID, `{SUB_ID}` = sub-ID). Replace the tokens to build your own link. `null` when there's no shareable form.</ResponseField>
    <ResponseField name="outclick" type="string">A **tracked** link through Affiliate.com's redirector (`outclick.co`). See [Outclick links](#outclick-links). `null` when there's nothing to link.</ResponseField>
    <ResponseField name="supports_deeplinking" type="boolean">Whether this provider can deep-link to any page. `null` if unknown.</ResponseField>
    <ResponseField name="deeplink" type="object">Deep-link builder — `domain` plus a `template` carrying a `{target_url}` token — or `null` if the provider can't deep-link (networks are always `null`).</ResponseField>
    <ResponseField name="approval" type="object">The program's terms as reported by the network (`commission_data`, `epc_data`, `cookie_duration`, `start_date`, `end_date`, `terms_and_conditions`). The `commission_data`/`epc_data` shapes vary by network. Present for `approved` **and** `available` standings (so you can see the offer before applying); `null` when there's no approval record or no terms (Shopnomix is always `null`).</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="network" type="object">
  The affiliate network for this merchant.

  <Expandable title="network fields">
    <ResponseField name="id" type="integer">Numeric network ID.</ResponseField>
    <ResponseField name="slug" type="string">`rnet_` format identifier.</ResponseField>
    <ResponseField name="name" type="string">Network display name.</ResponseField>
    <ResponseField name="region" type="string">ISO 3166-1 alpha-2 region code.</ResponseField>
    <ResponseField name="url" type="string">Network homepage URL.</ResponseField>
    <ResponseField name="logo_url" type="string">Network logo URL.</ResponseField>
    <ResponseField name="icon_url" type="string">Network icon URL.</ResponseField>
    <ResponseField name="canonical_id" type="string">`net_ULID` canonical network ID.</ResponseField>
    <ResponseField name="links" type="object">API links for this network record.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="canonical" type="object">
  The deduplicated canonical merchant record. `null` if none exists.

  <Expandable title="canonical fields">
    <ResponseField name="id" type="string">Canonical merchant ID in `mer_ULID` format.</ResponseField>
    <ResponseField name="slug" type="string">Short-form canonical identifier.</ResponseField>
    <ResponseField name="name" type="string">Canonical merchant name.</ResponseField>
    <ResponseField name="site_url" type="string">Canonical merchant website.</ResponseField>
    <ResponseField name="logo_url" type="string">Canonical logo URL.</ResponseField>
    <ResponseField name="icon_url" type="string">Canonical icon URL.</ResponseField>
    <ResponseField name="domains" type="object">Map of domain strings to their canonical merchant ID.</ResponseField>
    <ResponseField name="links" type="object">API links for this canonical record.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="merchant_types" type="array">
  Merchant classification. Values: `standard`, `asn` (Amazon Seller Network).
</ResponseField>

<ResponseField name="link_services" type="object">
  Third-party services available. Keys are service identifiers; values are `direct`, `indirect`, or `verified`. `null` if none.
</ResponseField>

## Provider link states

For each merchant we work down three options and stop at the first one that yields something:

1. **A link built for you.** Some networks build a link for one named publisher and hand it to us with your ID already in it. No slots left to fill — publish it as-is. This is the common case.
2. **A shared template.** More often for some networks, we hold one link for the merchant that everyone shares, with a slot where the ID goes. You fill `{AFF_ID}` (and optionally `{SUB_ID}`) before publishing, or let the `outclick` fill it at click time.
3. **No link.** The merchant still comes back with its name, logo and everything else we know — just nothing to link with. That's an answer, not a failure: the merchant exists and isn't monetizable by you yet.

<Note>
  **The case that looks like a template but isn't.** Sometimes the link we hold already has a real ID in the slot, and it belongs to someone else. That is not a template, whatever it looks like, and we never pass it on — every click would pay the wrong publisher. Those merchants fall to option 3 and return no link, even though the database plainly holds a URL for them. This is the usual explanation when a merchant you'd expect to be linkable comes back empty.
</Note>

Which lands you in one of three states:

| State             | You see                                                              | How to use it                                                                                                                                                                                                                                                         |
| ----------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Built for you** | `url` populated, `outclick` populated                                | Ready to go. `url` goes straight to the network with your credential **baked in**. The `outclick` has it baked in too — its `?affiliate_id={AFF_ID}&sub_id={SUB_ID}` slots are **optional overrides** (omit them and your credential is used; pass them to override). |
| **Shareable**     | `url: null`, `template` populated (`{AFF_ID}`), `outclick` populated | Linkable, but nothing is built for you yet. Build from `template` (swap `{AFF_ID}`/`{SUB_ID}`), or use `outclick` — here you **must** fill its `?affiliate_id={AFF_ID}&sub_id={SUB_ID}` slots (no credential to fall back on).                                        |
| **Not linkable**  | `url`, `template`, and `outclick` all `null`                         | Nothing to act on for this provider; the entry still names it. `status`/`approval` may still be present (e.g. terms you can read before applying).                                                                                                                    |

**When each field is `null`:**

* **`url`** — no built tracking link. It's populated whenever your approval record carries one (Shopnomix builds it from a resolved campaign id instead). **It is not gated on `status`** — a provider showing `available` or `pending` can still return a usable `url`, and an `approved` one can return `null` if no tracking link was stored. Read `url`, not `status`, to decide whether you have a ready-made link. Note that a populated `url` is not always a *finished* link: Shopnomix bakes in `campaign_id` but leaves `source={SUB_ID}` for you to fill.
* **`template`** — the network stored no shareable placeholder form for this merchant, **or** the only stored link has a real publisher ID baked into it and so can't be shared (see the note above). Shopnomix always has a `template` when the merchant has a home URL. For AdMedia merchants, `template` is also withheld from accounts without the AdMedia grant.
* **`outclick`** — nothing to wrap (`url` **and** `template` both `null`); or the merchant is priced per click (CPC); or the provider's link is built from your own login credentials, which a merchant-level link has nowhere to carry. That last case is **detected per merchant, not taken from a fixed list** — every link is tested before it's offered and quietly dropped if a slot comes back unfilled, since a broken link is worse than no link. Adservice, Belboon and Partnerize commonly land here.

Two account-level switches withhold links everywhere rather than per merchant:

* **Outclick disabled on your account** — every `outclick` on every merchant is withheld until it's switched back on.
* **No team context** — requests that resolve no team (queued exports, for example) mint no outclick links at all.

### Getting from "Shareable" to "Built for you"

A provider stays in the **Shareable** state until two separate things are both true. Missing either one keeps `url` at `null`:

1. **You're connected.** The provider is configured as a source on the pool your request resolves to — **Pools → Sources**. Nothing configured there means no `url`, regardless of anything else.
2. **The network has sent us a working link for this merchant.** Check `url` itself, not `status` — the two don't always move together.

**Shopnomix has no separate approval step.** A Shopnomix source with a campaign ID is sufficient on its own — `url` builds as soon as that's configured.

**Configuration is per pool, so check the right one.** If your request carries a `pool_id`, that pool's own sources are what count — a provider configured on a different pool won't help. Omit `pool_id` and the request resolves to your account's default pool instead, which needs its own configuration. A source configured on one pool never applies to another.

## Outclick links

Each provider carries an `outclick` — a link routed through Affiliate.com's redirector (`outclick.co`) rather than sent straight to the network. When a visitor follows it, Affiliate.com **records the click**, then forwards them to the provider with your credentials, so the click lands in your report. The `url` and `template` links, by contrast, go straight to the network and are **not** recorded by us — both carry your credentials to the same destination; the difference is only whether *we* record the click.

Every `outclick` also carries the merchant's plain home page inside it, so you can request the ordinary uncommissioned link instead of the affiliate one without building anything yourself. AdMedia links are the exception — they're format-locked and always resolve to the AdMedia redirect.

<Note>
  **AdMedia replaces the network entry rather than adding to it.** For a merchant reaching us through AdMedia, the `url`, `template` and `outclick` on the `network` provider are AdMedia's own — there is no separate `admedia` entry in `providers`. Only accounts granted AdMedia access see them; to everyone else the merchant looks like it has no link. Shopnomix, by contrast, runs *alongside* the network provider, so a merchant can carry both.
</Note>

* **Fill the slots.** A shared outclick ends with `?affiliate_id={AFF_ID}&sub_id={SUB_ID}` — replace `{AFF_ID}` with your affiliate/campaign ID and `{SUB_ID}` with your sub-ID.
* **The outclick param is always `affiliate_id` / `sub_id`** — for *every* provider. Affiliate.com's redirector maps them to each provider's native parameter on the way through, so you never use the provider-specific name on an `outclick`. Those names only appear on the direct `url` / `template` links:

  | Link                                    | `{AFF_ID}` goes in            | `{SUB_ID}` goes in   |
  | --------------------------------------- | ----------------------------- | -------------------- |
  | **`outclick`** — every provider         | `affiliate_id`                | `sub_id`             |
  | `template` / `url` — Shopnomix          | `campaign_id`                 | `source`             |
  | `template` / `url` — Awin               | `awinaffid`                   | *(network-specific)* |
  | `template` / `url` — Commission Factory | path segment (`…/{AFF_ID}/…`) | —                    |
* **Merchants-only naming.** These `{AFF_ID}`/`{SUB_ID}` tokens are how the **merchants** response spells the slots. The Products and Promotions endpoints still use `@@@`/`###`, and the merchant's stored `commissionable_url` keeps `@@@` — only the merchants response was renamed.
* **Reporting.** Merchant outclicks appear under the `merchant` offer type: `GET /v1/reports/outclick?offer_type=merchant` (the report defaults to `product`).
* **Deep links are not tracked here.** The `deeplink` builder produces a provider redirect (not an `outclick`), so deep-linked clicks don't appear in the outclick report — only the homepage-level `outclick` does.

## Error responses

| Status | Meaning                                                                                         |
| ------ | ----------------------------------------------------------------------------------------------- |
| `401`  | Missing or invalid API key                                                                      |
| `422`  | Missing network credentials for a network that requires them, or subscription usage cap reached |
| `429`  | Rate limit exceeded — retry after a backoff interval                                            |
| `503`  | API temporarily overloaded — typically recovers within five minutes                             |
