Shopping search engine for AI

The shopping search engine for AI

Ask for a product by keyword or by barcode. Get structured offers, prices and product content from shops and marketplaces in 32 countries, as JSON an agent or a RAG pipeline can use as it is.

  • 1 Text keywords
  • 2 Streamed per source
  • 3 GTIN, exact match
250+sources
32countries
1.4 smedian first answer
An AI agent asks many shops for a price and gets price tags back
Try it

Watch a search run, or run your own

It starts on its own when you get here and walks through the countries. Pick a country, type a GTIN or a product title, and run it.

Sony WH-1000XM5 Noise Cancelling Headphones - Black
Sony · GTIN 4548736132580
Open in the portal
Offers found0
Sources answered0/6
Lowest price-
Time0.0 s
Speed

Results stream in. You do not wait for the slowest shop.

Every source is asked at the same time and each answer is sent the moment it arrives. An agent can start on the first match while slow shops are still loading.

First answer1.4 s
First match1.6 s
All six sources4.8 s

Median of 12 recorded runs (6 countries, GTIN and title), 2026-10-07. Cached answers come back in milliseconds, a slow shop can take longer, and the demo stops at 5 s: a source that has not answered by then is cut.

Use case 1 · Search with a title

A shopping assistant that answers "what does it cost?"

Your agent has a product name from a chat, not a barcode. ShoppingQuery resolves the name to candidate GTINs and returns the offers it finds for them.

User asks"What does the Sony WH-1000XM5 cost in the UK?"
A name is not a variant. This one name resolved to 8 different GTINs (colours, markets), so most title results are marked grouped, not proven. For a proven match, use the GTIN.
The mascot points at a search bar, and many product variants appear below it
GET /v1/title?q=Sony WH-1000XM5&countries=GB
// simplified
{
  "query": {
    "type": "title",
    "value": "Sony WH-1000XM5",
    "resolved_gtin": "0027242923232",
    "candidates": [
      { "gtin": "0027242923232", "source": "idealo.de" },
      { "gtin": "4548736132573", "source": "idealo.de" },
      { "gtin": "4548736134294", "source": "idealo.de" },
      // 5 more
    ]
  },
  "offers": [
    { "source": "pricerunner.com", "shop": "A1 Tech Deals",
      "price": { "amount": 173.49, "currency": "GBP" },
      "match": { "scope": "grouped", "ean_verified": false } },
    { "source": "idealo.co.uk",
      "price": { "amount": 173.49, "currency": "GBP" },
      "match": { "scope": "exact", "ean_verified": true } },
    // 13 more offers
  ]
}
Real response, United Kingdom only, shortened. 2026-10-07.
Use case 2 · Product content

Ground your answers in real product data

An LLM that writes about a product from memory gets specs wrong. Fetch the title, description, specs and variant for a GTIN and put them in the context. Each description says which source it came from.

Pipeline stepEnrich a catalogue row, or give a RAG prompt the facts it should quote.
The mascot shows a product card with photos, a description and specs
GET /v1/ean/4548736132580/content
// simplified
{
  "gtin": "4548736132580",
  "title": "Sony WH-1000XM5 Noise Cancelling Headphones - Black",
  "brand": "Sony",
  "description": "De volgende generatie over-ear ...",
  "description_source": "kieskeurig.nl",
  "specs": [
    { "name": "Draadloos", "value": "true" },
    { "name": "Noise Cancelling", "value": "Ja" }
  ],
  "images": [
    { "url": "https://media.reshift.nl/..." },
    // 4 more
  ],
  "variant": { "colour": "black", "model_code": "wh1000xm5" },
  "timing_ms": 3578
}
Real response, shortened. Text comes back in the language of the source shop.
Sony WH-1000XM5, front view
Sony WH-1000XM5, product image 2
Sony WH-1000XM5, lifestyle image
Sony WH-1000XM5, product image 4
Sony WH-1000XM5, product image 5
Use case 3 · Search with a GTIN

The exact product, checked against the barcode

Send an EAN, GTIN or UPC. Each source is asked for that barcode, and an offer counts as exact only when the barcode on the shop's product page matches. The answer is one variant, not a lookalike.

