Shop API: List store products
Lists publicly published products from a Shopify store in catalogue or collection order, with variant prices and availability, optionally filtered by name words or an exact collection name.
Unofficial. Not affiliated with or endorsed by Shop.
Inputs
Values from the run on Oct 31, 2026, shown under Output.
- Page optional
page Page of matching products, for example 1.
1 (default)
Whole number 1 or more.
- Store, required
store Store website or a page on the store, for example allbirds.com or https://www.allbirds.com/collections/mens-shoes.
allbirds.com
- Keywords optional
keywords Text that each product name must contain, such as runner. Case-insensitive; leave blank for all names.
(default)
- Collection optional
collection Exact collection name to list, such as Men's Active Shoes. Leave blank for all products.
Men's Active Shoes
Default
.- Max Results optional
max_results Maximum matching products returned per page, for example 50.
3
Whole number from 1 to 250. Default
50.
Input as JSON
{ "store": "allbirds.com", "collection": "Men's Active Shoes", "max_results": 3}Output
{ "products": [ { "tags": [ "allbirds::carbon-score => 5.48", "allbirds::cfId => color-mens-tree-dashers2-natural-black-blizzard", "allbirds::complete => true" ], "brand": "Allbirds", "currency": "USD", "in_stock": false, "variants": [ { "sku": "AA000YM080", "price": 140, "in_stock": false, "variant_id": 39656140243024, "option_names": "8" }, { "sku": "AA000YM085", "price": 140, "in_stock": false, "variant_id": 39656140275792, "option_names": "8.5" }, { "sku": "AA000YM090", "price": 140, "in_stock": false, "variant_id": 39656140308560, "option_names": "9" } ], "product_id": 6643980468304, "lowest_price": 140, "product_link": "https://allbirds.com/products/mens-tree-dashers" , "product_name": "Men's Tree Dasher 2 - Natural Black (Blizzard Sole)", "product_type": "Shoes", "shopify_handle": "mens-tree-dashers", "main_image_link": "https://cdn.shopify.com/s/files/1/1104/4168/files/AA000YM_SHOE_LEFT_GLOBAL_MENS_TREE_DASHER_2.0_Natural_Black_Blizzard_48bbccd1-a0ef-475d-a3c1-af945ece7fbc.png?v=1751061059" , "last_updated_date": "2026-09-29", "price_before_discount": null }, { "tags": [ "allbirds::carbon-score => 5.48", "allbirds::cfId => color-mens-tree-dashers2-blizzard-blizzard", "allbirds::complete => true" ], "brand": "Allbirds", "currency": "USD", "in_stock": false, "variants": [ { "sku": "AA000QM080", "price": 140, "in_stock": false, "variant_id": 39656318861392, "option_names": "8" }, { "sku": "AA000QM085", "price": 140, "in_stock": false, "variant_id": 39656318894160, "option_names": "8.5" }, { "sku": "AA000QM090", "price": 140, "in_stock": false, "variant_id": 39656318926928, "option_names": "9" } ], "product_id": 6644025557072, "lowest_price": 140, "product_link": "https://allbirds.com/products/mens-tree-dashers-blizzard-black" , "product_name": "Men's Tree Dasher 2 - Blizzard (Blizzard/Black Sole)" , "product_type": "Shoes", "shopify_handle": "mens-tree-dashers-blizzard-black", "main_image_link": "https://cdn.shopify.com/s/files/1/1104/4168/files/AA000QM_SHOE_LEFT_GLOBAL_MENS_TREE_DASHER_2.0_Blizzard_Blizzard.png?v=1751060717" , "last_updated_date": "2026-09-29", "price_before_discount": null }, { "tags": [ "allbirds::carbon-score => 5.48", "allbirds::cfId => color-mens-tree-dashers2-natural-black-natural-black", "allbirds::complete => true" ], "brand": "Allbirds", "currency": "USD", "in_stock": true, "variants": [ { "sku": "AA0022M080", "price": 99, "in_stock": false, "variant_id": 39789589790800, "option_names": "8" }, { "sku": "AA0022M085", "price": 99, "in_stock": false, "variant_id": 39789589823568, "option_names": "8.5" }, { "sku": "AA0022M090", "price": 99, "in_stock": false, "variant_id": 39789589856336, "option_names": "9" } ], "product_id": 6697913974864, "lowest_price": 99, "product_link": "https://allbirds.com/products/mens-tree-dashers-natural-black-natural-black" , "product_name": "Men's Tree Dasher 2 - Natural Black (Natural Black Sole)", "product_type": "Shoes", "shopify_handle": "mens-tree-dashers-natural-black-natural-black", "main_image_link": "https://cdn.shopify.com/s/files/1/1104/4168/files/AA0023W_Shoe_Left_Global_Womens_Tree_Dasher_2_Natural_Black_Natural_Black_f8ef9dac-3200-4847-9142-47c4cf652ea9.png?v=1759440165" , "last_updated_date": "2026-09-29", "price_before_discount": 140 } ], "store_name": "Allbirds"}Code
curl https://api.fous.com/v1/runs \ -H "Authorization: Bearer $FOUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"method":"shop.app/list_store_products","input":{"store":"allbirds.com","collection":"Men' \''s Active Shoes","max_results":3}}'# Save as fous.py, then run: python3 fous.pyimport json, os, timefrom urllib.error import HTTPErrorfrom urllib.request import Request, urlopenAPI = "https://api.fous.com/v1/runs" KEY = os.environ["FOUS_API_KEY"]HEADERS = { "Authorization": f"Bearer {KEY}", "Content-Type": "application/json" ,}def call(url, body=None): data = json.dumps(body).encode() if body else None request = Request(url, data, HEADERS) try: with urlopen(request, timeout=120) as r: return r.status, json.load(r) except HTTPError as error: message = json.load(error)["error"]["message"] raise RuntimeError(message) from errorstatus, run = call(API, { "method": "shop.app/list_store_products" , "input": { "store": "allbirds.com", "collection": "Men's Active Shoes", "max_results": 3 }})# 202: still going after 30 s. Ask again until it ends.while status == 202: time.sleep(2) status, run = call(f"{API}/{run['id']}")print(json.dumps(run["data"], indent=2))// Save as fous.mjs, then run: node fous.mjsconst api = "https://api.fous.com/v1/runs" ;const headers = { Authorization: `Bearer ${process.env.FOUS_API_KEY}`, "Content-Type": "application/json" ,};let response = await fetch(api, { method: "POST", headers, body: JSON.stringify({ "method": "shop.app/list_store_products" , "input": { "store": "allbirds.com", "collection": "Men's Active Shoes", "max_results": 3 } }), signal: AbortSignal.timeout(120_000),});let run = await response.json();// 202: still going after 30 s. Ask again until it ends.while (response.status === 202) { await new Promise((done) => setTimeout(done, 2_000)); response = await fetch(`${api}/${run.id}`, { headers }); run = await response.json();}if (!response.ok) throw new Error(run.error.message);console.log(run.data);# Connect your agent to Fous once, over MCP (Streamable HTTP):# https://api.fous.com/mcp# Set FOUS_API_KEY first: create a key at https://app.fous.com/keys.# Claude Codeclaude mcp add \ --scope user \ --transport http fous https://api.fous.com/mcp \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Codexcodex mcp add fous \ --url https://api.fous.com/mcp \ --bearer-token-env-var FOUS_API_KEY# Cursor, VS Code, Windsurf, Cline and morenpx -y add-mcp https://api.fous.com/mcp -g -n fous \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Then ask your agent:# "Use Fous to run shop.app/list_store_products# with {"store":"allbirds.com","collection":"Men's Active Shoes","max_results":3}"Over HTTP, the answer’s data holds the output. A run still going after 30 seconds answers 202 with its id: ask GET /v1/runs/{id} until it ends.
Schema
Input schema
{ "type": "object", "required": [ "store" ], "properties": { "page": { "type": "integer", "default": 1, "minimum": 1, "description": "Page of matching products, for example 1." }, "store": { "type": "string", "minLength": 1, "description": "Store website or a page on the store, for example allbirds.com or https://www.allbirds.com/collections/mens-shoes." }, "keywords": { "type": "string", "default": "", "description": "Text that each product name must contain, such as runner. Case-insensitive; leave blank for all names." }, "collection": { "type": "string", "default": "", "description": "Exact collection name to list, such as Men's Active Shoes. Leave blank for all products." }, "max_results": { "type": "integer", "default": 50, "maximum": 250, "minimum": 1, "description": "Maximum matching products returned per page, for example 50." } }}Output schema
{ "type": "object", "required": [ "store_name", "products" ], "properties": { "products": { "type": "array", "items": { "type": "object", "required": [ "product_name", "brand", "product_type", "lowest_price", "price_before_discount", "currency", "in_stock", "variants", "tags", "main_image_link", "product_link", "last_updated_date", "product_id", "shopify_handle" ], "properties": { "tags": { "type": "array", "items": { "type": "string" } }, "brand": { "type": [ "string", "null" ] }, "currency": { "type": "string" }, "in_stock": { "type": "boolean" }, "variants": { "type": "array", "items": { "type": "object", "required": [ "option_names", "price", "in_stock", "variant_id", "sku" ], "properties": { "sku": { "type": [ "string", "null" ] }, "price": { "type": "number" }, "in_stock": { "type": "boolean" }, "variant_id": { "type": [ "integer", "null" ] }, "option_names": { "type": "string" } }, "additionalProperties": false } }, "product_id": { "type": [ "integer", "null" ] }, "lowest_price": { "type": [ "number", "null" ] }, "product_link": { "type": "string" }, "product_name": { "type": "string" }, "product_type": { "type": [ "string", "null" ] }, "shopify_handle": { "type": "string" }, "main_image_link": { "type": [ "string", "null" ] }, "last_updated_date": { "type": [ "string", "null" ] }, "price_before_discount": { "type": [ "number", "null" ] } }, "additionalProperties": false } }, "store_name": { "type": "string" } }, "additionalProperties": false}- Price
- 1 credit per completed run (1¢ with pay as you go); failed runs are free.
- Method
shop.app/list_store_products- Returns
- store name; products with name, brand, type, lowest and pre-discount price, currency, stock, variants, tags, image, link, last update
Use it from your agent
Give your agent this line. It reads SKILL.md, gets a Fous API key and connects the Fous MCP server. Its run then takes the method shop.app/list_store_products with the inputs above.
Ask your agent
- What products does gymshark.com sell with "leggings" in the name? Include prices and whether they're in stock.
- Use Shop to pull the first 100 items from the "Best Sellers" collection on bombas.com, with variant prices and stock.
- I want to know which items on https://www.brooklinen.com/collections/sheets are currently discounted. Show me their sale price next to the original price.
- Through shop.app, get page 2 of the full catalogue for tentree.com, 25 products per page.
- Find all mug products on deathwishcoffee.com, with their tags, images, and when each one was last updated.
See more
All Shop methodsGets a public Shopify product by its product page link, or by the closest name match within a store. Stores that restrict public product access cannot be read.
shop.app/get_store_productSearches Amazon products in a chosen country store, with price range, sort, Prime and page options. Returns the listings and prices shown to an anonymous shopper in the store's currency.
amazon.com/search_productsSearch Nordstrom products by words, price, sale status and sort order. Prices are the lowest listed price. Available sizes may be empty when a product page is unavailable.
nordstrom.com/search_productsGets current Apple Store prices and the configurations on sale for a product in one country. It includes only models sold on that country's public store.
apple.com/get_product_pricesLists the 20 products on the first Books to Scrape catalog page, with each product's detail page link, full title, displayed price and stock status.
books.toscrape.com/get_first_catalog_productsSearches Walmart products by keywords with optional sort and price range, returning prices, ratings, sellers and availability in Walmart's order. Uses Walmart's default location (no ZIP-based pricing).
walmart.com/search_productsSearches Macy's products in the site's order with optional USD price bounds, sale-only results and sorting. Prices for products with a range use the lowest shown price.
macys.com/search_productsSearches clothes and shoes in one Zalando country shop, with optional gender, brand, deal and sort filters. Prices and discounts are those shown on the product cards; size-dependent prices may be starting prices.
zalando.com/search_products