Skip to main content
GET
Search Products
Search one retailer’s catalog. Results are normalized into a single shape across retailers: product_id, title, image, brand, price, stars, and num_reviews are common to every retailer, and the remaining fields are retailer-specific and null elsewhere. The Response section below lists each field, and the example shows a real Amazon page of results. Prices are integers in cents. Etsy results also carry currency_code, and their price is in minor units of that currency. They also carry has_variants, which is true when the listing needs an option such as size or color chosen before it can be ordered. See Etsy on Search for how to order one.

Pricing

This is a metered data call, 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/products/search is the same search at the same price, paid per request instead of from a wallet.

Which retailer to pass

retailer is a Zinc retailer slug, the same identifier GET /retailers/check returns as retailer.retailer: To find a Shopify store’s slug, call GET /retailers/check?url= with any URL on the store. Two older forms still work: a store’s domain or URL (yetch.studio, https://www.seekinghealth.com/products/...) and the amazon_uk-style marketplace codes. Prefer the slug: the details and offers responses name the retailer by its slug in retailer, so the value you get back is the value to pass on. A Shopify store’s details also carry platform: "shopify". A retailer Zinc orders from but has no product data for, such as target, returns 422.

New Shopify stores

A Shopify store doesn’t have to be in Zinc’s catalog before you ask for it. With a live key, pass the store’s domain (or any URL on it) as retailer. The first request checks the store, which takes a few seconds, adds it to the catalog, and serves the request as usual. From then on the store answers to its slug and its domain like any other, with no further check. What can come back from that first request instead: Only a successful request is billed, as with any other call. A refused or failed check costs nothing.
Test keys and the MPP-paid /agent/* endpoints only reach stores already in the catalog. Anything else returns 422 ('<domain>' is not in Zinc's retailer catalog). Make one live-key request with the store’s domain to add it, or email support@zinc.com.

Going from a result to a product

Pass a result’s product_id, with the same retailer, to Get Product Details or Get Product Offers. Best Buy is the exception: search returns the SKU as product_id, but the details endpoint is addressed by the bsin, the trailing id in the product URL.

Paging

Use next_page from the response rather than counting results. A short or even empty results array with a non-null next_page is not the end of the results; this happens on free_shipping searches, on Best Buy (which server-renders only a few items per page), and on Etsy (which drops non-USD listings after paginating). next_page is null when the results are exhausted, and always null for Shopify stores, which return a single page.

Authorizations

Authorization
string
header
required

Zinc API key (Bearer zn_...)

Headers

authorization
string | null

Query Parameters

query
string
required

Search term

Minimum string length: 1
retailer
string
required

Zinc retailer slug: amazon, amazon-uk, amazon-ca, amazon-de, amazon-mx, amazon-fr, walmart, bestbuy, etsy, or a catalogued Shopify store's slug (e.g. retailer=yetch; GET /retailers/check?url=... returns a store's slug). A store's domain is also accepted, as are the older amazon_uk-style codes. A Shopify store not yet in Zinc's catalog is added on a live key's first request for it by domain; any other unknown value is a 422. Responses carry the slug.

page
integer | null

Page number for pagination

free_shipping
boolean
default:false

Only return items that ship for free (Walmart and Best Buy: ship price of 0). Currently a no-op for Amazon: the upstream search data under-reports Prime, so filtering on it would drop valid items — Amazon results are returned unfiltered. Filtering happens after pagination, so per-page counts vary; use next_page in the response to keep paging — an empty page with a non-null next_page is not the end of results. Rejected for Shopify stores: their search data carries no shipping information, so the filter cannot be honored.

Response

Normalized search results. Common fields are always present; retailer-specific fields are null or omitted for other retailers.

Response from the product search endpoint.

status
string
required
results
ProductSearchResult · object[]
next_page
integer | null

Only set on free_shipping searches: the page to request to keep paging. An empty results with a non-null next_page is NOT the end of results — request next_page to continue. None means results are exhausted (or the search was unfiltered).