User scans a barcode in a shop"Is this cheaper online?"
A barcode scan picks exactly one of four similar headphones
Search by title8 GTINs for one name
Search by GTIN1 product, 4 of 4 offers exact
Why it matters: a price for the black model is not a price for the silver one. Agents that buy, compare or monitor need the exact variant.
GET /v1/ean/027242923232?countries=US
// simplified
{
  "product": {
    "gtin": "027242923232",
    "title": "Sony WH-1000XM5 Noise-Canceling Wireless Over-Ear Headphones (Black)",
    "brand": "Sony"
  },
  "offers": [
    { "source": "bhphotovideo.com", "shop": "B&H",
      "price": { "amount": 198.00, "currency": "USD" },
      "match": { "scope": "exact", "ean_verified": true } },
    { "source": "bestbuy.com", "shop": "bestbuy",
      "price": { "amount": 198.00, "currency": "USD" },
      "match": { "scope": "exact", "ean_verified": true } },
    { "source": "focuscamera.com", "shop": "Focus Camera",
      "price": { "amount": 198.00, "currency": "USD" },
      "match": { "scope": "exact", "ean_verified": true } },
    // 1 more exact offer
  ],
  "stats": {
    "sources": 5, "offers": 4,
    "by_scope": { "exact": 4 }
  }
}
Real response, United States only (5 sources, 2.4 s), shortened. A UPC works as well as an EAN. 2026-10-07.
API

Four endpoints, one product

Ask for one barcode and take what you need. Each endpoint returns plain JSON.

Offers

Every shop that sells it, with price, currency, condition, stock and country.

GET /v1/ean/4548736132580/offers
{
  "shop": "MediaMarkt", "country": "NL",
  "price": { "amount": 232.00, "currency": "EUR" },
  "condition": "new", "availability": "in_stock"
}
Docs

Price history

The price curve per country, with the lowest price per day.

GET /v1/ean/8806094215038/price-history?country=NL
{
  "country": "NL",
  "points": [
    { "date": "2025-10-05", "lowest_price": 159.90 },
    { "date": "2026-10-08", "lowest_price": 339.00 }
  ]
}
Docs

Content

Titles, descriptions and specifications from the shops that list the product.

GET /v1/ean/4548736132580/content
{
  "title": "Sony WH-1000XM5 Noise Cancelling Headphones - Black",
  "brand": "Sony",
  "description_source": "kieskeurig.nl"
}
Docs

Images

All product photos, duplicates removed.

GET /v1/ean/4548736132580/images
{
  "gtin": "4548736132580",
  "images": [
    { "url": "https://media.reshift.nl/..." }
  ]
}
Docs
Read the API docs See pricing

Billing opens soon. The demo is free today.

Unified

One schema for every kind of source

A retailer, a price comparison site, a refurb shop and a classifieds site all come back in the same shape: price (in the shop's currency and in euro), condition, one harmonised grade, how exact the match is, and a link. Your code handles one format.

Five kinds of sources flow into one unified card
SourceTypePriceConditionGradeMatchLink
MediaMarktretailer€232.00newnewexact, verifiedshop page
Shoparizeaggregator€215.20newnewexact, verifiedclickout
Kieskeurigcomparison€232.00newnewgroupedclickout
CeXrefurb€150.00refurbishedfairverifiedshop page
Vintedclassifieds€100.00usedusedgroupedshop page

Real offers for the same GTIN, Netherlands, 2026-10-07, shortened.

Links and checks

More data per product

Price history and stock, next to the offers

The same GTIN also opens the history behind today's price, and whether the shop has the product in stock.

Price history

Every product comes with its price curve

Lowest price over time, per country and per shop. Use it to tell a real deal from a fake discount, or to time a purchase. Or to see that SSDs are not getting cheaper.

GET /v1/ean/8806094215038/price-history?country=NL

See the docs

  • Netherlands
  • Germany
  • Spain

Samsung 990 PRO 2TB (MZ-V9P2T0BW, GTIN 8806094215038). Real series, lowest price per week, the Netherlands, Germany and Spain, 2025-10 to 2026-10. Read on 2026-10-08. Netherlands 215 points since 2023-09, Germany 347 points, Spain 363 points. Same call, any country: the history goes back further where the source has it.

Stock

Is it in stock?

Where a shop publishes it, each offer says in_stock, limited, out_of_stock or preorder. A shop that says nothing stays null, so unknown is never mistaken for sold out.

GET /v1/ean/027242923232?countries=US
// simplified
{ "offers": [
  { "shop": "B&H", "price": 198.00,
    "availability": "in_stock" },
  { "shop": "Focus Camera", "price": 198.00,
    "availability": "in_stock" },
  { "shop": "bestbuy", "price": 198.00,
    "availability": null }
] }

Real response, United States, shortened. 2026-10-07. Stock comes from the shops that publish it, not from every source yet.

Coverage

32 countries

Some of the largest webshops we find and scrape in each country, picked at random on every visit. There are many more.

Also in the box