DEV Community

BuyWhere
BuyWhere

Posted on

Add price drop alerts to any app using the BuyWhere API

If your app already helps users discover products, the next useful feature is usually not more search. It is memory.

Users do not just want to know what a product costs right now. They want to know when it gets cheaper.

That makes price drop alerts a strong fit for BuyWhere, the definitive product catalog for AI agents. You can use the same product search endpoint you already call for discovery, run it on an interval, compare the latest price to a saved baseline, and trigger an alert when the delta crosses your threshold.

This tutorial shows the simplest production-shaped version of that workflow:

  • search for products with BuyWhere
  • store the product and starting price your user wants to track
  • poll BuyWhere on a schedule
  • compare the latest price against the stored baseline
  • send an email, push notification, Slack message, or in-app alert when the price falls

The canonical endpoint is:

GET /v1/products/search

Why this matters for developers

Price alerts are a strong retention feature because they turn one search session into an ongoing workflow.

Instead of forcing users to check the same product manually, your app can:

  • remember what they care about
  • monitor price movement for them
  • bring them back only when the timing is better

The important part is that you do not need a second integration surface to build this. BuyWhere can handle both discovery and monitoring through the same search API.

The core pattern

The implementation is intentionally simple:

  1. your user chooses a product to track
  2. your app stores the current price as a baseline
  3. a scheduled job reruns the same BuyWhere search
  4. your app finds the matching product and compares the latest price
  5. if the drop is large enough, your app sends the alert

BuyWhere handles product retrieval. Your application handles state and notifications.

Search for the tracked product

Start with the same request you would use for product discovery:

curl -sS "https://api.buywhere.ai/v1/products/search?q=airpods+pro&country_code=SG&limit=5" \
  -H "Authorization: Bearer $BUYWHERE_API_KEY"
Enter fullscreen mode Exit fullscreen mode

For alert workflows, the most useful fields in the response are:

  • id
  • title
  • price
  • domain
  • url
  • country_code

Save a baseline in your app

For a first implementation, store:

  • the user id
  • the BuyWhere product id
  • the original query
  • the country code
  • the merchant domain if you want merchant-specific tracking
  • the baseline price
  • the drop threshold
  • the notification channel

Example:

{
  "user_id": "user_123",
  "product_id": "bw_sg_12345",
  "query": "airpods pro",
  "country_code": "SG",
  "domain": "lazada.sg",
  "baseline_price": 349.0,
  "target_drop_amount": 20.0,
  "notification_channel": "email"
}
Enter fullscreen mode Exit fullscreen mode

Prefer BuyWhere id for matching. If you cannot store it yet, use the original query, narrow with domain, and fall back to url matching carefully.

Python example

import os
from dataclasses import dataclass

import requests


API_KEY = os.environ["BUYWHERE_API_KEY"]
BASE_URL = "https://api.buywhere.ai"


@dataclass
class TrackedItem:
    user_id: str
    product_id: str
    query: str
    country_code: str
    domain: str
    baseline_price: float
    target_drop_amount: float
    notification_channel: str


def search_products(query: str, country_code: str, domain: str, limit: int = 10):
    response = requests.get(
        f"{BASE_URL}/v1/products/search",
        headers={"Authorization": f"Bearer {API_KEY}"},
        params={
            "q": query,
            "country_code": country_code,
            "domain": domain,
            "limit": limit,
        },
        timeout=15,
    )
    response.raise_for_status()
    return response.json().get("data", [])


def find_tracked_product(products, product_id):
    for product in products:
        if product.get("id") == product_id:
            return product
    return None


def should_alert(baseline_price: float, current_price: float, target_drop_amount: float):
    return baseline_price - current_price >= target_drop_amount


def send_alert(item: TrackedItem, product: dict):
    print(
        f"[alert] user={item.user_id} "
        f"title={product['title']} "
        f"old_price={item.baseline_price} "
        f"new_price={product['price']} "
        f"url={product['url']}"
    )


