BuyWhere Product Catalog API

Agent-native REST and MCP product catalog covering 1.5M+ products across Southeast Asian and US e-commerce platforms. Operations include keyword search, side-by-side comparison, deals discovery, price history, and category browsing. Responses are Schema.org-compatible (Product, Offer, ItemList) and include normalized structured_specs and comparison_attributes so LLMs can rank and reason without scraping. Same operations are exposed to MCP clients at api.buywhere.ai/mcp.

Documentation

Specifications

Examples

Schemas & Data

Other Resources

OpenAPI Specification

buywhere-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: BuyWhere Product Catalog API
  version: '1'
  description: |
    Agent-native product catalog API for Southeast Asia and US commerce. Search 1.5M+
    products across Shopee, Lazada, Amazon, Walmart, FairPrice, Carousell, Best Denki,
    and 20+ e-commerce platforms. Compare prices, discover deals, and find best prices
    through REST or MCP (Model Context Protocol).

    Responses are structured for LLM and agent consumption (Schema.org-compatible
    `Product` / `Offer` / `ItemList` shapes). Each product carries normalized
    `structured_specs` (brand, model, size, color) and `comparison_attributes`
    so agents can reason and rank without scraping.

    BuyWhere is MCP-native — the same operations are exposed at
    `POST https://api.buywhere.ai/mcp` for MCP-compatible clients, with a hosted
    HTTP transport and a published `@buywhere/mcp-server` STDIO package.
  contact:
    name: BuyWhere API
    email: [email protected]
    url: https://api.buywhere.ai/
  termsOfService: https://buywhere.ai/terms
  license:
    name: Commercial
    url: https://buywhere.ai/terms
servers:
  - url: https://api.buywhere.ai/v1
    description: Production REST API
tags:
  - name: Authentication
    description: Agent registration and API key issuance.
  - name: Products
    description: Product search, lookup, comparison, deals, and price history.
  - name: Categories
    description: Product taxonomy and category browsing.
  - name: MCP
    description: Model Context Protocol surface (see /mcp endpoint and docs).
