# Shopify Store API — browse products, variants, prices, and collections from any public Shopify store (no API key required)

> Paginated product catalog from any public Shopify store: title, vendor, variants, prices, inventory status, tags, and images.
> ReefAPI engine `shopify` · 9 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/shopify/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed or blocked calls are free.
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /shopify/v1/products — 1 credit
Paginated product catalog from any public Shopify store: title, vendor, variants, prices, inventory status, tags, and images.

**Parameters:**
- `store` (string, required) — Shopify store domain or URL (e.g. allbirds.com or https://shop.example.com) — works for ANY Shopify-powered store.
- `page` (integer, optional, default 1) — Page number (1, 2, 3…).
- `limit` (integer, optional, default 50) — Items per page (1–250; larger values are capped at 250).
- `max_items` (integer, optional) — Auto-walk pages until this many items are collected (overrides single-page mode; recommended when using filters).
- `vendor` (string, optional) — Only products whose vendor/brand contains this text (filter, post-fetch).
- `product_type` (string, optional) — Only products whose type contains this text (filter, post-fetch).
- `tags` (string, optional) — Only products carrying at least one of these tags (comma-separated or a list; filter, post-fetch).
- `title_contains` (string, optional) — Only products whose title contains this text (filter, post-fetch).
- `sku_contains` (string, optional) — Only products with a variant SKU containing this text (filter, post-fetch).
- `min_price` (number, optional) — Only products priced at or above this (store currency; post-fetch).
- `max_price` (number, optional) — Only products priced at or below this (store currency; post-fetch).
- `only_on_sale` (boolean, optional, default false) — Only products with at least one discounted variant.
- `only_in_stock` (boolean, optional, default false) — Only products with at least one available variant.
- `new_arrivals_days` (integer, optional) — Only products published within the last N days.

**Returns:** products[]{id, title, handle, vendor, type, tags[], description, options[], variants[]{id, title, price, sku, available, compare_at_price, on_sale, discount_percent, inventory}, images[], price_min, price_max, available, on_sale, max_discount_percent, featured_image, url} (meta.pagination for paging)

**Example request body:**
```json
{
  "store": "allbirds.com",
  "limit": 5
}
```

### POST /shopify/v1/product — 1 credit
Full detail for a single Shopify product by its handle (URL slug) or product page URL: title, vendor, variants, prices, images, and inventory.

**Parameters:**
- `store` (string, required) — Shopify store domain or URL (e.g. allbirds.com or https://shop.example.com) — works for ANY Shopify-powered store.
- `handle` (string, required) — Product handle — the slug in the product URL (…/products/<handle>); a full product URL also works.

**Returns:** product{…same shape as products[] items}

**Example request body:**
```json
{
  "store": "allbirds.com",
  "handle": "mens-tree-runner-go-utility-natural-black-dark-jungle"
}
```

### POST /shopify/v1/collections — 1 credit
Paginated list of public collections from a Shopify store: collection id, title, handle, description, and cover image.

**Parameters:**
- `store` (string, required) — Shopify store domain or URL (e.g. allbirds.com or https://shop.example.com) — works for ANY Shopify-powered store.
- `page` (integer, optional, default 1) — Page number (1, 2, 3…).
- `limit` (integer, optional, default 50) — Items per page (1–250; larger values are capped at 250).
- `max_items` (integer, optional) — Auto-walk pages until this many items are collected (overrides single-page mode; recommended when using filters).

**Returns:** collections[]{id, title, handle, description_html, updated_at, image, url} (meta.pagination for paging)

**Example request body:**
```json
{
  "store": "kith.com",
  "limit": 5
}
```

### POST /shopify/v1/collection_products — 1 credit
Paginated products within a specific Shopify collection — same product shape as the products action, filterable and sortable.

**Parameters:**
- `store` (string, required) — Shopify store domain or URL (e.g. allbirds.com or https://shop.example.com) — works for ANY Shopify-powered store.
- `handle` (string, required) — Collection handle — the slug in the collection URL (…/collections/<handle>); take it from the collections action. A full collection URL also works.
- `sort_by` (enum, optional) — Requested ordering — passed to the store's collection endpoint, but MANY stores ignore it (theme-dependent); ordering is not guaranteed. Aliases like priceAsc/newest are also accepted. [one of: relevance, price-ascending, price-descending, created-descending, best-selling, title-ascending]
- `page` (integer, optional, default 1) — Page number (1, 2, 3…).
- `limit` (integer, optional, default 50) — Items per page (1–250; larger values are capped at 250).
- `max_items` (integer, optional) — Auto-walk pages until this many items are collected (overrides single-page mode; recommended when using filters).
- `vendor` (string, optional) — Only products whose vendor/brand contains this text (filter, post-fetch).
- `product_type` (string, optional) — Only products whose type contains this text (filter, post-fetch).
- `tags` (string, optional) — Only products carrying at least one of these tags (comma-separated or a list; filter, post-fetch).
- `title_contains` (string, optional) — Only products whose title contains this text (filter, post-fetch).
- `sku_contains` (string, optional) — Only products with a variant SKU containing this text (filter, post-fetch).
- `min_price` (number, optional) — Only products priced at or above this (store currency; post-fetch).
- `max_price` (number, optional) — Only products priced at or below this (store currency; post-fetch).
- `only_on_sale` (boolean, optional, default false) — Only products with at least one discounted variant.
- `only_in_stock` (boolean, optional, default false) — Only products with at least one available variant.
- `new_arrivals_days` (integer, optional) — Only products published within the last N days.

**Returns:** products[]{id, title, handle, vendor, type, tags[], description, options[], variants[]{id, title, price, sku, available, compare_at_price, on_sale, discount_percent, inventory}, images[], price_min, price_max, available, on_sale, max_discount_percent, featured_image, url} — products of ONE collection (meta.pagination for paging)

**Example request body:**
```json
{
  "store": "allbirds.com",
  "handle": "mens-tree-runner-go-utility-natural-black-dark-jungle"
}
```

### POST /shopify/v1/search — 1 credit
Predictive search across a Shopify store: matching products (title, price, variants, image) plus optional collection, page, and autocomplete query suggestions.

**Parameters:**
- `store` (string, required) — Shopify store domain or URL (e.g. allbirds.com or https://shop.example.com) — works for ANY Shopify-powered store.
- `query` (string, required) — What to search for in the store.
- `limit` (integer, optional, default 10) — Results per page (1–250; larger values are capped at 250).
- `page` (integer, optional, default 1) — Page number (1, 2, 3…).
- `max_items` (integer, optional) — Auto-walk pages until this many items are collected (overrides single-page mode; recommended when using filters).
- `resource_types` (string, optional) — Comma-separated suggest resources to include: product, collection, page, query (default product). 'query' returns the store's autocomplete search-term suggestions.
- `vendor` (string, optional) — Only products whose vendor/brand contains this text (filter, post-fetch).
- `product_type` (string, optional) — Only products whose type contains this text (filter, post-fetch).
- `tags` (string, optional) — Only products carrying at least one of these tags (comma-separated or a list; filter, post-fetch).
- `min_price` (number, optional) — Only products priced at or above this (store currency; post-fetch).
- `max_price` (number, optional) — Only products priced at or below this (store currency; post-fetch).
- `only_on_sale` (boolean, optional, default false) — Only products with at least one discounted variant.
- `only_in_stock` (boolean, optional, default false) — Only products with at least one available variant.

**Returns:** products[]{id, title, handle, vendor, type, tags[], description, options[], variants[]{id, title, price, sku, available, compare_at_price, on_sale, discount_percent, inventory}, images[], price_min, price_max, available, on_sale, max_discount_percent, featured_image, url} — predictive product matches for `query`; plus collections[], pages[], query_suggestions[] when requested via resource_types (meta.pagination for paging)

### POST /shopify/v1/recommendations — 1 credit
Related or complementary products that a Shopify store recommends for a given product — the store's own 'you may also like' / 'goes well with' set, same rich product shape.

**Parameters:**
- `store` (string, required) — Shopify store domain or URL (e.g. allbirds.com or https://shop.example.com) — works for ANY Shopify-powered store.
- `handle` (string, required) — Product handle — the slug in the product URL (…/products/<handle>); a full product URL also works.
- `intent` (enum, optional, default "related") — Which Shopify recommendation set to return. 'related' = similar products (works on every store); 'complementary' = goes-well-with picks (only on stores that configured Search & Discovery — falls back to related). [one of: related, complementary]
- `limit` (integer, optional, default 10) — How many recommended products to return (1–250).

**Returns:** products[]{id, title, handle, vendor, type, tags[], description, options[], variants[]{id, title, price, sku, available, compare_at_price, on_sale, discount_percent, inventory}, images[], price_min, price_max, available, on_sale, max_discount_percent, featured_image, url} — the store's recommended products for the given product (meta.intent shows which set was returned)

**Example request body:**
```json
{
  "store": "allbirds.com",
  "handle": "mens-tree-runner-go-utility-natural-black-dark-jungle",
  "limit": 4
}
```

### POST /shopify/v1/collection — 1 credit
Metadata for a single Shopify collection by handle: title, description, cover image, published/updated dates, and product count.

**Parameters:**
- `store` (string, required) — Shopify store domain or URL (e.g. allbirds.com or https://shop.example.com) — works for ANY Shopify-powered store.
- `handle` (string, required) — Collection handle — the slug in the collection URL (…/collections/<handle>). A full collection URL also works.

**Returns:** collection{id, title, handle, description, description_html, image, products_count, published_at, updated_at, url}

**Example request body:**
```json
{
  "store": "allbirds.com",
  "handle": "mens-tree-runner-go-utility-natural-black-dark-jungle"
}
```

### POST /shopify/v1/pages — 1 credit
Content pages published on a Shopify store (About, FAQ, Shipping, size guides, etc.): title, handle, URL, and HTML/plain-text body.

**Parameters:**
- `store` (string, required) — Shopify store domain or URL (e.g. allbirds.com or https://shop.example.com) — works for ANY Shopify-powered store.
- `page` (integer, optional, default 1) — Page number (1, 2, 3…).
- `limit` (integer, optional, default 50) — Items per page (1–250; larger values are capped at 250).
- `max_items` (integer, optional) — Auto-walk pages until this many items are collected (overrides single-page mode; recommended when using filters).

**Returns:** pages[]{id, title, handle, url, body_html, body_text, published_at, updated_at} (meta.pagination for paging)

**Example request body:**
```json
{
  "store": "allbirds.com"
}
```

### POST /shopify/v1/store_info — 1 credit
Rich profile for a Shopify store: name, currency, country/city, product & collection counts, accepted card brands, social links, myshopify domain, and platform confirmation.

**Parameters:**
- `store` (string, required) — Shopify store domain or URL (e.g. allbirds.com or https://shop.example.com) — works for ANY Shopify-powered store.

**Returns:** platform + store + name + domain + myshopify_domain + currency + money_format + country + city + province + ships_to_countries[] + published_products_count + published_collections_count + card_brands[] + socials[] + description + raw{}

**Example request body:**
```json
{
  "store": "allbirds.com"
}
```

## More
- Try it live, no code: https://reefapi.com/playground?engine=shopify
- Human docs page: https://reefapi.com/docs/shopify
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
