ScreenshotNeo

BlogHow-to

How to Track Amazon Prices Automatically for Competitive Intelligence

Choose the right Amazon price data source, automate collection and alerts, and avoid misleading comparisons from stale or mismatched offers.

By the ScreenshotNeo team4 October 202611 min read

To track Amazon prices automatically for competitive intelligence, first choose a source that matches the data you need: Amazon’s seller-facing Selling Partner API (SP-API) for defined pricing and offer signals, a provider such as Keepa for marketplace offer histories and threshold alerts, or Amazon’s price-history feature for a quick shopper-facing view. Collect observations with timestamps and marketplace context, compare equivalent offers, and treat gaps as unknown. Amazon Automate Pricing is for changing your own offer price under rules; it is not a general competitor-history database.

This guide focuses on collecting and interpreting price intelligence. Screenshots can preserve visual evidence of a listing, but they do not replace structured price data or establish a complete history.

1. Define what “price” means for your decision

Before choosing an API or setting an alert, decide which product and offer you are measuring. An ASIN-level competitive signal, a particular seller’s offer, and the SKU you sell are different targets.

  • Product identity: ASIN, variant, pack size, and marketplace.
  • Offer identity: seller, condition, fulfillment method, and Prime status when available.
  • Effective price: item price, shipping, coupon, and other discounts that matter to your comparison.
  • Decision: monitor a competitor, evaluate market position, or change your own price.

Normalize like for like. A multipack and a single unit are not equivalent just because the listing titles look similar. Amazon’s competitive external price can account for unit pricing across different pack sizes and may use near-identical products as comparables, which makes product matching part of the analysis rather than a cleanup detail. [Amazon pricing FAQ]

2. Choose a source that fits the question

Need Starting point Limits to check
Current seller-facing offer and competitive signals Amazon SP-API Product Pricing API Seller eligibility, Pricing role, marketplace and region, signal definitions, ASIN/SKU coverage, and integration work.
Historical marketplace offers and threshold alerts A provider such as Keepa Marketplace coverage, data freshness, history gaps, offer selection, API limits and price, notification delivery, and permitted use.
Quick shopper-facing view of recent price movement Amazon price-history feature Country availability, product-page support, and history period currently shown.
Rule-based changes to your own price Amazon Automate Pricing Professional selling account, active offer, rule and price limits, and the outcomes you need to monitor.

These options do not expose the same data. Amazon lists its Product Pricing API as seller-only. It provides defined offer and pricing signals; it is not documented as unrestricted access to all historical competitor prices. Keepa documents marketplace offer and history data, with caveats about stale or incomplete offers and gaps. Amazon’s customer price-history feature is a viewing aid. Automate Pricing executes seller-defined repricing rules. [Amazon Product Pricing API] [Keepa Marketplace Offer Object] [Amazon price-history feature] [Amazon Automate Pricing]

3. Automate collection and preserve observations

Use pull operations for scheduled snapshots and event or notification signals where the source supports them. Amazon documents Product Pricing operations and notifications such as ANY_OFFER_CHANGED and PRICE_HEALTH; Keepa documents threshold tracking and API notification delivery. These signals can complement snapshots, but a single current response does not create a complete history. [Amazon Product Pricing API and Notifications FAQ] [Keepa Tracking Creation Object]

  1. Choose the data source and confirm the applicable role, account, marketplace, terms, and usage limits.
  2. Set the target products and offer criteria. Record marketplace and currency with every observation.
  3. Schedule collection at a cadence appropriate to the decision. Use notifications for timely signals where available, and snapshots for analysis over time.
  4. Store the raw response or relevant fields, the observation timestamp, and the source. Do not overwrite previous observations.
  5. Validate freshness and gaps. Mark absent or stale data unknown instead of carrying forward the previous price as if it were confirmed.
  6. Alert only after defining the threshold, comparison basis, and any noise controls your workflow needs.

Amazon’s Product Pricing API documents specific operations and limits, including batches of up to 40 SKUs for Featured Offer Expected Price data and up to 20 ASINs for featured offers. Those are operation-specific batch sizes, not total tracking limits. Check the current API documentation and your access before designing batch jobs. [Product Pricing API operations]

4. A runnable local workflow for stored observations

The script below turns observations your permitted collector has already saved into a latest-price report and threshold alerts. It deliberately does not call Amazon or a third-party provider: their authentication, endpoint, data model, and permissions differ, and this research does not establish a universal public endpoint. Save it as price_monitor.py. It uses only Python’s standard library.

Prepare observations.csv with one row per observed offer and these columns: observed_at,marketplace,asin,seller,condition,fulfillment,item_price,shipping,coupon, currency. Use ISO-8601 timestamps, numeric prices in the same currency, and coupon as a non-negative amount. Leave unknown values blank, not zero.

from __future__ import annotations

import argparse
import csv
from collections import defaultdict
from datetime import datetime
from decimal import Decimal, InvalidOperation
from pathlib import Path

