---
title: "Search product listings on Taobao / Tmall by keyword. Returns a normalized Product page."
method: POST
path: "/v2/ops/ecommerce.taobao.product.search"
tags: ["ecommerce/taobao"]
---

# Search product listings on Taobao / Tmall by keyword. Returns a normalized Product page.

`POST /v2/ops/ecommerce.taobao.product.search`

## Request

- Base URL: `https://api.agentkey.app`
- URL: `https://api.agentkey.app/v2/ops/ecommerce.taobao.product.search`
- Auth: HTTP bearer

Keyword search over product listings on Taobao / Tmall. Results are normalized to the Product object; page with next_cursor. The server picks the provider and fails over; the response names the provider that served it.

Fixed price: 4.4 credits per successful call, whichever provider serves it.

## Request body

- object
  - `cursor` string: Opaque pagination cursor from the previous response's next_cursor. Send the same query parameters with it.
  - `fields` string[]: Projection: keep only these dotted paths of data, e.g. ["items.id", "items.text"].
  - `include_raw` boolean: Attach the raw upstream payload as `raw` (not a stable contract; truncated above 256 KB).
  - `limit` integer: Maximum number of products to return.
  - `price_max` number: Highest selling price to include, in the platform's currency.
  - `price_min` number: Lowest selling price to include, in the platform's currency.
  - `provider` string: Shorthand for routing.only = [provider].
  - `query` string, required: Keyword or phrase to search for.
  - `routing` Routing: Provider routing override. order: try these providers first; only: restrict to these (equivalent to pinning); allow_fallbacks: false tries only the first eligible provider.
    - `allow_fallbacks` boolean: false = try only the first eligible provider.
    - `only` string[]: Restrict to these providers.
    - `order` string[]: Providers to try first, in order.
    - `strategy` 'auto': How eligible providers are ordered. auto = the method's curated order. fastest / stable / popular are specified but not implemented yet (400 until then). The price is fixed whatever the strategy; mutually exclusive with order.
  - `sort` 'general' | 'latest' | 'sales' | 'price_asc' | 'price_desc': general = the platform's default ranking; sales = best selling first; price_asc / price_desc = by selling price.
  - `tmall` boolean: true = only Tmall listings (search V1 filter).

## Response `200`

Success envelope

- ProductPageEnvelope: Success envelope whose data is a ProductPage.
  - `attempts` Attempt[], required
    - `error_type` string: validation | not_found | rate_limit | timeout | upstream_unauthorized | upstream_unavailable | provider_error
    - `provider` string, required: Provider slug.
    - `refunded` boolean: true when the reservation for this attempt was refunded.
    - `status` integer, required: HTTP status AgentKey mapped this attempt to (200 on success).
    - `took_ms` integer, required
    - `tool` string, required: Registry tool name (Provider/operation) that was called.
    - `upstream_status` integer: The provider's real HTTP status; absent when nothing was received.
  - `credits_charged` number, required: Credits charged for this call (the method's fixed price).
  - `data` object, required: One page of products.
    - `items` Product[], required
      - `brand` string, nullable, required: Brand name when the platform reports one.
      - `category` string, nullable, required: Platform category name (leaf) when reported.
      - `description` string, nullable, required: Listing description / selling points as plain text; null when the endpoint returns only a card.
      - `id` string, required: Platform-native product / item ID (ASIN on Amazon, item id on Taobao).
      - `image_url` string, nullable, required: Main listing image URL (the cover every search card carries).
      - `images` string[], nullable, required: Listing image URLs, main image first. null when the provider exposes no images at all.
      - `in_stock` boolean, nullable, required: Whether the listing is purchasable right now; null when not reported.
      - `monthly_sales_count` integer, nullable, required: Units sold in the past month when that is what the platform shows (Amazon's "500+ bought in past month" badge, Douyin Shop's "月销" on search cards and shop listings). Not comparable with sales_count.
      - `platform` string, required: Platform slug, identical to the one in the method name.
      - `price` object, required: Current price. amount is the displayed selling price; original_amount the struck-through list price when there is a discount.
        - `amount` number, nullable, required: Selling price in major units (12.5 = 12.50).
        - `currency` string, nullable, required: ISO 4217 currency code (CNY, USD, SGD …).
        - `original_amount` number, nullable, required: List / pre-discount price when shown; null otherwise.
      - `rating` object, required
        - `count` integer, nullable, required: Number of ratings / reviews.
        - `score` number, nullable, required: Average rating on the platform's own scale (Amazon 0–5, Taobao 0–5).
      - `sales_count` integer, nullable, required: Cumulative units sold / "已售" counter when the platform exposes one (approximate on platforms that report "1万+"). Platforms that only show a past-month figure report it in monthly_sales_count instead.
      - `sales_text` string, nullable, required: The platform's own sales line as displayed ("1万+人收货", "1.8K+ sold", "500+ bought in past month"); sales_count or monthly_sales_count is the number read from it.
      - `shop` object, required: The seller of the listing.
        - `id` string, nullable, required: Platform-native shop / seller ID.
        - `name` string, nullable, required: Shop display name.
        - `url` string, nullable, required: Shop page URL.
      - `title` string, required: Listing title.
      - `url` string, nullable, required: Canonical product page URL.
    - `next_cursor` string, nullable, required: Opaque cursor for the next page; null when the result set is exhausted or the provider cannot page. Send it back unchanged with the same query parameters.
  - `op` string, required: Method name.
  - `op_version` integer, required: Method version that served the call.
  - `provider` string, required: Provider that actually served the call.
  - `raw` unknown
  - `raw_truncated` boolean
  - `request_id` string, required: Correlation id; quote it in support requests.
  - `took_ms` integer, required
  - `unsupported_fields` string[], required: Output paths this provider structurally does not supply; such fields are null for a different reason than 'missing on this record'.

## Other responses

- `400`: Validation error (unknown field, bad cursor, bad routing)
- `402`: Insufficient credits
- `404`: Not found (method, or upstream object)
- `429`: Rate limited upstream
- `502`: All providers failed
- `504`: Timed out

---

[API](https://skmtc.dev/agentkey/apis/agentkey-scenario-methods.md) - [All operations](https://skmtc.dev/agentkey/apis/agentkey-scenario-methods/llms.txt) - [OpenAPI document](https://skmtc.dev/agentkey/apis/agentkey-scenario-methods/revisions/a7cf5b682fdd?raw)
