← Back to documentation

API_DOCUMENTATION

BuyWhere API Documentation

Developer-facing documentation for the BuyWhere product catalog API. Target audience: AI agent developers integrating product search.


Getting Started

Overview

The BuyWhere API provides structured access to a product catalog spanning multiple Singapore and Southeast Asian e-commerce platforms. Built for AI agent workflows with features like batch lookups, confidence scoring, and real-time streaming.

Base URL

https://api.buywhere.ai

Quick Start

1. Get an API Key

Sign up at https://api.buywhere.ai/v1/developers/signup to receive your API key.

Your key will look like: bw_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2. Make Your First Request

curl -H "Authorization: Bearer bw_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
     "https://api.buywhere.ai/v2/search?q=iphone+15+pro&limit=5"

3. Understand the Response

{
  "query": "iphone 15 pro",
  "total": 1247,
  "limit": 5,
  "offset": 0,
  "has_more": true,
  "items": [
    {
      "id": 18472931,
      "sku": "IPHONE15PRO256",
      "source": "shopee_sg",
      "name": "iPhone 15 Pro 256GB Natural Titanium",
      "price": "1349.00",
      "currency": "SGD",
      "buy_url": "https://shopee.sg/product/...",
      "affiliate_url": "https://buywhere.ai/click/...",
      "image_url": "https://cf.shopee.sg/file/...",
      "brand": "Apple",
      "category": "Mobile Phones",
      "rating": "4.8",
      "review_count": 2341,
      "is_available": true,
      "confidence_score": 0.95,
      "data_freshness": "recent"
    }
  ]
}

Response Format

All API responses are JSON with consistent wrapper fields:

FieldTypeDescription
totalintegerTotal matching products
limitintegerResults per page
offsetintegerCurrent offset
has_morebooleanMore results available
itemsarrayArray of product objects

Product objects include these core fields:

FieldTypeDescription
idintegerUnique BuyWhere product ID
skustringProduct SKU from source
sourcestringPlatform source (e.g., shopee_sg, lazada_sg)
namestringProduct title
pricestringPrice as decimal string
currencystringISO currency code (SGD, MYR, THB, etc.)
buy_urlstringDirect link to product
affiliate_urlstringBuyWhere tracked link for commissions
image_urlstringProduct image URL
brandstringBrand name
categorystringProduct category
ratingstringAverage rating (0-5)
review_countintegerNumber of reviews
is_availablebooleanCurrently in stock
confidence_scorefloatData quality score (0-1)
data_freshnessstringfresh, recent, stale, very_stale

Authentication

API Key Authentication

All API requests require authentication via Bearer token or X-API-Key header.

Option 1: Authorization Header (Recommended)

curl -H "Authorization: Bearer bw_live_xxxxxxxx" \
     "https://api.buywhere.ai/v2/products/123"

Option 2: X-API-Key Header

curl -H "X-API-Key: bw_live_xxxxxxxx" \
     "https://api.buywhere.ai/v2/products/123"

Key Tiers

Tier PrefixRate LimitUse Case
bw_free_*60 req/minDemo, testing
bw_live_*600 req/minProduction
bw_partner_*UnlimitedPlatform data partners

Scopes

API keys support granular scopes:

ScopePermission
products:readRead product data
products:writeSubmit product updates
deals:readAccess deals endpoints
analytics:readView usage analytics
webhooks:manageCreate and manage webhooks

Key Rotation

Rotate your key without downtime:

POST /v1/keys/{id}/rotate

The old key remains valid for 24 hours during transition.


Rate Limits

Rate limits are enforced per API key and reset on a sliding window.

TierLimitWindow
Free60 requests1 minute
Live600 requests1 minute
PartnerUnlimited-

Rate Limit Headers

Response headers show your current limit status:

X-RateLimit-Limit: 600
X-RateLimit-Remaining: 547
X-RateLimit-Reset: 1713202500

Handling Rate Limits

When rate limited, the API returns 429 Too Many Requests:

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded",
    "details": {
      "retry_after": 60
    }
  }
}

Retry strategy: Use exponential backoff starting at 2 seconds.


Error Reference

HTTP Status Codes

CodeMeaningCause
200OKRequest succeeded
400Bad RequestMalformed request syntax
401UnauthorizedMissing or invalid API key
403ForbiddenValid key but insufficient scope
404Not FoundResource does not exist
422Unprocessable EntityValidation error in parameters
429Too Many RequestsRate limit exceeded
500Internal Server ErrorBuyWhere server error
503Service UnavailableTemporary downtime

Error Response Format

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable description",
    "details": {}
  }
}

Validation Errors (422)

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": {
      "errors": [
        {
          "field": "price_min",
          "message": "Value must be greater than or equal to 0",
          "type": "greater_than_equal"
        }
      ],
      "count": 1
    }
  }
}

Common Errors

MISSING_API_KEY

HTTP: 401
Cause: No API key provided
Fix: Add Authorization: Bearer <key> header

# Wrong
curl "https://api.buywhere.ai/v2/products"

