V2 Streaming Endpoints
Subscribe to real-time product and price updates using Server-Sent Events (SSE).
Base URLs:
https://api.buywhere.ai/v2/products/streamhttps://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
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
category | string | No | - | Filter by category |
platform | string | No | - | Filter by source platform |
country | string | No | - | Filter by country |
min_price | number | No | - | Minimum price filter |
max_price | number | No | - | Maximum price filter |
in_stock | boolean | No | - | 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
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
product_ids | string | No | - | Comma-separated product IDs to monitor |
min_price | number | No | - | Minimum price filter |
max_price | number | No | - | Maximum price filter |
min_price_change_pct | number | No | 0 | Minimum % price change to report |
category | string | No | - | 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 Type | Description |
|---|---|
product_update | General product data update |
price_change | Price modification for a product |
stock_change | Inventory status change |
heartbeat | Keep-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
- V2 Search - Search products
- V2 Batch Details - Batch product lookup
- Agent Native Search - AI-optimized search