V2 Streaming Endpoints

Subscribe to real-time product and price updates using Server-Sent Events (SSE).

Base URLs:

  • https://api.buywhere.ai/v2/products/stream
  • https://api.buywhere.ai/v2/prices/stream

Overview

The streaming endpoints provide real-time feeds of product updates and price changes. These are ideal for dashboards, monitoring systems, and AI agents that need to track inventory and pricing changes.

Product Stream

Subscribe to real-time product updates.

GET /v2/products/stream

Query Parameters

ParameterTypeRequiredDefaultDescription
categorystringNo-Filter by category
platformstringNo-Filter by source platform
countrystringNo-Filter by country
min_pricenumberNo-Minimum price filter
max_pricenumberNo-Maximum price filter
in_stockbooleanNo-Filter by availability

cURL Example

curl -N "https://api.buywhere.ai/v2/products/stream?category=electronics" \
  -H "Authorization: Bearer bw_live_xxxxxxxxxxxxxxxx" \
  -H "Accept: text/event-stream"

Python Example

import httpx
import sseclient

API_KEY = "bw_live_xxxxxxxxxxxxxxxx"

with httpx.stream(
    "GET",
    "https://api.buywhere.ai/v2/products/stream",
    params={"category": "electronics"},
    headers={"Authorization": f"Bearer {API_KEY}"},
    timeout=None
) as response:
    client = sseclient.SSEClient(response)
    for event in client.events():
        if event.data:
            product = json.loads(event.data)
            print(f"Product update: {product['title']} - {product['price']}")

JavaScript Example

const API_KEY = "bw_live_xxxxxxxxxxxxxxxx";

const eventSource = new EventSource(
  `https://api.buywhere.ai/v2/products/stream?category=electronics`,
  {
    headers: { "Authorization": `Bearer ${API_KEY}` }
  }
);

eventSource.onmessage = (event) => {
  const product = JSON.parse(event.data);
  console.log(`Product update: ${product.title} - ${product.currency} ${product.price}`);
};

eventSource.onerror = (error) => {
  console.error("Stream error:", error);
};

Go Example

package main

import (
    "fmt"
    "io"
    "net/http"
)

func streamProducts(apiKey string) error {
    req, _ := http.NewRequest("GET", "https://api.buywhere.ai/v2/products/stream", nil)
    req.Header.Set("Authorization", "Bearer "+apiKey)
    req.Header.Set("Accept", "text/event-stream")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    reader := resp.Body
    buf := make([]byte, 4096)
    for {
        n, err := reader.Read(buf)
        if n > 0 {
            fmt.Printf("Received: %s\n", string(buf[:n]))
        }
        if err == io.EOF {
            break
        }
        if err != nil {
            return err
        }
    }
    return nil
}

Price Stream

Subscribe to real-time price change notifications.

GET /v2/prices/stream

Query Parameters

ParameterTypeRequiredDefaultDescription
product_idsstringNo-Comma-separated product IDs to monitor
min_pricenumberNo-Minimum price filter
max_pricenumberNo-Maximum price filter
min_price_change_pctnumberNo0Minimum % price change to report
categorystringNo-Filter by category

cURL Example

curl -N "https://api.buywhere.ai/v2/prices/stream?product_ids=18472931,18472932&min_price_change_pct=5" \
  -H "Authorization: Bearer bw_live_xxxxxxxxxxxxxxxx" \
  -H "Accept: text/event-stream"

Python Example

import httpx
import json

API_KEY = "bw_live_xxxxxxxxxxxxxxxx"

with httpx.stream(
    "GET",
    "https://api.buywhere.ai/v2/prices/stream",
    params={
        "product_ids": "18472931,18472932",
        "min_price_change_pct": 5
    },
    headers={"Authorization": f"Bearer {API_KEY}"},
    timeout=None
) as response:
    for line in response.iter_lines():
        if line.startswith("data:"):
            data = json.loads(line[5:])
            print(f"Price change: {data['product_id']} - {data['old_price']} -> {data['new_price']}")

JavaScript Example

const API_KEY = "bw_live_xxxxxxxxxxxxxxxx";

const url = new URL("https://api.buywhere.ai/v2/prices/stream");
url.searchParams.set("product_ids", "18472931,18472932");
url.searchParams.set("min_price_change_pct", "5");

const eventSource = new EventSource(url.toString(), {
  headers: { "Authorization": `Bearer ${API_KEY}` }
});

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log(`Price change: ${data.product_id} - ${data.old_price} -> ${data.new_price}`);
};

Go Example

package main

import (
    "bufio"
    "fmt"
    "net/http"
    "strings"
)

func streamPrices(apiKey string) error {
    req, _ := http.NewRequest("GET", "https://api.buywhere.ai/v2/prices/stream", nil)
    req.Header.Set("Authorization", "Bearer "+apiKey)
    req.Header.Set("Accept", "text/event-stream")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    scanner := bufio.NewScanner(resp.Body)
    for scanner.Scan() {
        line := scanner.Text()
        if strings.HasPrefix(line, "data:") {
            fmt.Printf("Price update: %s\n", strings.TrimPrefix(line, "data:"))
        }
    }
    return scanner.Err()
}

SSE Response Format

Both streaming endpoints use Server-Sent Events format:

event: product_update
data: {"id":18472931,"title":"iPhone 15 Pro","price":"1349.00","currency":"SGD","updated_at":"2026-04-15T12:00:00Z"}

event: price_change
data: {"product_id":18472931,"old_price":"1399.00","new_price":"1349.00","change_pct":-3.6}

Event Types

Event TypeDescription
product_updateGeneral product data update
price_changePrice modification for a product
stock_changeInventory status change
heartbeatKeep-alive ping (every 30 seconds)

Error Responses

401 Unauthorized

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}

Implementation Notes

  • Stream connections timeout after 5 minutes of inactivity
  • Clients should reconnect automatically on disconnect
  • Heartbeat events are sent every 30 seconds to keep connections alive
  • Maximum 10 concurrent stream connections per API key

Related Endpoints