# Correct
curl -H "Authorization: Bearer bw_live_xxx" \
     "https://api.buywhere.ai/v2/products"

INVALID_API_KEY

HTTP: 401
Cause: API key not found or revoked
Fix: Generate a new key at /v1/developers/signup

INVALID_CURSOR

HTTP: 400
Cause: Malformed pagination cursor
Fix: Re-fetch initial query to get a fresh cursor

INVALID_REGION

HTTP: 422
Cause: Invalid region parameter
Fix: Use us, sg, or sea

# Wrong
/v2/products?region=asiapacific

# Correct
/v2/products?region=sea

QUERY_TOO_LONG

HTTP: 422
Cause: Search query exceeds 500 characters
Fix: Shorten your search query

MAX_LIMIT_EXCEEDED

HTTP: 422
Cause: limit parameter exceeds maximum
Fix: Keep limit ≤ 100 for standard endpoints

UNSUPPORTED_CURRENCY

HTTP: 422
Cause: Currency code not supported
Fix: Use one of: SGD, MYR, THB, PHP, VND, USD

PRODUCT_NOT_FOUND

HTTP: 404
Cause: Product ID does not exist
Fix: Verify the product ID, or search for the product first

RATE_LIMIT_EXCEEDED

HTTP: 429
Cause: Too many requests in the current window
Fix: Wait retry_after seconds and retry with exponential backoff

INTERNAL_ERROR

HTTP: 500
Cause: Unexpected server error
Fix: Retry after 30 seconds. If persistent, contact support.


Agent-Native Features

The BuyWhere API includes features specifically designed for AI agent workflows.

Batch Lookups

Fetch multiple products in a single request:

POST /v2/products/batch-details
Content-Type: application/json
Authorization: Bearer bw_live_xxx

{
  "product_ids": [18472931, 18347291, 18234521]
}

Streaming Updates

Subscribe to real-time product updates via SSE:

GET /v2/products/stream?category=Mobile+Phones
Authorization: Bearer bw_live_xxx
Accept: text/event-stream

Price Change Stream

Monitor price changes for specific products:

GET /v2/prices/stream?product_ids=18472931,18347291&min_price_change_pct=5
Authorization: Bearer bw_live_xxx
Accept: text/event-stream

Confidence Score

Each product includes a confidence_score (0-1) indicating data quality:

  • 0.9-1.0: High confidence, complete data with image, rating, reviews
  • 0.7-0.9: Medium confidence, partial data
  • 0.5-0.7: Lower confidence, limited source data
  • <0.5: Minimal data, use with caution

Session Context

Pass session context for personalized results:

curl -H "X-Session-Context: eyJidWRnZXRfbWF4Ijo1MDAwLCJ0YXJnZXRfY3VycmVuY3kiOiJTR0QifQ==" \
     -H "Authorization: Bearer bw_live_xxx" \
     "https://api.buywhere.ai/v2/agents/search?q=headphones"

The header is base64-encoded JSON with fields:

  • budget_min, budget_max: Price range filter
  • target_currency: Preferred currency
  • preferred_sources: Comma-separated platform list

Code Examples

Python

import httpx

API_KEY = "bw_live_xxxxxxxxxxxxxxxx"
BASE_URL = "https://api.buywhere.ai"

headers = {"Authorization": f"Bearer {API_KEY}"}

# Search products
response = httpx.get(
    f"{BASE_URL}/v2/search",
    params={"q": "wireless headphones", "limit": 10},
    headers=headers
)
data = response.json()
print(f"Found {data['total']} products")

# Batch lookup
response = httpx.post(
    f"{BASE_URL}/v2/products/batch-details",
    json={"product_ids": [18472931, 18347291]},
    headers=headers
)
products = response.json()["products"]

JavaScript/Node.js

const API_KEY = "bw_live_xxxxxxxxxxxxxxxx";
const BASE_URL = "https://api.buywhere.ai";

const headers = { "Authorization": `Bearer ${API_KEY}` };

// Search products
const searchResponse = await fetch(
  `${BASE_URL}/v2/search?q=wireless+headphones&limit=10`,
  { headers }
);
const { total, items } = await searchResponse.json();
console.log(`Found ${total} products`);

// Batch lookup
const batchResponse = await fetch(
  `${BASE_URL}/v2/products/batch-details`,
  {
    method: "POST",
    headers: { ...headers, "Content-Type": "application/json" },
    body: JSON.stringify({ product_ids: [18472931, 18347291] })
  }
);
const { products } = await batchResponse.json();

cURL

# Search
curl "https://api.buywhere.ai/v2/search?q=laptop&limit=5" \
  -H "Authorization: Bearer bw_live_xxx"

# Batch lookup
curl -X POST "https://api.buywhere.ai/v2/products/batch-details" \
  -H "Authorization: Bearer bw_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"product_ids": [18472931, 18347291]}'

# Price comparison
curl "https://api.buywhere.ai/v2/agents/price-comparison?product_name=iphone+15" \
  -H "Authorization: Bearer bw_live_xxx"