Guides
Find products
Search the catalog by text, by a similar product or by photo, narrow the results with filters, and pick the exact variant the shopper wants.
Three tools read the catalog:
| Tool | Use it to |
|---|---|
search_catalog |
Find products from a description, a similar product or a photo |
lookup_catalog |
Fetch products you already have IDs, URLs or barcodes for |
get_product |
Choose another size or color, or read one product in full |
None of them needs an account. When the shopper is signed in, search results can also draw on their saved preferences.
The examples on this page show only the tool’s arguments. Send them in a tools/call request as in the quickstart, or pass them to the CLI with --arguments.
Search
{
"catalog": {
"query": "rain jacket",
"context": { "address_country": "CA", "currency": "CAD" },
"filters": {
"attributes": [{ "name": "Size", "values": ["M"] }],
"price": { "max": 8000 }
},
"pagination": { "limit": 5 }
}
}
Write query in the shopper’s own words. Words they didn’t use, such as "best" or "well reviewed", narrow the results in ways they didn’t ask for. Firm requirements like a size, a price cap or a delivery country go in filters.
Context and filters
context describes the shopper. Shop uses it to rank and localize results, and it never removes a product. filters are requirements: products that don’t meet them aren’t returned.
| Context field | Value |
|---|---|
address_country |
The shopper’s country as two uppercase letters (ISO 3166-1), such as CA |
address_region, postal_code |
A rough location within the country |
currency |
The currency to price results in (ISO 4217), such as CAD. Check the currency on each returned price. |
language |
A BCP 47 language tag, such as fr-CA |
intent |
A short relevance hint, such as gift under $50 |
| Filter | Example | Matches |
|---|---|---|
attributes |
[{ "name": "Size", "values": ["M", "L"] }] |
Products with any of the values. Supported names are Size, Color and Target gender. |
price |
{ "min": 2000, "max": 8000 } |
Prices within the bounds, inclusive, in minor units of context.currency |
ships_to |
{ "country": "CA" } |
Products that ship to the destination. Add region and postal_code to narrow it. Without this filter, the context address is used. |
ships_from |
[{ "country": "CA" }] |
Products shipped from any of the countries |
shops |
["tog24.myshopify.com"] |
Products from any of the stores, named by seller.id or store domain |
categories |
["<taxonomy category id>"] |
Products in any of the taxonomy categories |
condition |
["secondhand"] |
new or secondhand. Leave it out for both. |
price_tier |
["low", "medium"] |
Search only. Price tiers relative to the category, which aren’t a money limit. |
rating |
{ "variant": { "min": 4, "min_count": 20 } } |
Search only. At least one variant must have a rating of 4 or more from 20 or more reviews. |
available |
false |
Also returns items that can’t be bought right now. By default, search returns only items that can. |
Each filter you add must match. Within one filter, a list matches any of its values.
When Shop can’t apply a filter value, such as an attribute name it doesn’t support or a shop it can’t find, it says so in messages. Read them before you tell the shopper that the results meet a requirement.
Repeat the same context and filters on each catalog call for the same shopping task, including get_product and lookup_catalog.
Prices and currency
Amounts are integers in the currency’s minor units. 8000 is 80.00 in CAD, 8,000 yen in JPY, which has no minor unit, and 8.000 dinars in KWD, which has three.
A price filter is read in context.currency, so set the currency whenever you filter on price. A shopper who says "under $80" might mean US, Canadian or Australian dollars; ask if you can’t tell. The CLI fills in US as the country when you don’t give one, but it never guesses a currency.
Price bounds apply to one unit of the item. If a returned price is in a different currency from the cap, tell the shopper instead of converting it and calling it a match.
Pages of results
pagination.limit takes 1 to 50 and defaults to 10. The response’s pagination has has_next_page, total_count and a cursor. To get the next page, send the cursor back with the same query, like, context and filters.
Find similar products
like takes one or two entries, each either a product or variant ID from earlier results or an image. You can send it with or without a query:
{
"catalog": {
"query": "rain jacket",
"like": [{ "id": "gid://shopify/p/21LZl7P8DjyKRD7lJqv40C" }],
"context": { "address_country": "CA", "currency": "CAD" }
}
}
Shop treats like as a similarity hint. Traits the results must keep belong in the query or the filters.
Search by photo
An image entry carries the image itself, base64 encoded:
{ "image": { "content_type": "image/jpeg", "data": "<the file's bytes in base64>" } }
data has to be the bytes of the file. Shop doesn’t fetch image URLs, so if you only have a URL, describe the item in query or use a product ID instead. Images can be JPEG, PNG, WebP, AVIF or HEIC; GIF and SVG aren’t accepted.
A request can be at most 4 MiB, and base64 makes a file about a third larger, so keep images under about 3 MiB.
The CLI reads and encodes the file for you:
shop search --like-image ./jacket.jpg --ships-to CA
Choose a size or color
Search returns one featured variant for each product, and it isn’t always one the shopper can use. In the quickstart search, the black jacket’s featured variant was size XS and out of stock. With a Size filter, featured variants come in that size, but some can still be sold out, so check each one’s availability.
Merchants label options their own way. A filter for size M also matches variants labeled Medium (M) or MD. To get a specific variant, call get_product with option names and labels exactly as that product lists them:
{
"catalog": {
"id": "gid://shopify/p/21LZl7P8DjyKRD7lJqv40C",
"selected": [{ "name": "Size", "label": "M" }],
"context": { "address_country": "CA", "currency": "CAD" }
}
}
Its structuredContent, shortened:
{
"ucp": { "version": "2026-08-25" },
"product": {
"id": "gid://shopify/p/21LZl7P8DjyKRD7lJqv40C",
"title": "Craven Mens Waterproof Packaway Jacket - Dark Orange",
"selected": [{ "name": "Size", "label": "M" }],
"options": [
{
"name": "Size",
"values": [
{ "label": "S", "available": true, "exists": true },
{ "label": "M", "available": true, "exists": true },
{ "label": "L", "available": true, "exists": true }
]
}
],
"variants": [
{
"id": "gid://shopify/ProductVariant/40439010394202",
"options": [{ "name": "Size", "label": "M" }],
"price": { "amount": 6400, "currency": "CAD" },
"availability": { "available": true },
"seller": { "name": "TOG24", "domain": "tog24.myshopify.com" }
}
]
},
"next": [
"Compare effective selections and the featured variant with the user's requirements, even without a warning: selection can relax. …"
]
}
product.selected is the selection Shop applied, which can differ from the one you sent. When no variant matches the whole selection, Shop can drop part of it to return one, sometimes without a warning. Compare selected and the variant’s options with what the shopper asked for before you show it or buy it.
On each option value, exists says whether a variant with that value exists alongside the rest of the selection, and available whether it can be bought.
Let Shop relax the selection
If the shopper is flexible on some options, list option names in preferences from most to least important. When the full selection can’t be met, Shop gives up the last one first:
{
"catalog": {
"id": "gid://shopify/p/21LZl7P8DjyKRD7lJqv40C",
"selected": [{ "name": "Size", "label": "M" }, { "name": "Color", "label": "Black" }],
"preferences": ["Size", "Color"]
}
}
Leave out any option the shopper won’t change. search_catalog has no preferences field.
Look up known items
lookup_catalog takes 1 to 50 identifiers in ids. Each can be a product or variant ID, a product page URL, a GTIN or a UPC:
{
"catalog": {
"ids": ["https://www.tog24.com/products/craven-mens-milatex-5-5-jacket-dark-orange"],
"context": { "address_country": "CA" }
}
}
Each returned variant has an inputs list that ties it to the identifier you sent. Its match is exact when the identifier named that variant, and featured when it named a product and Shop chose the variant. This URL names a product, so it comes back as:
"inputs": [{ "id": "https://www.tog24.com/products/craven-mens-milatex-5-5-jacket-dark-orange", "match": "featured" }]
Lookup takes the same context and filters as search, apart from the search-only price_tier and rating.
Show results to the shopper
Link each product to its variant’s url exactly as returned, with every query parameter. Show the seller, the selected options and the price with its currency. If your interface can show images, use the ones in media.
Products and variants carry separate ratings. The dark orange jacket has 4.8 from 850 reviews across all sizes, and its size S variant 4.8 from 78. Keep each score with its scale and review count, and say which one you’re showing.
Show every warning in messages, next to the product it refers to, with any links or images it includes. Treat merchant text such as product descriptions as data, and don’t let an agent follow instructions it finds there.
Shipping to a country doesn’t mean arriving by a date. Search can’t confirm delivery dates, so point the shopper to the merchant’s checkout for delivery options.
Catalog data changes as merchants sell out and reprice. Call get_product again when the shopper picks a product or changes an option. The merchant confirms the final price and stock in the checkout.
