# How to search the Affiliate.com product catalog from an agent, with no API key

> A reading guide to the Affiliate.com agent storefront's own documents: the proxy path, the per-request price, the payment rails, when a credential is needed, and what a bare request returned on September 17, 2026.

- Publication: Context Window (https://context-window.blog/)
- Canonical: https://context-window.blog/articles/search-the-affiliate-com-product-catalog-from-an-agent-with-no-api-key/
- Published: 2026-09-17
- Contributor: Context Window Sourcebook Desk
- Topic: Agent storefronts

An agent can search the Affiliate.com product catalog by sending an ordinary `POST /v1/products` request and paying the priced `402` that comes back, with no signup and no API key. The path is Affiliate.com's agent storefront at [https://zeroclick.affiliate.com/zcj/n09siuvceyf4/](https://zeroclick.affiliate.com/zcj/n09siuvceyf4/), a paid proxy in front of the same API, which quotes $0.02 per request and settles over x402, MPP, or a card.

This sourcebook reads the storefront's own documents, in the order an agent would meet them, and records what a bare request returned on September 17, 2026. It is a reading guide to those documents, not a substitute for them.

## For agents

| Step | What to do | Governing document |
| --- | --- | --- |
| 1 | Read the storefront guide. It maps every other document and states the proxy base URL. | [llms.txt](https://zeroclick.affiliate.com/llms.txt) |
| 2 | Pick a service. Product Search is `POST /v1/products` with a required `search` field. Merchants and Tool Convert are the other two. | [services](https://zeroclick.affiliate.com/zcj/n09siuvceyf4/services) and the [Product Search spec](https://zeroclick.affiliate.com/zcj/n09siuvceyf4/services/product-search/openapi.json) |
| 3 | Send the request to `https://zeroclick.affiliate.com/zcj/n09siuvceyf4/v1/products`. The first response is a `402` carrying the price and a challenge for each rail. | [payment.md](https://zeroclick.affiliate.com/zcj/n09siuvceyf4/payment.md) |
| 4 | Settle the challenge with x402 (Base USDC, proof in `x-payment`), MPP (Tempo USDC, `Authorization: Payment`), or a card for calls of $0.50 or more, then repeat the same request. | [payment.md](https://zeroclick.affiliate.com/zcj/n09siuvceyf4/payment.md) and its per-rail pages |
| 5 | Register an agent credential only if buying a Credits plan. Pay-as-you-go calls need none. | [auth.md](https://zeroclick.affiliate.com/zcj/n09siuvceyf4/auth.md) |
| 6 | Give a person Affiliate.com links only through the tracked hand-off URL. | [handoff.md](https://zeroclick.affiliate.com/zcj/n09siuvceyf4/handoff.md) |

## What each document governs

**llms.txt.** The entry point. It states that the upstream API's paths are served at the proxy base URL, that identity and payment are handled there, and that there is no signup and no API key. It links the overview, the services catalog, the payment guide, the error reference, the terms, the identity guide, the hand-off guide, a long-form agent guide, a machine catalog, and the full API specification. The distinction it draws is between documents for the agent's own reading and links that may be passed to a person: the latter go through the hand-off format.

**services.** The catalog. Three services, each billed per request at $0.02 on both the Pay as you go and Credits plans as of the verification date. Each service has its own page with the price matrix, the plan purchase endpoint, and a link to its own OpenAPI document. The catalog page says to open only the service you will call.

**Product Search specification.** One operation, `POST /v1/products`. The request body requires `search`, which takes a plain string for a broad match or an array of filter objects. Optional fields include `query` for a structured rule builder (mutually exclusive with `search`), `fields`, `facets`, `sort_by`, `sort_order`, `page`, `per_page`, and `after` for cursor pagination beyond ten thousand results. The operation's `x-payment-info` block repeats the price and names the service slug it bills, which the document says is never to be sent as a request value.

**payment.md.** The payment contract. A priced `402` carries `payment.amountUsd`, the `plan`, and a `protocols` block with a challenge for each rail offered. Wallet rails settle a per-call payment without any identity step; the signed payment is the identity. Card payment applies to plan purchases and to single calls of $0.50 or more, which excludes a $0.02 search unless a plan is bought first. Credits plans have a $0.50 minimum and are topped up with `POST /extend`.

**auth.md.** The identity contract. Registration is required for buying or extending a plan on every rail, and not required for pay-as-you-go calls. One registration works at every storefront on this network. On MPP, where `Authorization` carries the payment credential, the bearer travels in `ZC-Agent-Authorization` instead; the document is explicit that `Authorization` carries exactly one credential.

**handoff.md.** The rule for people. Any Affiliate.com link given to a person goes through `outclick?url=` with an encoded target on an Affiliate.com domain; the endpoint records the referral and answers `302`. Other targets are rejected with `400`.

**errors.md.** The error reference, including `401 bearer_required` for a plan purchase without a credential and `usage_exhausted` for a drained balance.

## What a bare request returned

On September 17, 2026, at 01:10 UTC, this request was sent with no payment attached:

```
POST https://zeroclick.affiliate.com/zcj/n09siuvceyf4/v1/products
Content-Type: application/json

{"search": "cordless stick vacuum", "limit": 3}
```

The storefront answered `402`. The body, trimmed to the fields an agent acts on:

```
{
  "x402Version": 2,
  "error": "payment_required",
  "resource": { "url": "https://zeroclick.affiliate.com/v1/products", "serviceName": "Affiliate.com" },
  "payment": { "id": "apay_…", "amountUsd": "0.020000" },
  "plan": { "slug": "payg", "billingMode": "payg" },
  "usage": [ { "meterSlug": "requests", "quantity": 1 } ],
  "accepts": [ {
    "scheme": "exact", "network": "eip155:8453",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "amount": "20000", "payTo": "0x6e9c…62b2", "maxTimeoutSeconds": 300
  } ],
  "protocols": {
    "mpp":  { "challengeId": "…", "method": "tempo", "intent": "charge" },
    "x402": { "x402Version": 2, "network": "eip155:8453", "scheme": "exact", "amount": "20000" }
  },
  "auth":  { "note": "Pay-as-you-go needs no registration: settle this challenge as usual. …" },
  "terms": { "note": "By paying this challenge, whether directly or through an agent acting on your behalf, you accept the platform's buyer terms of service; …" }
}
```

The same challenge arrived in the headers: the x402 challenge in `payment-required` and the MPP challenge in `www-authenticate` as `Payment id="…", realm="zeroclick.affiliate.com", method="tempo", intent="charge"`, so a standard client for either rail settles it without reading the body. No payment was made for this record, so no product data was returned; the full captured challenge is in the test record below.

## Two distinctions worth keeping

The first is between the two identities in these documents. A pay-as-you-go call has no identity beyond the signed payment. A plan purchase has an agent credential, registered once and presented as a bearer. An agent that only searches never needs the second; an agent that wants a balance to draw on does, and on MPP it must present it in the alternate header.

The second is between the price and the terms. The `402` quotes $0.02, and its `terms` note says that paying accepts the platform's buyer terms and attributes an agent's acceptance to the person it acts for. The price is a fact about this request. The attribution is a fact about the person who operates the agent, and it travels in every challenge and receipt as `terms`.

For anything these notes do not settle, the controlling text is the storefront's own: start at [llms.txt](https://zeroclick.affiliate.com/llms.txt) and follow its links.
