Blog
GuidesOct 27, 2026 9 min read

Amazon Price Monitoring with Python and DataBlue

Build an Amazon price monitor with Python: collect product observations, keep delivery context consistent, compare changes and budget DataBlue credits.

By DataBlue Team

You can build an Amazon price monitor by fetching a product's current price, saving a timestamped observation, and comparing it with the previous observation for the same product and delivery context. DataBlue provides the Amazon product data; your application supplies the schedule, price history and alerts.

This guide is for developers building product research or pricing workflows. It demonstrates one product at a time, using Python and the DataBlue Amazon Products API. It does not place orders, manage a seller account, or provide Amazon's historical prices retroactively.

Decide what you are comparing

Use a specific ASIN rather than a keyword search when following the same product over time. Search results can change order or return different products. Keep the Amazon domain, country and postal code fixed between observations, and keep product variants separate.

A displayed product price is not necessarily the final checkout total. Delivery charges, coupons, membership offers, tax treatment and seller changes can affect what a buyer pays. The example detects an observed price change; it does not prove that the same seller changed its price or that the item is available for every buyer.

For accepted inputs and response fields, see the Amazon Products API reference. To compare other supported marketplaces, use the e-commerce API directory.

Prepare your first request

Create a DataBlue account, get an API key from the dashboard and make sure the account has available credits. Install the Python requests package with python -m pip install requests. Set DATABLUE_API_KEY and AMAZON_ASIN in your environment; do not put the key into the script or source control.

The example uses amazon.com, US and postal code 10001. Replace the ASIN with a real product you want to observe. If you change marketplace, update the country and delivery context together and verify the returned product before collecting a series. An accepted location field alone is not proof of coverage for every product or address.

The request sends POST https://api.datablue.dev/v1/data/amazon/products with Authorization: Bearer YOUR_API_KEY and JSON containing asin, domain, country, postal_code, num_results=1 and detail_level=full. Full detail requests enrichment when available; individual fields can still be missing.

Fetch a product and save a price observation

Save the following as amazon_price_monitor.py. Each execution requests one product, handles a queued response, and appends a valid observation to a local JSONL file. It prints a change only when there is a previous observation with the same ASIN, marketplace, requested location and returned currency.

"""One observation per execution; scheduling and alerts belong to your app."""import jsonimport osimport timefrom datetime import datetime, timezonefrom decimal import Decimalfrom pathlib import Pathfrom uuid import UUIDimport requestsBASE = "https://api.datablue.dev"def fetch_product(session, payload):    response = session.post(BASE + "/v1/data/amazon/products", json=payload, timeout=330)    response.raise_for_status()    result = response.json()    if response.status_code == 202:        # Construct the polling URL locally; never forward credentials to an arbitrary URL.        job_id = str(UUID(result["job_id"]))        print("Queued job:", job_id, flush=True)        for _ in range(60):            time.sleep(5)            poll = session.get(BASE + "/v1/data/jobs/" + job_id, timeout=30)            poll.raise_for_status()            job = poll.json()            if job.get("status") in ("failed", "cancelled"):                raise RuntimeError("Job failed or was cancelled: " + str(job.get("error")))            if job.get("status") == "completed":                result = job.get("result") or {}                break        else:            raise TimeoutError("Polling stopped; inspect the recorded job ID before submitting again.")    if result.get("success") is not True or result.get("partial"):        raise RuntimeError("Incomplete result; inspect errors, quality and warnings before retrying.")    if result.get("warnings"):        print("Source warnings:", result["warnings"])    if result.get("domain") != payload["domain"]:        raise ValueError("Unexpected marketplace")    product = next((p for p in result.get("products", []) if p.get("asin") == payload["asin"]), None)    if product is None or product.get("price_value") is None or not product.get("currency"):        raise ValueError("No comparable price and currency; missing price is not zero.")    amount = Decimal(str(product["price_value"]))    if not amount.is_finite() or amount <= 0:        raise ValueError("Invalid product price")    return productdef record_observation(product, payload, path):    key = [payload["asin"], payload["domain"], payload["country"],           payload["postal_code"], product["currency"]]    prior = None    if path.exists():        for line in path.read_text(encoding="utf-8").splitlines():            row = json.loads(line)            if row["key"] == key:                prior = row    observation = {        "observed_at": datetime.now(timezone.utc).isoformat(),        "key": key,        "price": str(Decimal(str(product["price_value"]))),        "price_display": product.get("price"),        "in_stock": product.get("in_stock"),    }    with path.open("a", encoding="utf-8") as file:        file.write(json.dumps(observation) + "\n")    if prior and Decimal(prior["price"]) != Decimal(observation["price"]):        print("Observed price changed:", prior["price"], "->", observation["price"], product["currency"])    else:        print("Baseline saved" if prior is None else "Observed price unchanged")def main():    payload = {        "asin": os.environ["AMAZON_ASIN"].strip().upper(),        "domain": "amazon.com", "country": "US", "postal_code": "10001",        "num_results": 1, "detail_level": "full",    }    with requests.Session() as session:        session.headers["Authorization"] = "Bearer " + os.environ["DATABLUE_API_KEY"]        product = fetch_product(session, payload)    record_observation(product, payload, Path("amazon-price-history.jsonl"))if __name__ == "__main__":    main()

