---
title: "Search"
description: "按关键词跨 Shopify 店铺搜索商品，支持价格、评分、成色和库存过滤。"
---

> Every apinoa docs page as markdown: https://apinoa.com/llms.txt (all in one file: https://apinoa.com/llms-full.txt; this API family in one file: https://apinoa.com/docs/marketplace/llms.txt)

```http
GET | POST /v1/shopify/search
```

参数可以用 `GET` 的查询字符串发送，也可以用 `POST` 的 JSON 请求体发送，两者等价。

## 请求

```bash tab="cURL"
curl "https://gateway.apinoa.com/v1/shopify/search?query=running+shoes" \
  -H "x-api-key: $APINOA_API_KEY"
```

```js tab="JavaScript"
const params = new URLSearchParams({ query: "running shoes" });
const res = await fetch(`https://gateway.apinoa.com/v1/shopify/search?${params}`, {
  headers: { "x-api-key": process.env.APINOA_API_KEY },
});
const { success, data, error } = await res.json();
```

```python tab="Python"
import os

import requests

res = requests.get(
    "https://gateway.apinoa.com/v1/shopify/search",
    params={"query": "running shoes"},
    headers={"x-api-key": os.environ["APINOA_API_KEY"]},
)
body = res.json()
```

## 参数

| Parameter | Type | Required | Notes |
|---|---|---|---|
| `query` | string | yes | Keywords to search for. Required: Shopify search always needs a keyword, which is also why Shopify has no keyword-less `browse`. |
| `categoryId` | string |  | Narrow to one category, by the marketplace's own id. Opaque and per-marketplace; take it from Product.category[].id or from a result's `facets`. |
| `condition` | enum |  | Item condition: `new` or `used`. `refurbished` is refused by name rather than folded into `used` — the catalog sells new and secondhand, and those are different claims. `new` `used` |
| `cursor` | string |  | Opaque; comes from the previous response and carries the page index. Shopify pages by cursor rather than by number — this is the only paging knob, and `page` is refused by name. |
| `inStock` | boolean \| enum |  | Only listings the marketplace reports as purchasable now. |
| `priceMax` | number ≥ 0 |  | Highest price to return, in decimal major units. |
| `priceMin` | number ≥ 0 |  | Lowest price to return, in decimal major units. |
| `ratingMin` | number 0–5 |  | Lowest average star rating to return, on the marketplace's own 0-5 scale. |
| `region` | string |  | Buyer country as ISO 3166-1 alpha-2; sets availability, shipping and price. |

The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json

## 响应

在 `data` 中返回 [`SearchResult`](/docs/api-reference/marketplaces/response-schema#searchresult)。 真实响应的节选：数组只保留前几项，长文本已截断。

```json
{
  "success": true,
  "data": {
    "marketplace": "shopify",
    "query": "running shoes",
    "page": {
      "index": 1,
      "size": 50,
      "total": 235
    },
    "items": [
      {
        "marketplace": "shopify",
        "id": "startfitness.co.uk/adidas-adizero-evo-sl-mens-running-shoes-white",
        "attributes": [
          {
            "name": "Weight",
            "value": "224 g ± 9 g (size UK 8.5)"
          },
          {
            "name": "Midsole Drop",
            "value": "6 mm"
          }
        ],
        "title": "adidas Adizero EVO SL Mens Running Shoes - White",
        "url": "https://startfitness.co.uk/products/adidas-adizero-evo-sl-mens-running-shoes-white?variant=44383311691984",
        "price": {
          "currency": "USD",
          "amount": 171
        },
        "rating": {
          "average": 4.8
        },
        "seller": {
          "id": "startfitness.co.uk",
          "name": "Start Fitness",
          "url": "https://startfitness.co.uk"
        },
        "inStock": true,
        "imageUrl": "https://cdn.shopify.com/s/files/1/0564/9521/0704/files/adidas-Adizero-Evo-SL-JH6206.jpg",
        "badges": [],
        "promotions": []
      }
    ],
    "cursor": "eyJjIjoiZXlKdlptWnpaWFFpT2pVd0xDSjBiM1JoYkY5amIzVnVkQ0k2TWpNMUxDSnlaWFIxY201bFpDSTZOVEI5IiwiaSI6MiwiaCI6IkhnMUNENHV3REJ…",
    "facets": []
  }
}
```

## 错误

| 状态 | 代码 | 含义 |
|---|---|---|
| 400 | `INVALID_CURSOR` | 该 `cursor` 不是本操作返回的。请不带它重新开始。 |
| 400 | `INVALID_PARAMS` | 参数缺失、未知或超出范围。消息中会指出是哪一个。 |
| 401 | `UNAUTHORIZED` | 缺少 `x-api-key` 请求头，或密钥已吊销或未知。 |
| 402 | `INSUFFICIENT_BALANCE` | 余额不足以支付本次调用。请在控制台充值。 |
| 429 | `MARKETPLACE_SATURATED` | 并发调用过多。请等待 `Retry-After` 秒后重试。 |
| 502 | `UPSTREAM_ERROR` | 平台返回了无法使用的内容。请退避后重试。 |

全部错误代码见 [Errors](/docs/errors)。失败的调用不计费。

## 价格

**Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day.

## 说明

- **结果来自许多相互独立的店铺。** 每个条目的 `id` 为 `shop/handle`，可衔接到 [Product](/docs/api-reference/shopify/product) 和 [Reviews](/docs/api-reference/shopify/reviews)。
- **按 `cursor` 分页。** 传入上一次响应的 `cursor`；`page` 会被拒绝。每页最多 50 条，因此没有 `pageSize`。
- **没有 `sort`，也没有 `brands`。** Shopify 搜索两者都不提供。
- **没有 `currency`。** 价格跟随 `region`。
- **`condition=refurbished` 会被拒绝**，而不是映射为 `used`：该商品库只区分 `new` 和 `secondhand`。
