One search. Every store.
Search Amazon, Best Buy and eBay in one API call. Cartroute returns every matching in-stock offer, new or renewed and clearly labelled, with price, shipping and a price-history verdict, grouped by product, as one normalized JSON response your agent can act on.
# One call. Amazon, Best Buy and eBay. curl "https://cart-route.com/api/v1/search?q=sony+wh-1000xm6" \ -H "Authorization: Bearer $CARTROUTE_API_KEY" { "object": "search_result", "data_source": "live", "total_results": 1, "results": [ { "title": "Sony WH-1000XM6 Wireless Noise Cancelling Headphones", "price_summary": { "best_retailer": "eBay", "best_effective_price_usd": 291.26, "spread_usd": 178.01, "offers_count": 31 }, "price_insight": { "verdict": "typical_price", "low_90d_usd": 180 }, "offers": [ { "retailer": "eBay", "price_usd": 280, "shipping_usd": 11.26, "best_coupon": null, "effective_price_usd": 291.26, "in_stock": true } ] } ], "credits": { "charged": 1, "remaining": 199 } }
# Claude Code claude mcp add --transport http cartroute https://cart-route.com/mcp \ --header "Authorization: Bearer $CARTROUTE_API_KEY" # Any client with a JSON config (Cursor, Claude Desktop via mcp-remote) { "mcpServers": { "cartroute": { "url": "https://cart-route.com/mcp", "headers": { "Authorization": "Bearer cr_live_..." } } } } # Tools: search_products, get_product, get_price_history, # find_coupons, list_retailers, list_categories, get_account
import os, requests r = requests.get( "https://cart-route.com/api/v1/search", params={"q": "65 inch oled tv", "max_price": 2000, "condition": "new"}, headers={"Authorization": f"Bearer {os.environ['CARTROUTE_API_KEY']}"}, timeout=10, ) best = r.json()["results"][0]["price_summary"] print(best["best_retailer"], best["best_effective_price_usd"])
Every search covers
What does Cartroute return for a single query?
One GET /api/v1/search returns every matching product, every retailer offer for each product, and the six numbers an agent needs to recommend where to buy. Nothing needs to be scraped, parsed or reconciled on your side.
Price plus shipping
landed_price_usd adds the shipping the listing states. When a listing does not state shipping, shipping_stated is false instead of a guessed zero.
Every condition, labelled
New, renewed, refurbished, open-box and used offers each carry condition, and the best price is always a new unit when one is in stock. Out-of-stock offers are never returned.
Price-history verdict
price_insight.verdict compares today's price with every daily price Cartroute has recorded for the product, with the numbers behind it.
Matched by model number
Listings from different stores are grouped when they share a model number and brand. Different storage sizes, screen sizes and bundles are never merged with the bare unit.
Fetched when you ask
Searches go to the retailers when they arrive and are reused for up to 6 hours. Every offer carries last_checked_at and freshness_seconds.
One shape for every store
Amazon, Best Buy and eBay results arrive as the same JSON objects, so an agent compares them without per-store parsing.
How does an agent connect to Cartroute?
Three ways, all authenticated with the same API key, all metered the same way: one credit per successful call, nothing for a malformed one.
- REST. OpenAPI 3.1 describes every field. Errors are RFC 9457 problem+json with stable codes.
- MCP. Point any Model Context Protocol client at
https://cart-route.com/mcp. Seven tools, Streamable HTTP. Setup guide. - Self-registration. An agent can create an account for its user with
POST /api/v1/accountsand receive a working key with 100 credits.
Built for machines that retry
| Idempotency | Idempotency-Key replays for 24 h, no second charge |
| Rate limits | RateLimit-* headers and Retry-After |
| Units | Every money field ends in _usd |
| Pagination | Opaque next_cursor |
| Discovery | api-catalog, MCP card, llms.txt |
| Every page | Add ?format=json or Accept: application/json |
Which products have the widest price gap today?
Same product, same condition, different retailer. Live prices , updated November 8, 2026.
Why not scrape each retailer directly?
Most teams try it first. It works for one retailer and breaks at three: bot defences, layout changes, and matching the same product across stores are each a full-time job.
| Cartroute | DIY scraping | Single-retailer APIs | |
|---|---|---|---|
| Retailers per call | 3 | 1 per scraper | 1 |
| Cross-store product matching | Model number and brand | You build it | Not offered |
| Shipping in the comparison | Yes, landed price | Checkout emulation | Rarely |
| Price history | Daily, kept 180 days | From when you start | Rarely |
| MCP server | Yes | No | No |
| Time to first result | About a minute | Weeks | Days per retailer, with approvals |
How much does it cost to start?
Nothing. A new account gets 100 credits immediately and 100 more after confirming the email address: 200 searches with no card. Paid plans start at $29 a month for 5,000 credits.