def check_price_drop(item: TrackedItem):
    products = search_products(
        query=item.query,
        country_code=item.country_code,
        domain=item.domain,
    )
    product = find_tracked_product(products, item.product_id)

    if not product:
        return

    current_price = float(product["price"])

    if should_alert(item.baseline_price, current_price, item.target_drop_amount):
        send_alert(item, product)


tracked_item = TrackedItem(
    user_id="user_123",
    product_id="bw_sg_12345",
    query="airpods pro",
    country_code="SG",
    domain="lazada.sg",
    baseline_price=349.0,
    target_drop_amount=20.0,
    notification_channel="email",
)

check_price_drop(tracked_item)
Enter fullscreen mode Exit fullscreen mode

That example prints an alert, but the same hook can trigger email, push, Slack, Discord, or an in-app notification.

JavaScript example

If your app backend is JavaScript or TypeScript, the pattern is the same:

const apiKey = process.env.BUYWHERE_API_KEY;

async function searchProducts({ query, countryCode, domain, limit = 10 }) {
  const params = new URLSearchParams({
    q: query,
    country_code: countryCode,
    domain,
    limit: String(limit),
  });

  const response = await fetch(
    `https://api.buywhere.ai/v1/products/search?${params.toString()}`,
    {
      headers: {
        Authorization: `Bearer ${apiKey}`,
      },
    }
  );

  if (!response.ok) {
    throw new Error(`BuyWhere request failed: ${response.status}`);
  }

  const payload = await response.json();
  return payload.data ?? [];
}

function shouldAlert(baselinePrice, currentPrice, targetDropAmount) {
  return baselinePrice - currentPrice >= targetDropAmount;
}

async function checkPriceDrop(trackedItem) {
  const products = await searchProducts({
    query: trackedItem.query,
    countryCode: trackedItem.countryCode,
    domain: trackedItem.domain,
  });

  const product = products.find((item) => item.id === trackedItem.productId);
  if (!product) return;

  if (
    shouldAlert(
      trackedItem.baselinePrice,
      Number(product.price),
      trackedItem.targetDropAmount
    )
  ) {
    console.log({
      userId: trackedItem.userId,
      title: product.title,
      oldPrice: trackedItem.baselinePrice,
      newPrice: product.price,
      url: product.url,
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

That is enough to drop into a Next.js route, Express worker, serverless cron job, or queue consumer.

Decide what counts as a price drop

The simplest rule is:

  • alert when baseline_price - current_price >= threshold

Example:

  • baseline 349
  • current price 329
  • threshold 20
  • result: send the alert

This keeps the logic predictable and avoids noisy notifications from tiny price changes.

Prevent duplicate alerts

A scheduled job will keep finding the same lower price unless you store alert history.

A simple first fix is to record:

  • last_alerted_price
  • last_alerted_at
  • status

Then only re-alert when the price drops again beyond the last alerted price, or when the item has never been alerted before.

Run it on a schedule

You can start with:

  • cron
  • a background worker
  • a serverless scheduler
  • GitHub Actions for a prototype

Example cron entry:

0 * * * * /usr/bin/python3 /path/to/check_price_drops.py
Enter fullscreen mode Exit fullscreen mode

Hourly or daily checks are enough for a first release.

The user-facing message

Your alert should tell the user:

  • what changed
  • how much they can save now
  • where to go next

Example:

Price drop detected: AirPods Pro is now SGD 329, down from SGD 349.
Buy now: https://lazada.sg/products/airpods-pro
Enter fullscreen mode Exit fullscreen mode

That is enough to turn BuyWhere search into a retention loop instead of a one-time lookup.

Start with one narrow workflow

Do not overbuild version one.

Start with:

  • one product per alert
  • one notification channel
  • one simple threshold rule
  • one scheduled polling job

If you already have BuyWhere search working, price drop alerts are a straightforward next step.

Get your API key and quickstart at buywhere.ai/developers/.

Top comments (0)