REQUIRED = {
    "observed_at", "marketplace", "asin", "seller", "condition",
    "fulfillment", "item_price", "shipping", "coupon", "currency"
}

def money(value: str, field: str) -> Decimal | None:
    value = value.strip()
    if not value:
        return None
    try:
        amount = Decimal(value)
    except InvalidOperation as exc:
        raise ValueError(f"Invalid {field}: {value!r}") from exc
    if not amount.is_finite() or amount < 0:
        raise ValueError(f"{field} must be a finite, non-negative number")
    return amount

def read_rows(path: Path):
    with path.open(newline="", encoding="utf-8") as handle:
        reader = csv.DictReader(handle)
        missing = REQUIRED - set(reader.fieldnames or [])
        if missing:
            raise ValueError("Missing CSV columns: " + ", ".join(sorted(missing)))
        for line, row in enumerate(reader, start=2):
            try:
                when = datetime.fromisoformat(row["observed_at"].replace("Z", "+00:00"))
                item = money(row["item_price"], "item_price")
                shipping = money(row["shipping"], "shipping")
                coupon = money(row["coupon"], "coupon")
                if item is None:
                    raise ValueError("item_price is required")
                if not row["asin"].strip() or not row["marketplace"].strip():
                    raise ValueError("asin and marketplace are required")
                if not row["currency"].strip():
                    raise ValueError("currency is required")
                # Do not treat unknown shipping or coupon values as zero.
                landed = None if shipping is None else item + shipping - (coupon or Decimal("0"))
                yield {
                    **row,
                    "when": when,
                    "item": item,
                    "landed": landed,
                    "line": line,
                }
            except (ValueError, InvalidOperation) as exc:
                raise ValueError(f"CSV line {line}: {exc}") from exc

def main():
    parser = argparse.ArgumentParser(description="Summarize saved Amazon offer observations")
    parser.add_argument("csv_file", type=Path)
    parser.add_argument("--below", type=Decimal, help="Alert when landed price is below this amount")
    args = parser.parse_args()
    rows = list(read_rows(args.csv_file))
    if not rows:
        print("No observations found.")
        return

    grouped = defaultdict(list)
    for row in rows:
        key = (row["marketplace"], row["asin"], row["currency"])
        grouped[key].append(row)

    for (marketplace, asin, currency), offers in sorted(grouped.items()):
        latest_time = max(r["when"] for r in offers)
        latest = [r for r in offers if r["when"] == latest_time]
        print(f"{marketplace} {asin} ({currency}) latest observation: {latest_time.isoformat()}")
        for row in sorted(latest, key=lambda r: (r["seller"], r["condition"])):
            landed = "unknown" if row["landed"] is None else str(row["landed"])
            print(f"  seller={row['seller'] or 'unknown'} condition={row['condition'] or 'unknown'} "
                  f"fulfillment={row['fulfillment'] or 'unknown'} item={row['item']} "
                  f"shipping={row['shipping'] or 'unknown'} coupon={row['coupon'] or 'unknown'} landed={landed}")
            if args.below is not None and row["landed"] is not None and row["landed"] < args.below:
                print(f"  ALERT: landed price {row['landed']} is below {args.below}")

if __name__ == "__main__":
    main()

Run it with python price_monitor.py observations.csv --below 25.00. This reports the latest timestamp per marketplace, ASIN, and currency and flags observed landed prices below the threshold. It does not infer missing history, deduplicate offers across sellers, convert currencies, or determine whether two listings are equivalent. Those decisions depend on your competitive-intelligence definition.

For production, have your authorized source adapter write normalized observations in this schema, while retaining source identifiers and raw responses in a separate durable store. Use idempotent writes keyed by source, marketplace, product, offer, and observation timestamp where possible. Validate timestamps, currency consistency, and freshness before alerting. Add retry handling and a dead-letter path for failed collection rather than silently losing observations.

5. Read signals carefully

Amazon’s documented fields have specific meanings. Competitive Price Threshold and Featured Offer Price are not interchangeable with a general historical series. Average Selling Price is based on purchases in the last 60 days and excludes promotional purchases such as Best Deals and Lightning Deals. Price by Amazon (retailOfferPrice) is defined as the highest price listed in the last 14 days for products shipped and sold by Amazon. Do not label either value “current competitor price” without validating that interpretation for your use. [Amazon signal definitions]

Keepa’s offer data can include seller, condition, fulfillment and Prime flags, coupons, and price, shipping, stock, and Prime-exclusive histories. Its documentation warns offers may be stale or incomplete and that histories may contain gaps. Check update and last-seen information where provided, and represent missing observations explicitly. [Keepa offer fields and caveats]

