GET /v1/products/{id}
The primary product-lookup endpoint. Resolves any UPC, EAN, ISBN, GTIN, ASIN, or Walmart item_id and returns the full normalized product including price history, marketplace fees, and Bucket-1 facts.
Request
GET https://api.retailerapi.com/v1/products/{id}
Authorization: Bearer rk_live_...Path parameters
| Name | Required | Description |
|---|---|---|
id | yes | UPC-12, EAN-13, ISBN-10/13, GTIN-14, Amazon ASIN (B0XXXXXXXX), Walmart item_id (6-12 digits), or any retailer PDP URL. URLs must be URL-encoded when passed in the path. Cost is 1 token regardless of identifier type. URL submission works on any retailer that ships Product structured data. The 7 vetted retailers (Amazon, Walmart, Target, Home Depot, Lowe's, Best Buy, eBay) have dedicated by-URL parsers and return the richest shape. The ~2 million Shopify-hosted stores work via Shopify's public /products/<handle>.json endpoint. Any other retailer with Product JSON-LD or OpenGraph product tags in its initial HTML works through the generic-URL path.Examples:
|
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
format | string | auto-detect | One of UPC, EAN, ISBN, GTIN, ASIN, item_id. Set when input could be ambiguous. ASIN routes through Amazon-first; include_offers_reviews is silently ignored on that path. |
include_offers_reviews | boolean | false | Live marketplace sellers + review summary (rating, sentiment, verified-purchase counts) + a monthly review trend. Individual review bodies (reviews.top_reviews) are included when the source exposes them — Walmart currently returns aggregates only. +5 tokens. |
include_cross_retailer | boolean | false | Include the cross_retailer block — a map keyed by retailer slug of cached per-retailer cells (price, in_stock, Bucket-1 fields). +2 tokens. Read-only over our cache; never triggers fresh scrapes. Cells with status='indexing' mean we haven't fetched that retailer yet — call again in a few seconds. |
include_seller_context | boolean | false | Live seller-side state under cross_retailer.<retailer>.seller_context.restricted and .wfs_eligibility, plus top-level seller_context.restricted aggregation. +3 tokens. Marketplace fees (referral_fee_usd, wfs_fee_usd) are FREE in the base call — this flag adds the live-state fields only. Applies to marketplace retailers; first-party retailers emit seller_context: null. |
retailer | string | (unified) | Anchor the response to a specific retailer's data. Slug format: lowercase alphanumeric only, 2-30 chars, no TLD or separators (homedepot not home-depot). Vetted retailers have custom parsers; other slugs route through a self-extending WebFetch waterfall. Cost: 1 token flat. |
force_refresh | boolean | false | Bypass cache and force a fresh scrape of the retailer specified by ?retailer=<retailer>. Only valid with ?retailer=<retailer> — passing force_refresh alone returns 400. No additional token cost beyond the retailer surcharge. This is the ONLY way to force fresh data from the API. |
Cost summary
| Call shape | Tokens | What you get |
|---|---|---|
| Base lookup | 1 | title, brand, image, price, identifiers, weight, dimensions, MSRP, description, categories, price history, stats, retailer_links, Bucket-1 facts (sold_tag, estimated_sales, is_best_seller, pack_count, hazmat), computed marketplace fees (referral_fee_usd, wfs_fee_usd) |
+ include_cross_retailer | 3 | + cross_retailer block (cached cells for every retailer we have for this UPC, read-only) |
+ include_seller_context | 4 | + live restriction + WFS eligibility state |
+ include_offers_reviews | 6 | + live marketplace sellers + review summary (sentiment + monthly trend) |
| All three flags | 11 | Full reseller view |
?retailer=<r> | 1 | Anchor to a specific retailer (replaces base call shape) |
?retailer=<r>&force_refresh=true | 1 | Same as above but bypasses cache + scrapes fresh. Only way to force fresh data from the API. |
Marketplace fees (referral_fee_usd, wfs_fee_usd) are computed from public rate cards and are always free in the base call — same model as Keepa's referralFeePercentage. include_seller_context only pays for the live-state fields (restricted, wfs_eligibility).
Response
200 OK with a JSON body. Fields below show a UPC lookup with all opt-in flags enabled.
{
"item_id": "19667262713",
"upc": "086279195869",
"ean": null,
"isbn": null,
"gtin": "00086279195869",
"asin": null,
"mpn": "EP-PC8",
"model": "EP-PC8",
"title": "12-in-1 Electric Pressure Cooker 6 QT...",
"brand": "Cooks Essentials",
"image_url": "https://i5.walmartimages.com/...",
"description": "Cook everything from rice to roast...",
"current_price": 100.56,
"buybox_price": 100.56,
"secondary_offer_price": 99.50,
"msrp": 149.99,
"weight_lbs": 12.5,
"weight_assembled_lbs": 12.5,
"weight_package_lbs": 14.2,
"dimensions": { "height_in": 13.2, "width_in": 13.0, "length_in": 12.8 },
"dimensions_assembled": { "height_in": 13.2, "width_in": 13.0, "length_in": 12.8 },
"dimensions_package": { "height_in": 15.0, "width_in": 14.5, "length_in": 14.0 },
"offers_count": 4,
"total_offers": 6,
"delivery_date": "2026-06-23",
"fulfillment": {
"shipping": { "available": true, "cost": 0, "free": true, "date": "2026-06-23" },
"delivery": { "available": false, "cost": null, "date": null },
"pickup": { "available": true, "cost": 0, "date": "2026-06-21" }
},
"seller_name": "Walmart",
"seller_id": "F55CDC31AB754BB68FE0B39041159D63",
"average_rating": 4.3,
"review_count": 1247,
"categories": ["Home", "Appliances", "Pressure Cookers"],
"specs": [
{ "name": "Model", "value": "EP-PC8" },
{ "name": "Capacity", "value": "6 quart" },
{ "name": "Color", "value": "Stainless Steel" }
],
"walmart_url": "https://www.walmart.com/ip/...",
"in_stock": true,
"condition": "new",
"seller_type": "first_party",
"seller_rating": null,
/* top-level UPC-scoped restriction view — present when include_seller_context=true */
"seller_context": {
"restricted": { "any": false, "retailers": [], "primary_reason": null }
},
"price_history": [
{ "recorded_at": "2026-04-09T12:00:00Z", "price": 99.99, "in_stock": true }
],
"stats": { "sales_rank_30d": 142, "price_low_90d": 89.99, "price_high_90d": 119.99 },
/* free for barcode lookups; absent for item_id */
"retailer_links": [
{ "retailer": "walmart", "url": "https://walmart.com/ip/...", "found_via": "native_catalog" },
{ "retailer": "amazon", "url": "https://amazon.com/dp/B0...", "found_via": "amazon_catalog" }
],
/* Map keyed by retailer slug. Only present when include_cross_retailer=true.
Read-only over our cache — to refresh a specific retailer's data,
use ?retailer=<retailer>&force_refresh=true. */
"cross_retailer": {
"walmart": {
"retailer": "walmart",
"status": "ok",
"price": 100.56,
"url": "https://www.walmart.com/ip/...",
"in_stock": true,
"unavailable": false,
"sold_tag": "100+ bought",
"estimated_sales": 1200,
"is_best_seller": true,
"pack_count": 1,
"hazmat": false,
"seller_context": {
"referral_fee_usd": 15.08,
"wfs_fee_usd": 11.95,
"restricted": { "flag": false, "reason": null },
"wfs_eligibility": { "enabled": true, "reason": null }
},
"_source": "primary",
"_freshness": { "refreshed_at": "2026-05-16T10:00:00Z" }
},
"amazon": {
"retailer": "amazon",
"status": "ok",
"price": 105.99,
"url": "https://www.amazon.com/dp/...",
"in_stock": true,
"unavailable": false,
"sold_tag": null,
"estimated_sales": null,
"is_best_seller": null,
"pack_count": null,
"hazmat": null,
"seller_context": {
"referral_fee_usd": 15.90,
"wfs_fee_usd": null,
"restricted": null,
"wfs_eligibility": null
},
"_source": "secondary",
"_freshness": { "refreshed_at": "2026-05-16T09:00:00Z" }
}
/* + ebay, lowes, target, bestbuy, homedepot */
},
/* present when include_offers_reviews=true */
"offers": [
{ "seller_id": "...", "seller_name": "Walmart", "price": 100.56, "is_buy_box": true, "in_stock": true }
],
"review_summary": {
"average_rating": 4.3,
"total_reviews": 1247,
"rating_distribution": { "5": 812, "4": 234, "3": 98, "2": 53, "1": 50 }
},
"reviews": {
"summary": { "average_rating": 4.3, "total_reviews": 1247, "sentiment": { "positive": 1040, "neutral": 110, "negative": 97 }, "verified_purchases": 1180 },
"monthly_breakdown": [
{ "month": "2026-05", "total_reviews": 41, "average_rating": 4.4, "sentiment": { "positive": 34, "neutral": 4, "negative": 3 } }
],
"top_reviews": [] /* individual review bodies, when the source exposes them. Walmart currently returns aggregates only, so this is typically empty. */
},
"_meta": {
"title_source": "walmart",
"weight_lbs_source": "amazon",
"dimensions_source": "amazon",
"data_quality_score": 1.0
},
"tokens_consumed": 11,
"tokens_remaining": 856249
}Field types
- Identifiers: always strings.
item_idis Walmart-internal;upcis the GTIN equivalent. - Prices: USD floats with 2 decimal places.
nullwhen out of stock. - Timestamps: ISO 8601 UTC.
- in_stock:
truewhen at least one retailer reports the product is in stock;falseonly when every retailer with a known signal reports out-of-stock;nullwhen no retailer has reported yet. - cross_retailer.<retailer>.status:
ok|stale|indexing|not_found|blocked|error - cross_retailer.<retailer>.seller_context:
nullpermanently for first-party retailers (target, bestbuy, lowes, homedepot) — they don't have a marketplace. - retailer_links: where the product is found across retailers (URL only). Free on every barcode lookup.
Cross-retailer field semantics
Bucket-1 facts (sold_tag, estimated_sales, is_best_seller, pack_count, hazmat) populate where each retailer supports the concept. Most are populated for Walmart today; other retailers backfill as we add per-retailer parsers. Null doesn't mean "we forgot to fetch" — it means "this retailer doesn't expose this concept".
Top-level weight_lbs, dimensions, description, mpn, model use the best source we have across retailers. When one retailer's payload is missing weight or dimensions, another retailer's value backfills it automatically (Amazon's catalog tends to be most reliable for physical specs because FBA forces sellers to declare them). _meta.weight_lbs_source records which retailer the value came from on every response.
Package vs assembled. Retailers that distinguish the boxed-for-shipping weight from the product's own weight expose both as weight_assembled_lbs + weight_package_lbs (and the parallel dimensions_assembled + dimensions_package). Top-level weight_lbs / dimensions are the derived "best available": assembled wins (it's what the product actually is); package fills in when no assembled value is known. Retailers that only expose one weight populate weight_lbs and leave the explicit pair as null — call weight_assembled_lbs ?? weight_lbs when you need the product weight and don't care about the source.
Diagnostic _meta block
Every barcode lookup includes a _meta object describing which source each top-level field came from and how strongly sources agreed on identity. Safe to ignore for most uses.
{
"_meta": {
"title_source": "amazon",
"brand_source": "walmart",
"weight_lbs_source": "amazon",
"dimensions_source": "amazon",
"data_quality_score": 0.667,
"disagreements": [
{
"retailer": "target",
"reason": "title-mismatch",
"similarity": 0.21,
"their_title": "Different product entirely",
"consensus_title": "12-in-1 Electric Pressure Cooker 6 QT..."
}
]
}
}Errors
404when the identifier doesn't resolve (multiple format fallbacks are attempted before returning 404)400when the identifier doesn't match any expected format429when you exceed your throttle or monthly quota
Examples
Walmart item_id
curl -H "Authorization: Bearer rk_live_..." \
"https://api.retailerapi.com/v1/products/19667262713"UPC with cross-retailer
curl -H "Authorization: Bearer rk_live_..." \
"https://api.retailerapi.com/v1/products/194629116676?include_cross_retailer=true"Reseller full view (cross-retailer + seller context)
curl -H "Authorization: Bearer rk_live_..." \
"https://api.retailerapi.com/v1/products/194629116676?include_cross_retailer=true&include_seller_context=true"EAN-13 (international)
curl -H "Authorization: Bearer rk_live_..." \
"https://api.retailerapi.com/v1/products/5060214160102"ISBN-13 (book)
curl -H "Authorization: Bearer rk_live_..." \
"https://api.retailerapi.com/v1/products/9780553213119?format=ISBN"