paths:
  /auth/register:
    post:
      summary: Register Agent And Issue API Key
      description: Register an AI agent (or application) and receive a Bearer API key with a free-tier rate limit allocation.
      operationId: registerAgent
      tags:
        - Authentication
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentRegistration'
            example:
              agent_name: shopping-copilot
              contact: [email protected]
              use_case: Price comparison assistant for Singapore consumers.
      responses:
        '201':
          description: API key issued for the agent.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiKeyIssue'
              example:
                api_key: bw_free_2f7a9c0b1d8e4f3a9c0b1d8e4f3a9c0b
                tier: free
                rate_limit:
                  rpm: 60
                  daily: 1000
        '400':
          $ref: '#/components/responses/BadRequest'
  /products/search:
    get:
      summary: Search Products By Keyword
      description: Full-text search across the BuyWhere catalog with filters for merchant platform, region, country, price range, and currency. Set `compact=true` for an LLM-optimized payload.
      operationId: searchProducts
      tags:
        - Products
      security:
        - BearerAuth: []
      parameters:
        - name: q
          in: query
          schema:
            type: string
          description: Keyword search query (full-text).
          example: wireless headphones
        - name: domain
          in: query
          schema:
            type: string
          description: Filter by merchant platform (e.g. `lazada`, `shopee`, `amazon`, `walmart`, `carousell`).
          example: shopee
        - name: region
          in: query
          schema:
            type: string
            enum: [sea, us, eu, au]
          description: Filter by region.
        - 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: min_price
          in: query
          schema:
            type: number
          description: Minimum price in the active currency.
        - name: max_price
          in: query
          schema:
            type: number
          description: Maximum price in the active currency.
        - 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 a minimal payload for AI agents (id, title, price, currency, url, structured_specs, comparison_attributes).
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        '200':
          description: Product list with meta (total, response_time_ms, cached).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductList'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /products/deals:
    get:
      summary: List Discounted Products By Discount Percentage
      description: Returns products sorted by discount percentage, filtered by minimum discount, currency, and country.
      operationId: getDeals
      tags:
        - Products
      security:
        - BearerAuth: []
      parameters:
        - name: currency
          in: query
          schema:
            type: string
            default: SGD
        - name: country_code
          in: query
          schema:
            type: string
            enum: [SG, US, VN, TH, MY]
          description: When set, only deals from that country are returned.
        - name: min_discount
          in: query
          schema:
            type: number
            default: 10
          description: Minimum discount percentage (0–90).
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        '200':
          description: Discounted products with `price`, `original_price`, and `discount_pct`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DealList'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /products/compare:
    get:
      summary: Compare Multiple Products Side-By-Side
      description: Compare 2–10 products side-by-side with normalized price, brand, rating, and category path.
      operationId: compareProducts
      tags:
        - Products
      security:
        - BearerAuth: []
      parameters:
        - name: ids
          in: query
          required: true
          schema:
            type: string
          description: Comma-separated product IDs (2–10).
          example: 8a2c3a8e-1234-5678-9abc-def012345678,9b3d4b9f-2345-6789-abcd-ef0123456789
      responses:
        '200':
          description: Array of products with comparison-ready attributes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompareResponse'
        '400':
          description: Fewer than 2 IDs provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /products/{id}:
    get:
      summary: Get Product By ID
      description: Returns the full product detail including title, description, price, merchant, structured specs, and Schema.org-compatible metadata.
      operationId: getProduct
      tags:
        - Products
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Product detail.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '404':
          $ref: '#/components/responses/NotFound'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /products/{id}/prices:
    get:
      summary: Get Product Price History
      description: Returns price history (with min/max/avg stats) over a configurable look-back window.
      operationId: getProductPrices
      tags:
        - Products
      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.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PriceHistory'
        '404':
          $ref: '#/components/responses/NotFound'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /categories:
    get:
      summary: List Top-Level Product Categories
      description: List top-level product categories with slug, name, and product count.
      operationId: listCategories
      tags:
        - Categories
      security:
        - BearerAuth: []
      parameters:
        - name: currency
          in: query
          schema:
            type: string
            default: SGD
      responses:
        '200':
          description: Category list with slug, name, and product_count.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CategoryList'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /categories/{slug}:
    get:
      summary: Get Products Within A Category
      description: Returns products in the specified category along with any subcategories.
      operationId: getCategoryProducts
      tags:
        - Categories
      security:
        - BearerAuth: []
      parameters:
        - name: slug
          in: path
          required: true
          schema:
            type: string
          description: Category slug (from `/categories`).
        - name: currency
          in: query
          schema:
            type: string
            default: SGD
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        '200':
          description: Category detail with subcategories and products.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CategoryDetail'
        '404':
          $ref: '#/components/responses/NotFound'
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: |
        Pass your API key as a Bearer token. Get a free key at `POST /v1/auth/register`.
        Tiers: `bw_free_*` (60 rpm), `bw_live_*` (600 rpm), `bw_partner_*` (unlimited).
  responses:
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Resource not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    BadRequest:
      description: Invalid request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: Rate limit exceeded. Implement exponential backoff and respect `Retry-After`.
      headers:
        Retry-After:
          schema:
            type: integer
          description: Seconds to wait before retrying.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    AgentRegistration:
      type: object
      required:
        - agent_name
      properties:
        agent_name:
          type: string
          description: Name or identifier of your agent.
        contact:
          type: string
          format: email
          description: Contact email (optional).
        use_case:
          type: string
          description: Brief description of your use case.
    ApiKeyIssue:
      type: object
      properties:
        api_key:
          type: string
          description: Bearer token (prefixed with `bw_free_`, `bw_live_`, or `bw_partner_`).
        tier:
          type: string
          enum: [free, live, partner]
        rate_limit:
          type: object
          properties:
            rpm:
              type: integer
              description: Requests per minute.
            daily:
              type: integer
              description: Daily request quota.
    Product:
      type: object
      description: Schema.org-compatible product representation.
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        description:
          type: string
        brand:
          type: string
        domain:
          type: string
          description: Source merchant platform (lazada, shopee, amazon, walmart, etc.).
        url:
          type: string
          format: uri
          description: Canonical merchant product URL.
        image_url:
          type: string
          format: uri
        price:
          type: number
        original_price:
          type: number
        discount_pct:
          type: number
        currency:
          type: string
          example: SGD
        country_code:
          type: string
          example: SG
        rating:
          type: number
        review_count:
          type: integer
        category_path:
          type: array
          items:
            type: string
        structured_specs:
          type: object
          description: Normalized structured attributes (brand, model, size, color, etc.).
          additionalProperties: true
        comparison_attributes:
          type: object
          description: Attributes pre-normalized for agent comparison reasoning.
          additionalProperties: true
        normalized_price_usd:
          type: number
        availability:
          type: string
          enum: [in_stock, out_of_stock, preorder, limited]
        updated_at:
          type: string
          format: date-time
    ProductList:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Product'
        meta:
          type: object
          properties:
            total:
              type: integer
            response_time_ms:
              type: integer
            cached:
              type: boolean
            limit:
              type: integer
            offset:
              type: integer
    Deal:
      allOf:
        - $ref: '#/components/schemas/Product'
        - type: object
          properties:
            discount_pct:
              type: number
              description: Discount percentage (0–90).
    DealList:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Deal'
        meta:
          type: object
          properties:
            total:
              type: integer
            response_time_ms:
              type: integer
    CompareResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Product'
        meta:
          type: object
          properties:
            count:
              type: integer
    PricePoint:
      type: object
      properties:
        date:
          type: string
          format: date
        price:
          type: number
        currency:
          type: string
    PriceHistory:
      type: object
      properties:
        id:
          type: string
          format: uuid
        currency:
          type: string
        days:
          type: integer
        points:
          type: array
          items:
            $ref: '#/components/schemas/PricePoint'
        stats:
          type: object
          properties:
            min:
              type: number
            max:
              type: number
            avg:
              type: number
            current:
              type: number
    Category:
      type: object
      properties:
        slug:
          type: string
        name:
          type: string
        product_count:
          type: integer
        parent_slug:
          type: string
          nullable: true
    CategoryList:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Category'
    CategoryDetail:
      type: object
      properties:
        category:
          $ref: '#/components/schemas/Category'
        subcategories:
          type: array
          items:
            $ref: '#/components/schemas/Category'
        products:
          type: array
          items:
            $ref: '#/components/schemas/Product'
        meta:
          type: object
          properties:
            total:
              type: integer
            limit:
              type: integer
            offset:
              type: integer
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum: [invalid_params, not_found, rate_limited, unauthorized, internal_error]
            message:
              type: string
            request_id:
              type: string
externalDocs:
  description: BuyWhere developer documentation and MCP guide
  url: https://api.buywhere.ai/docs/guides/mcp