Keepa vs PricesAPI
Build ASIN-based Amazon analysis, or compare recorded product offers across retailers.
Use PricesAPI data to build price comparisons and history views. Coverage varies by product and market; your application handles analysis and pricing decisions.
Keepa fits Amazon-focused apps that need retained price-change series, marketplace offers and Buy Box data. PricesAPI fits product-and-market seller comparisons and raw recorded-offer charts where coverage exists.
Official-source facts
Reviewed 2026-09-22. Competitor facts below come from these official sources; PricesAPI facts come from our API documentation and pricing rules. Documented fields do not establish coverage, accuracy or performance for your products. We have not run a paid head-to-head benchmark.
- Product request: ASINs, relative history windows and refresh options (recovery checked 2026-10-01)
- Product object: history, variants, timestamps and units
- Offer object: seller, condition and shipping sentinels
- Plans: token costs, refill and expiry
- Requests: response envelope and errors (retry row checked 2026-10-01)
| Feature | PricesAPI | Keepa |
|---|---|---|
| Free access | Free, one-time: 300 Searches with merchant offers (3,000 credits); 6 rpm | Product API access uses an API plan and token balance. See Plans & Tokens for current access terms; tokens are not PricesAPI credits. |
| Entry paid plan | $49/month: 3,000 Searches with merchant offers (30,000 credits); 20 rpm | Plans replenish tokens per minute; requested product and offer data changes consumption. See Plans & Tokens when sizing your workload. |
| Identity and market | Select id, id_type (pricesapi or catalog), and market. Exact catalogue variants differ from product clusters; name matching is not a barcode guarantee. | Supply an ASIN or product code (UPC/EAN/GTIN/ISBN-13) and an Amazon domain ID. Codes can resolve multiple ASINs; select the intended child variant and check supported locales. |
| Seller and condition | Snapshot includes seller_id, domain, listing title and URL. Condition is not published on Snapshot or observed History; mixed-condition rows need care. | Offers include sellerId, product-scoped offerId, condition and fulfilment flags. Parent/child ASIN fields help navigate variants; liveOffersOrder identifies current offers. |
| Delivery and totals | Snapshot and History have no numeric shipping field. price is the item price; delivery_info is seller delivery text (null means unknown, not free). Delivery depends on the buyer's location. | offerCSV separates price and shipping. Shipping 0 means free; -2 means undetermined; -1 can mean unshippable or unspecified. Do not add sentinel values as costs. |
| Currency | Snapshot and History currency is inferred from the requested market, such as USD for market=us. Compare item prices within the same market. | Amounts use the locale's smallest currency unit, such as euro cents or yen. Do not divide every locale's values by 100. |
| Freshness | Snapshot exposes observation time, age and stale state; reading it does not trigger a refresh. Recording time is not a merchant update time. | update controls product refresh; offers have separate lastSeen and update evidence. lastUpdate is not lastPriceChange, and offersSuccessful can be true with no offers. |
| History | Raw recorded offers plus date-window coverage, not a promise of daily sampling. Leave gaps visible; available depth varies by product and market. | Precollected change series start at trackingSince, with gaps possible. Since 2026-02-23, NEW/USED/COLLECTIBLE/REFURBISHED minima include delivery; earlier entries exclude it. |
| Pagination and batch | Snapshot returns up to 60 offers and a truncation flag, no offer cursor. Batch accepts 100 products; History uses bound continuation cursors. | Product requests accept up to 100 identifiers. days limits history returned; offers requests 20–100 fresh offers, while stored historical offers can enlarge the array. |
| Asynchronous work | Snapshot and History are direct retained reads. Async Bulk Search is a separate discovery workflow, not an immutable History export. | The compared Product endpoint returns synchronously; clients can issue parallel requests. Its documented response is not a task-ID polling workflow. |
| Interrupted reads · checked Oct 1 | Save each History page and next_cursor together. Valid continuations add no charge. Without a saved first response or cursor, another cursorless request is a new billable read. Expired cursors require a chosen restart; pagination is not an immutable export. | Product returns history in one response. days=X selects the latest X × 24 hours, so repeating it later shifts the window. update=-1 prevents request-triggered refresh, not all data changes. The reviewed Product docs do not promise free replay or a saved-response retrieval handle. |
| Billing unit | Search Products: 10 credits per response with at least one merchant offer; Product Snapshot: 1 credit per product; Price History: 1 credit per day with recorded offers. History reserves requested days, then refunds days without offers; valid continuations add no charge. Known-product empty Snapshots still bill. | Base Product read: one token per product. Offers replaces that base with six tokens per found offer page; options and outcomes affect cost. Tokens refill per minute and expire unused after 60 minutes. |
| Failures | 404 unknown identity, 403 balance, 409 expired History cursor and 429 with Retry-After are different cases. Restarting a History walk can bill again. | Inspect HTTP status, error and token balance. 429 means tokens exhausted; 402 is an inaccessible key. Failed offer refresh can leave historical data rather than fresh offers. |
| Pacing and retries · checked Oct 1 | Limits are per account, not per key. For rate-only 429, honor Retry-After seconds. Over-quota Search retries also return 429: inspect credit details and pause until credit is available, regardless of the delay. | 429 includes token-bucket details. refillIn is milliseconds until the next refill, not guaranteed admission: tokensLeft can be negative. Check balance and refill flow before more work; 402 needs an access change, not backoff. |
- Feature
- Free access
- PricesAPI
- Free, one-time: 300 Searches with merchant offers (3,000 credits); 6 rpm
- Keepa
- Product API access uses an API plan and token balance. See Plans & Tokens for current access terms; tokens are not PricesAPI credits.
- Feature
- Entry paid plan
- PricesAPI
- $49/month: 3,000 Searches with merchant offers (30,000 credits); 20 rpm
- Keepa
- Plans replenish tokens per minute; requested product and offer data changes consumption. See Plans & Tokens when sizing your workload.
- Feature
- Identity and market
- PricesAPI
- Select id, id_type (pricesapi or catalog), and market. Exact catalogue variants differ from product clusters; name matching is not a barcode guarantee.
- Keepa
- Supply an ASIN or product code (UPC/EAN/GTIN/ISBN-13) and an Amazon domain ID. Codes can resolve multiple ASINs; select the intended child variant and check supported locales.
- Feature
- Seller and condition
- PricesAPI
- Snapshot includes seller_id, domain, listing title and URL. Condition is not published on Snapshot or observed History; mixed-condition rows need care.
- Keepa
- Offers include sellerId, product-scoped offerId, condition and fulfilment flags. Parent/child ASIN fields help navigate variants; liveOffersOrder identifies current offers.
- Feature
- Delivery and totals
- PricesAPI
- Snapshot and History have no numeric shipping field. price is the item price; delivery_info is seller delivery text (null means unknown, not free). Delivery depends on the buyer's location.
- Keepa
- offerCSV separates price and shipping. Shipping 0 means free; -2 means undetermined; -1 can mean unshippable or unspecified. Do not add sentinel values as costs.
- Feature
- Currency
- PricesAPI
- Snapshot and History currency is inferred from the requested market, such as USD for market=us. Compare item prices within the same market.
- Keepa
- Amounts use the locale's smallest currency unit, such as euro cents or yen. Do not divide every locale's values by 100.
- Feature
- Freshness
- PricesAPI
- Snapshot exposes observation time, age and stale state; reading it does not trigger a refresh. Recording time is not a merchant update time.
- Keepa
- update controls product refresh; offers have separate lastSeen and update evidence. lastUpdate is not lastPriceChange, and offersSuccessful can be true with no offers.
- Feature
- History
- PricesAPI
- Raw recorded offers plus date-window coverage, not a promise of daily sampling. Leave gaps visible; available depth varies by product and market.
- Keepa
- Precollected change series start at trackingSince, with gaps possible. Since 2026-02-23, NEW/USED/COLLECTIBLE/REFURBISHED minima include delivery; earlier entries exclude it.
- Feature
- Pagination and batch
- PricesAPI
- Snapshot returns up to 60 offers and a truncation flag, no offer cursor. Batch accepts 100 products; History uses bound continuation cursors.
- Keepa
- Product requests accept up to 100 identifiers. days limits history returned; offers requests 20–100 fresh offers, while stored historical offers can enlarge the array.
- Feature
- Asynchronous work
- PricesAPI
- Snapshot and History are direct retained reads. Async Bulk Search is a separate discovery workflow, not an immutable History export.
- Keepa
- The compared Product endpoint returns synchronously; clients can issue parallel requests. Its documented response is not a task-ID polling workflow.
- Feature
- Interrupted reads · checked Oct 1
- PricesAPI
- Save each History page and next_cursor together. Valid continuations add no charge. Without a saved first response or cursor, another cursorless request is a new billable read. Expired cursors require a chosen restart; pagination is not an immutable export.
- Keepa
- Product returns history in one response. days=X selects the latest X × 24 hours, so repeating it later shifts the window. update=-1 prevents request-triggered refresh, not all data changes. The reviewed Product docs do not promise free replay or a saved-response retrieval handle.
- Feature
- Billing unit
- PricesAPI
- Search Products: 10 credits per response with at least one merchant offer; Product Snapshot: 1 credit per product; Price History: 1 credit per day with recorded offers. History reserves requested days, then refunds days without offers; valid continuations add no charge. Known-product empty Snapshots still bill.
- Keepa
- Base Product read: one token per product. Offers replaces that base with six tokens per found offer page; options and outcomes affect cost. Tokens refill per minute and expire unused after 60 minutes.
- Feature
- Failures
- PricesAPI
- 404 unknown identity, 403 balance, 409 expired History cursor and 429 with Retry-After are different cases. Restarting a History walk can bill again.
- Keepa
- Inspect HTTP status, error and token balance. 429 means tokens exhausted; 402 is an inaccessible key. Failed offer refresh can leave historical data rather than fresh offers.
- Feature
- Pacing and retries · checked Oct 1
- PricesAPI
- Limits are per account, not per key. For rate-only 429, honor Retry-After seconds. Over-quota Search retries also return 429: inspect credit details and pause until credit is available, regardless of the delay.
- Keepa
- 429 includes token-bucket details. refillIn is milliseconds until the next refill, not guaranteed admission: tokensLeft can be negative. Check balance and refill flow before more work; 402 needs an access change, not backoff.
Credits, searches and extracted records are different billing units. Compare the work each request does, not just the number included in a plan. The recommendations below are our assessment.
Choose PricesAPI when
- Your app compares product offers across retailers using an explicit market, rather than centring its identity model on ASINs.
- You want to build price-history charts from recorded offers and show the coverage available for each product.
Choose Keepa when
- Your workflow starts with Amazon ASINs and needs price-change history, Buy Box or fulfilment-specific marketplace analysis.
- You can decode Keepa time, currency units and sentinel values, and budget for the optional offer data your app needs.
Building a price tracker?
Already have a product ID? Use id, id_type=pricesapi|catalog and market directly with Snapshot or History, both in public Beta. Choose the read your app needs; History does not require a Snapshot request.
- Find candidates for free. If you need an ID, search by product or seller text and market. Check that the result matches your product. Catalog summaries do not guarantee History availability.
- Compare stored seller prices. Read a product’s latest retained offers. Show when each offer was observed; a stored offer is not a live-price guarantee.
- Chart recorded prices. Read a date window and follow the remaining pages. Compare a headphone promotion with its earlier recorded prices, leaving unobserved days as gaps.
History reports coverage for your requested window. It first reserves credits for the full window, then refunds days without offers; continuation pages add no charge. Check the billing rules before choosing a long window.
Response shape
Product Search API returns matched products with available merchant offers inline. Carry a result’s product_ref into Snapshot or History; free product lookup is another starting point. Both examples are illustrative and based on the linked contracts; values are not live measurements or current commercial data.
GET /api/v1/products/search?q=Sony%20WH-1000XM5&market=us
{
"success": true,
"data": {
"query": "Sony WH-1000XM5",
"market": "us",
"products": [{
"position": 1,
"pid": 100569554,
"product_ref": { "id": "100569554", "id_type": "pricesapi", "market": "us" },
"cluster_id": "123456789",
"catalog_id": "987654321",
"title": "Sony WH-1000XM5 Wireless Headphones",
"image": "https://example.com/headphones.jpg",
"headline_price": 348,
"headline_currency": "USD",
"condition_label": null,
"source": "Amazon.com",
"multi_store": true,
"rating": 4.7,
"reviews": 8523,
"delivery": "Free delivery",
"tags": [],
"nearby_distance_km": null,
"offers": [{
"seller": "Amazon.com",
"seller_url": "https://amazon.com",
"price": 348,
"currency": "USD",
"product_title": "Sony WH-1000XM5",
"stock_status": "In stock",
"delivery_info": "Free delivery",
"url": "https://example.com/product"
}],
"offerCount": 1
}]
},
"meta": { "latency_ms": 842, "raw_count": 3, "gid_bearing_count": 2 }
}
Carry product_ref.id, id_type and market to the read you need:
GET /api/v1/products?id=100569554&id_type=pricesapi&market=us
GET /api/v1/products/history?id=100569554&id_type=pricesapi&market=us&from=2026-09-01&to=2026-09-07
Already have a catalog ID? Skip discovery and choose one read:
Snapshot:
GET /api/v1/products?id=987654321&id_type=catalog&market=us
History (no Snapshot request needed):
GET /api/v1/products/history?id=987654321&id_type=catalog&market=us&from=2026-09-01&to=2026-09-07
Snapshot: inspect observation and offers_page.truncated.
History: inspect coverage and follow page.next_cursor with the same parameters.
Null product_ref means no usable product identity; do not substitute cluster_id.Illustrative, not executed. Invented ASIN and changes; abbreviated response.
GET https://api.keepa.com/product?key=REDACTED&domain=1&asin=ASIN_SELECTED_BY_CALLER&history=1&days=30&update=-1
domain=1 selects Amazon US; update=-1 avoids a refresh.
csv[0] projects AMAZON time/price pairs. 4700 means USD 47.00 here.
Keepa minutes convert to Unix milliseconds: (minutes + 21564000) * 60000.
Response fragment:
{
"tokensConsumed": 1,
"tokensLeft": 59,
"refillIn": 30000,
"products": [{
"asin": "ASIN_SELECTED_BY_CALLER",
"domainId": 1,
"trackingSince": 8000000,
"lastUpdate": 8267760,
"csv": [[8267660, 4900, 8267760, 4700]]
}]
}Try the Product Search API
3,000 free credits, granted once. That covers 300 Searches returning at least one merchant offer at 10 credits each. Searches with no products or no merchant offers, and failed requests, cost nothing. Snapshot and History use different billing units.
Need more? Developer is $49/month for 30,000 credits, with a limit of 20 requests per minute.