6. Alerts, freshness, and analysis choices

  • Threshold alerts: use a clearly defined basis such as item price or landed price, and specify currency, condition, fulfillment, and offer scope.
  • Change alerts: compare a new observation with the prior valid observation for the same offer definition. Record the timestamp and source for both.
  • Out of stock: distinguish no offer returned from a confirmed out-of-stock state. Provider tracking may expose separate out-of-stock and back-in-stock criteria.
  • Missing data: gaps mean unknown. Do not interpolate across them for operational alerts unless the analysis explicitly marks the estimate.
  • Product matching: verify variants and unit counts. Keep coupons and shipping separate so analysts can recompute comparisons consistently.
  • Time zones: store timestamps in UTC or preserve their offset; render in a local zone only for reports.

Choose collection frequency based on how quickly a decision must respond and what the source permits. More frequent polling can increase API consumption and operational work without fixing stale upstream data. Event notifications reduce some polling needs but still require reconciliation and history storage.

7. Keep competitive monitoring separate from repricing

A monitoring system gathers evidence for a decision. A repricer changes an offer. Amazon Automate Pricing is for a seller’s own offers, requires a Professional selling account and an active offer, and allows minimum and optional maximum price limits. Amazon says sellers can review a detailed 30-day history against business reports. Repricing does not guarantee Featured Offer status; inventory, fulfillment, and customer service are among the other factors Amazon names. [Amazon Automate Pricing]

Set and review price floors before enabling rule-based changes. Keep an audit trail of rule inputs and resulting prices, and evaluate outcomes against the business reports rather than assuming a price drop caused a placement change.

8. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. It can capture a product page as a visual record, but a screenshot is not structured price history and should not be treated as the source for automated price analysis. The API accepts a URL and returns an image or PDF. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://www.amazon.com/dp/ASIN -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://www.amazon.com/dp/ASIN"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://www.amazon.com/dp/ASIN' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

Replace ASIN with the product identifier and use a marketplace URL appropriate to your workflow. Cookie banners, newsletter popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents use screenshot tools. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month with no card.

9. Troubleshooting

Symptom Likely cause Fix
No SP-API competitive data Seller-only access, missing Pricing role, marketplace mismatch, or operation-specific eligibility. Check the current Product Pricing API requirements and authorization for the seller and marketplace.
Price appears inconsistent with the product page Signal definitions differ; the value may include a threshold or historical average rather than a live offer. Verify the field definition and compare equivalent offer, shipping, coupon, condition, and fulfillment data.
History has holes The provider did not observe or return an offer for every interval. Preserve gaps as unknown; check freshness fields and request regularly if the provider recommends it.
Offer is present but old Returned offer data can be stale. Check last-seen or update metadata and avoid using stale values for immediate decisions.
Alerts fire on irrelevant products Variants, pack sizes, or conditions were grouped together. Refine product and offer keys; normalize unit pricing only when pack contents are verified.
Alerts fire too often Threshold is applied to noisy changes or incomparable offers. Define the offer scope and landed-price basis, and use a deliberate change rule before notifying.
Local CSV parser fails Missing required columns, invalid ISO timestamp, malformed numeric price, or inconsistent data. Use the documented header row, ISO-8601 timestamps, and non-negative decimal values; leave unknown values blank.
Repricing does not win the Featured Offer Price is only one consideration; eligibility and operational performance also matter. Review inventory, fulfillment, customer service, and Seller Central performance reports.

10. Reliability and cost checklist

  • Confirm the source’s current access, API limits, permitted use, marketplace coverage, and commercial cost before implementation.
  • Budget for collection volume, retention, retries, notification processing, and analyst time to validate product matches.
  • Store timestamps, currency, source, offer attributes, and freshness metadata alongside every price.
  • Monitor collector success and stale-data age separately; a successful API call can still return incomplete market coverage.
  • Use bounded retries with backoff for transient failures, and surface persistent failures rather than silently treating them as unchanged prices.
  • Keep an audit trail for alert decisions and any subsequent repricing action.

The research dossier does not establish current Keepa pricing, universal collection limits, or permission for arbitrary page scraping. Verify provider terms and account-specific limits directly. Amazon SP-API is seller-facing and its available signals depend on roles and marketplace context.

11. Frequently asked questions

Can I get Amazon price history through SP-API?

The documented Product Pricing API provides defined pricing and offer information and notifications. The cited documentation does not describe it as an unrestricted historical price database. Store your own timestamped observations or evaluate a history provider for that need.

Can Amazon SP-API track any competitor I choose?

It is seller-facing, and access to competitive signals depends on SP-API roles and marketplace context. Confirm the applicable access and returned data before building around a particular ASIN or seller.

How much Amazon price history is available to shoppers?

Amazon describes 30-, 90-, and 365-day views. Availability varies: its page lists the feature in the U.S., UK, Canada, and India, while its stated 365-day rollout names the U.S., UK, and India. Check the current marketplace experience. [Amazon price-history availability]

No. Amazon says price can help, but inventory availability, fulfillment, and customer service also affect eligibility. [Amazon Automate Pricing]

Should I use screenshots as my price database?

No. Screenshots can preserve a visual record, but structured, timestamped offer data is the better basis for automated comparisons and alerts.