Skip to main content
GET
Beta — this endpoint is in active development and may change without notice. Field names, ranking, and coverage are still evolving. We’d love your feedback: book a 30-minute customer interview and help shape the v1 — we’ll send you a $50 Amazon gift card as a thank-you.
GET /search returns a single ranked list of buyable products across every supported retailer — Amazon, Walmart, Target, Best Buy, Home Depot, Lowe’s, Costco, Wayfair, Macy’s, and more — in one call. Each result’s url is the orderable retailer URL: pass it directly to Create order. There is no opaque sku id and no separate ASIN / item-id field — the URL is the contract. This is distinct from the per-retailer /products/search, which searches one retailer at a time. Use /search when you want breadth.

Pricing

Search is billed whether or not you go on to order. A retry loop bills every attempt: check GET /wallet/me rather than retrying into a 402.
The MPP counterpart POST /agent/search is the same search at the same price, paid per request instead of from a wallet.

Ranking

Results are ranked by a quality signal that combines rating and review volume, with price as a tiebreaker for unrated items. The list is then woven across retailers so a single retailer doesn’t dominate the top — typically you’ll see two or three different retailers in the first few results.

Filtering and sorting

All three parameters are optional. With none set, a search behaves exactly as described above. The explicit sorts don’t reorder every result. They take the 20 most relevant results (or limit, if larger) that match at least half the query, then sort those, so a cheap accessory that merely names the product can’t lead a price_asc page. Results with no price (or no rating, for rating) sort last. A search costs one billed call whatever limit you set.

Shopify stores

retailer also takes up to 3 Shopify stores, by their retailer slug (e.g. retailer=yetch) or domain. GET /retailers/check?url= returns a store’s slug.
  • A store in the filter is searched directly, using the store’s own search. A filter of only stores (?retailer=yetch) searches just those stores; mix in other retailers (?retailer=amazon&retailer=yetch) and the results are ranked together.
  • Each result’s url is on the store’s public domain, so it goes straight to Create order. retailer is the store’s slug.
  • With a live key, a store not yet in Zinc’s catalog is checked and added the first time you name it by domain, exactly as on Search Products, with the same 422, 503 and 429 answers when it can’t be. In test mode and on POST /agent/search, an uncatalogued store returns 422.
  • More than 3 stores returns 422. If one store’s search fails, the others’ results are still returned.
  • It’s still one billed call, however many stores the filter names.

Etsy

retailer=etsy (or etsy.com) searches Etsy directly, the same way a store is searched. Etsy can be combined with other retailers and stores, and it doesn’t count toward the 3-store limit.
  • Each result’s url is the Etsy listing. retailer is etsy.
  • Results have no stars or num_reviews. Etsy publishes no product-level rating, so sort=rating puts Etsy results last.
  • Only listings priced in US dollars are returned.
  • has_variants says whether a listing has options, such as size or color, that must be chosen before it can be ordered. false means it can be ordered as is. When it’s true, the API can’t tell you what the options are: Etsy shares them only with the listing’s own shop. Read them from the listing page, then pass the buyer’s choice as variant when you create the order: one {label, value} pair per option, using the option name and choice as the listing shows them (e.g. {"label": "Size", "value": "Large"}). Etsy won’t cart a listing with options until one is chosen, so expect an order without variant to fail. has_variants is null on other retailers’ results.

Beta limits

These will change before v1:
  • No condition filter — used / marketplace listings may appear when the source doesn’t expose condition.
  • Coverage varies by query; some long-tail and DTC retailers may not appear.
  • retailer is the only filter; there’s no brand, category, or rating filter yet.
  • Shopify stores and Etsy appear only when named in retailer; an unfiltered search doesn’t include them.
  • Response shape may add fields (e.g. condition, shipping ETA). Existing fields won’t be removed without notice.

Help shape the beta

Customer interview — 30 minutes · $50 Amazon gift card

We’re actively iterating on /search. Tell us what queries you’re running, what coverage you need, and what’s missing. As a thank-you we’ll send you a $50 Amazon gift card.

Authorizations

Authorization
string
header
required

Zinc API key (Bearer zn_...)

Headers

authorization
string | null

Query Parameters

q
string
required

Search term

Minimum string length: 1
min_price
integer | null

Cents. Drop results priced below this.

Required range: x >= 0
max_price
integer | null

Cents. Drop results priced above this. Pass the max_price you intend to send to POST /orders and every result returned fits it. Results with no known price are dropped when a clamp is set.

Required range: x >= 0
retailer
string[] | null

Only return results from these retailers. Repeat the param for several: ?retailer=amazon&retailer=target. Takes the discovery retailers (amazon, bestbuy, bhphotovideo, chewy, costco, homedepot, kohls, lowes, macys, newegg, staples, target, walmart, wayfair), etsy, and up to 3 catalogued Shopify stores by their Zinc retailer slug (e.g. retailer=yetch; a store's domain also works). Etsy and stores are searched directly, and only when named here: an unfiltered search never includes them. Etsy results are listings: when has_variants is true the order needs a variant, and the options must be read from the listing page, because Etsy shares them only with the listing's own shop. With a live key, a Shopify store not yet catalogued is added on first use by its domain.

sort
enum<string>
default:relevance

Result order. relevance (default) blends query match, source rank and rating, and mixes retailers. The explicit sorts order the 20 most relevant results (or limit, if larger) that match at least half the query, so accessories that merely name the product don't lead; results with no price (or no rating, for rating) sort last.

Available options:
relevance,
price_asc,
price_desc,
rating
limit
integer | null

Return at most this many results (1-50). One search is one billed call either way.

Required range: 1 <= x <= 50

Response

Successful Response

Response from the cross-retailer search endpoint.

status
string
required
query
string
required
results
Sku · object[]
excluded_by_price
integer | null

How many orderable results the min_price/max_price clamp removed; null when no clamp was set.

hint
string | null

Set when the result list is empty for a reason the caller can act on.