Run python amazon_price_monitor.py once to establish a baseline, then again at your chosen interval. Use one process and a persistent working directory for this small example. For concurrent workers or a large catalogue, use a database with unique observation IDs and concurrency controls instead of sharing this JSONL file.

The history begins when you start collecting. The timestamp records when your application received the data, not necessarily when Amazon changed the price. The example makes no freshness guarantee and does not bypass cache policy.

Handle missing prices and unfinished jobs

An HTTP 202 response means work is queued, not that a product has been retrieved. The script records the job ID and polls the native Data API status route. If polling expires, inspect that job before resubmitting; a client timeout does not establish that server-side work failed.

An HTTP 200 response alone is not enough either. Check success, partial, warnings, the expected ASIN, and the fields needed for your comparison. This example refuses partial results and missing or non-positive prices. A missing price must not become zero, and a missing in_stock value means unknown, not sold out.

The returned currency can be a symbol or a code. Preserve it and avoid comparing different currencies. The example requires identical currency strings; a production system should normalize currencies deliberately using marketplace context rather than treating every dollar symbol as the same currency.

If authentication fails, check the API key and account access. For rate limits or temporary errors, use bounded retries with backoff and inspect the response. Do not repeatedly resubmit POST requests without checking whether previous work completed.

Estimate the credit budget before scheduling

As checked on 28 October 2026, the live Amazon Products catalogue charges 7 credits per delivered product, with a block size of one product. This is a product-output unit, not a universal price per HTTP request. One request returning ten billed products would consume 70 credits under that rule.

For an illustrative schedule of 100 products checked four times per day for 30 days, the budget is 100 × 4 × 30 = 12,000 product observations. If each check delivers one billable product at the current weight, that is 84,000 credits. This is a planning calculation, not a measured usage result or a subscription recommendation.

The current rule bills delivered output on partial results, releases the charge on failures, makes zero-result responses free, and charges cached output at the full rate. A response your monitor rejects as unsuitable can still contain billable delivered output; application validation and billing are different checks.

Verify the live pricing catalogue and calculator before running a schedule. Rates can change. Effective dollar cost depends on the selected plan and how much of its included credit allowance you use; it is not a standalone pay-as-you-go quote.

Add a schedule and alerts in your application

Use your own scheduler, such as cron, Windows Task Scheduler or a job queue, to execute the script. Choose an interval based on your use case and budget. Prevent overlapping runs, retain the last successful observation, and track failures separately from valid price changes.

The example prints changes to the console. To send an alert, add your own email or webhook integration after validation. For stronger alerts, compare the same seller and variant where that information is available, require a meaningful price-change threshold, and recheck suspicious changes before acting on them. DataBlue does not provide the scheduling, history store or notification service in this example.

Common questions

Does this retrieve Amazon price history?

No. It builds a history from observations you collect from this point onward. It does not retrieve past prices from before the monitor started.

Is this Amazon's official seller API?

No. DataBlue is an independent hosted data service. This endpoint retrieves product data; it is not an Amazon seller-account integration and does not create or manage orders.

Can one request cover multiple products?

The current request schema supports an asins list of up to 50 direct product identifiers. Start with one product to validate the output, then handle missing or partial results per product when expanding. Billing follows delivered product units rather than the number of network requests.

Can the same approach work for other marketplaces?

The fetch, validate, save and compare pattern is reusable, but inputs, output fields, coverage and billing differ. Review each endpoint in the DataBlue API directory instead of reusing Amazon's payload unchanged.

Start with a small, verifiable watchlist

Test one known product against the same marketplace and delivery context you use in the browser. Confirm the product, currency and usable price, then collect a short series before expanding. Use the Amazon API reference for the contract and DataBlue pricing for the current credit budget.