BuyWhere Products API

Product search, lookup, comparison, deals, and price history.

Operations 7

GET /products/search Search products by keyword with full-text search #
GET /products/{id}/price-history Historical price points for a product #
GET /products/deals Get discounted products sorted by discount percentage #
GET /products/compare Compare multiple products side-by-side #
GET /products/{id} Get a product by ID #
GET /products/{id}/prices Get price history for a product #
GET /products/{id}/similar Find similar products by embedding similarity #

Documentation

Specifications

Schemas & Data

Other Resources

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/buywhere:buywhere-products-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

buywhere-products-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: BuyWhere Product Catalog Products API
  version: '1'
  description: Agent-native product catalog API for Southeast Asia and US commerce. Search 370M+ products across Shopee, Lazada, Amazon, Walmart, FairPrice, Carousell, and 20+ e-commerce platforms. Compare prices, discover deals, and find best prices through REST or MCP.
servers:
- url: https://api.buywhere.ai/v1
tags:
- name: Products
paths:
  /products/search:
    get:
      summary: Search products by keyword with full-text search
      description: 'Public read endpoint: works without credentials at anonymous rate limits. Sending a Bearer API key raises limits to your tier (free tier: 10 requests/min, 10,000/day) and enables usage attribution.'
      operationId: searchProducts
      security: []
      parameters:
      - name: q
        in: query
        schema:
          type: string
        description: 'Keyword search query (full-text). Alias: query.'
      - name: query
        in: query
        schema:
          type: string
        description: Alias for q (accepted for agent convenience; prefer q).
      - name: deliver_to
        in: query
        schema:
          type: string
          enum:
          - SG
          - US
          - VN
          - TH
          - MY
          - ID
          - PH
        description: 'REQUIRED for buyer-facing use: ISO-3166 country of the end user (e.g. "SG", "US"). Ranks deliverable products first and prevents all-market scans. Prefer over country_code.'
      - name: domain
        in: query
        schema:
          type: string
        description: Filter by merchant platform (e.g. lazada, shopee)
      - name: region
        in: query
        schema:
          type: string
        description: Filter by region (sea, us, eu, au)
      - name: country_code
        in: query
        schema:
          type: string
          enum:
          - SG
          - US
          - VN
          - TH
          - MY
        description: 'Filter by ISO country code. When provided without an explicit `currency` param, the default currency is inferred (SG→SGD, US→USD, VN→VND, TH→THB, MY→MYR). `min_price`/`max_price` apply in the inferred currency. Default: SG.'
      - name: include_unshippable
        in: query
        schema:
          type: boolean
          default: true
        description: Include products not deliverable to deliver_to country (default true). Set to false to return only same-country products.
      - name: min_price
        in: query
        schema:
          type: number
        description: Minimum price in the active currency (inferred from country_code or explicit currency param)
      - name: max_price
        in: query
        schema:
          type: number
        description: Maximum price in the active currency (inferred from country_code or explicit currency param)
      - name: currency
        in: query
        schema:
          type: string
          default: SGD
        description: Explicit currency override. If omitted and country_code is set, currency is inferred from country_code.
      - name: compact
        in: query
        schema:
          type: boolean
          default: false
        description: Return minimal payload for AI agents. Adds normalized_price_usd field. Reduces response ~40%.
      - name: limit
        in: query
        schema:
          type: integer
          default: 20
          maximum: 100
      - name: offset
        in: query
        schema:
          type: integer
          default: 0
      - name: mode
        in: query
        schema:
          type: string
          enum:
          - keyword
          - semantic
          - hybrid
          default: keyword
        description: Search mode. `keyword` (default) is full-text search on the indexed search_vector. `semantic` embeds the query (flow-embed-1, 1024-dim) and searches the pgvector pool, and `hybrid` RRF-merges the FTS and semantic candidate ranks. If vector infrastructure is unavailable, `semantic` and `hybrid` fall back to the keyword path.
      responses:
        '200':
          description: Product list with meta (total, response_time_ms, cached, mode)
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          format: uuid
                          description: Unique product identifier
                        title:
                          type: string
                          description: Product title
                        price:
                          type: object
                          properties:
                            amount:
                              type: number
                            currency:
                              type: string
                          description: Current price object
                        merchant:
                          type: string
                          description: Merchant slug
                        url:
                          type: string
                          format: uri
                          description: Product page URL
                        image_url:
                          type: string
                          format: uri
                          description: Product image URL
                        country_code:
                          type: string
                          enum:
                          - SG
                          - US
                          - VN
                          - TH
                          - MY
                          description: ISO country code
                        category_path:
                          type: array
                          items:
                            type: string
                          description: Category hierarchy
                        updated_at:
                          type: string
                          format: date-time
                        click_url:
                          type: string
                          format: uri
                          description: BuyWhere tracked click URL
                        affiliate_disclosure:
                          type: string
                          description: Affiliate disclosure text
                        metadata:
                          type: object
                          description: Additional product metadata
                  meta:
                    type: object
                    properties:
                      total:
                        type: integer
                        description: Total matching products (approximate for large catalogs)
                      limit:
                        type: integer
                        description: Items returned per page
                      offset:
                        type: integer
                        description: Pagination offset
                      response_time_ms:
                        type: integer
                        description: Server processing time in milliseconds
                      cached:
                        type: boolean
                        description: Whether this response was served from cache
                      mode_used:
                        type: string
                        enum:
                        - keyword
                        - semantic
                        - hybrid
                        description: Search mode used
                      mode_used_engine:
                        type: string
                        description: Detailed engine description (e.g. "keyword (fts)")
                      has_more:
                        type: boolean
                        description: Whether more results are available
                      hint:
                        type: string
                        description: Usage guidance for agents (e.g. deliver_to recommendation)
                      degraded:
                        type: boolean
                        description: Whether the response is degraded due to upstream issues
                      status:
                        type: string
                        enum:
                        - ok
                        - degraded
                        description: Response status
                      emptiness_reason:
                        type: string
                        description: Why results are empty (e.g. timeout, no_match)
                      confidence:
                        type: string
                        enum:
                        - high
                        - medium
                        - low
                        description: Result confidence
                      diagnostic:
                        type: object
                        properties:
                          engine_status:
                            type: string
                          indexed_for_region:
                            type: boolean
                          category_recognized:
                            type: boolean
                          timed_out_stage:
                            type: string
                            description: Stage that timed out (catalog_search, offer_aggregation)
                          deliver_to_present:
                            type: boolean
                          rate_limit_remaining:
                            type:
                            - integer
                            - 'null'
                      degraded_kind:
                        type: string
                        description: Type of degradation (timeout, api_error, auth_failure)
                      degraded_reason:
                        type: string
                        description: Human-readable degradation reason
                      deliver_to:
                        type: string
                        description: Buyer delivery country used for ranking
                      deliver_to_inferred:
                        type: boolean
                        description: Whether deliver_to was inferred from country_code
                  search_mode:
                    type: object
                    description: 'Mode honesty: which engine the request asked for, which one actually ran, and why any fallback happened.'
                    properties:
                      requested_mode:
                        type:
                        - string
                        - 'null'
                        enum:
                        - keyword
                        - semantic
                        - hybrid
                        - null
                      executed_mode:
                        type: string
                        enum:
                        - keyword
                        - semantic
                        - hybrid
                      fallback_reason:
                        type:
                        - string
                        - 'null'
                        description: e.g. vector_error, query_embed_failed, vector_db_unavailable, sort_forces_keyword
        '400':
          description: Invalid query parameters (limit out of range, malformed country code, inverted or negative price range, unknown mode)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        example: invalid_request
                      message:
                        type: string
                      details:
                        type: array
                        items:
                          type: object
                          properties:
                            field:
                              type: string
                            issue:
                              type: string
        '429':
          description: Rate limit exceeded
      tags:
      - Products
  /products/{id}/price-history:
    get:
      summary: Historical price points for a product
      operationId: getPriceHistory
      security:
      - BearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
        description: BuyWhere product ID
      responses:
        '200':
          description: Price history series
          content:
            application/json:
              schema:
                type: object
        '401':
          description: Missing or invalid API key
      tags:
      - Products
  /products/deals:
    get:
      summary: Get discounted products sorted by discount percentage
      operationId: getDeals
      security:
      - BearerAuth: []
      parameters:
      - name: currency
        in: query
        schema:
          type: string
        description: 'ISO-4217 currency of the listings to return. Default: the currency of country_code, else of deliver_to, else SGD.'
      - name: country_code
        in: query
        schema:
          type: string
        description: 'Filter by ISO-3166 alpha-2 country code (alias: country). When set, only deals from that country are returned, in its currency unless currency is given.'
      - name: min_discount
        in: query
        schema:
          type: number
          default: 10
        description: Minimum discount percentage. Discounts of 80 percent or more are excluded as implausible list-price inflation, so useful values are 0-79.
      - name: limit
        in: query
        schema:
          type: integer
          default: 20
          maximum: 100
      - name: offset
        in: query
        schema:
          type: integer
          default: 0
      - name: deliver_to
        in: query
        schema:
          type: string
        description: 'Recommended for buyer-facing use: ISO-3166 country of the end user. Sets the market currency when currency is omitted and labels each item availability (local, ships_to_you, unavailable, unknown).'
      - name: include_unshippable
        in: query
        schema:
          type: boolean
          default: true
        description: With deliver_to, set false to drop items that cannot be delivered there (meta.total reflects the kept items).
      responses:
        '200':
          description: Discounted products with price, original_price, and discount_pct
        '401':
          description: Missing or invalid API key
      tags:
      - Products
  /products/compare:
    get:
      summary: Compare multiple products side-by-side
      operationId: compareProducts
      security:
      - BearerAuth: []
      parameters:
      - name: ids
        in: query
        required: true
        schema:
          type: string
        description: Comma-separated product IDs (2-10)
      responses:
        '200':
          description: Array of products with price, brand, rating, category_path
        '400':
          description: Fewer than 2 IDs provided
        '401':
          description: Missing or invalid API key
      tags:
      - Products
  /products/{id}:
    get:
      summary: Get a product by ID
      operationId: getProduct
      security:
      - BearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Product detail
        '404':
          description: Product not found
      tags:
      - Products
  /products/{id}/prices:
    get:
      summary: Get price history for a product
      operationId: getProductPrices
      security:
      - BearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: days
        in: query
        schema:
          type: integer
          default: 30
          maximum: 90
        description: Look-back window in days
      responses:
        '200':
          description: Price history with min/max/avg stats
        '404':
          description: Product not found
      tags:
      - Products
  /products/{id}/similar:
    get:
      summary: Find similar products by embedding similarity
      operationId: findSimilarProducts
      security:
      - BearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: UUID of the source product
      - name: limit
        in: query
        schema:
          type: integer
          default: 10
          minimum: 1
          maximum: 20
        description: Number of similar products to return
      responses:
        '200':
          description: Array of similar products with similarity scores
        '400':
          description: Invalid product id
        '404':
          description: Product not found
      tags:
      - Products
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
x-provenance:
  method: harvested
  publisher: BuyWhere
  source: https://api.buywhere.ai/openapi.json
  note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
    stamped by stamp-openapi-provenance.py (roadmap#793)