Blog / API guides

Idealo API: Compare Product Prices Across Shops as JSON

To get idealo price comparison data as JSON, call GET /v1/idealo/search with a query to find products, then pass a product's id as product_id to GET /v1/idealo/offers for that product's offers. Each call costs 1 credit, and failed calls cost nothing. This guide walks through both calls, the parameters, a real search response and a cost estimate for a price monitor.

What does the idealo API return?

The Idealo API on Perceptlayer exposes 13 endpoints on the price comparison site idealo.de, all returning JSON and all costing 1 credit per successful call. They cover keyword search, products, offers, reviews, shop profiles, categories, deals and trending items. Data is collected from publicly available sources and returned as found at the time of the call.

The endpoints fall into three groups, and most workflows touch only the first two.

Group Endpoints Use it to
Find products search, autocomplete, brand-products, categories, trending Turn a keyword, brand or category into product IDs
Compare prices product, products, offers, international-prices Get offers and prices for a known product
Context reviews, shop, shop-products, deals Add ratings, seller details and discounted items

The site sits in the Marketplaces area of the catalogue, alongside other shopping sources. If you also need Google's view of the same products, see the Google Shopping API guide.

How do you authenticate and make the first call?

You need a Perceptlayer API key (they start with sk_live_), sent in the X-API-Key header. Get a free API key by verifying an email address: that gives you 1,000 free credits every month, no credit card. Where a client can't set headers, the api_key query parameter works instead; see the authentication docs.

Search is the natural first call. query is optional on this endpoint, but a keyword is what makes the result useful:

curl "https://api.perceptlayer.com/v1/idealo/search?query=air+fryer" \
  -H "X-API-Key: $API_KEY"

Every successful response carries X-Credits-Used and X-Credits-Remaining headers, so you can watch the balance from the response itself. More on requests and responses is in the requests docs.

Which parameters does the search endpoint take?

GET /v1/idealo/search takes eight optional parameters and no required ones. A query of up to 200 characters searches by keyword, category_id narrows to one category, and price_min and price_max bound the price. sort and item_states[] accept fixed values, listed below, and page moves through results.

Parameter Type Notes
query string Up to 200 characters
category_id string Restrict to one category
page integer Results page
sort string RELEVANCE_DESC, PRICE_ASC, PRICE_DESC, DISCOUNT_DESC, CREATION_DATE_DESC
filters[] list of string Facet filters
item_states[] list of string BARGAIN, SHORT_TERM_BARGAIN, EXCLUDE_USED, FAST_DELIVERABLE
price_min number Lower price bound
price_max number Upper price bound

The docs for this endpoint don't state defaults or page sizes, so check the response's pagination block instead of assuming. To get category IDs, call /v1/idealo/categories, which takes no parameters. For type-ahead input, /v1/idealo/autocomplete takes a required query (up to 100 characters) and an optional limit.

What does a search response look like?

A search response is a JSON object with a results array of products, plus facets, pagination and the category. Each product carries its id, title, a numeric price, a currency, an offer_count and a cheapest_offer object. The excerpt below is a recorded response for query=air fryer, trimmed with ….

{
  "success": true,
  "query": "air fryer",
  "category_id": "3513",
  "sort": "RELEVANCE_DESC",
  "results": [
    {
      "id": "203597427",
      "type": "PRODUCT",
      "title": "Ninja AF500",
      "subheading": "Heißluftfritteuse",
      "category_id": "3513",
      "url": "https://www.idealo.de/preisvergleich/OffersOfProduct/203597427_-af500-ninja.html",
      "price": 162.9,
      "price_formatted": "162,90 €",
      "currency": "EUR",
      "offer_count": 80,
      "rating": {
        "user_review_count": 453,
        "score_percent": 100,
        "test_rating": "2,0"
      },
      "cheapest_offer": {
        "offer_key": "7abc0f760d8206c9f1c6127689df9ed0",
        "shop_id": "301558",
        "shop_name": "alza.de",
        "shipping_costs": "4,99 €",
        "shipping_is_free": false
      },
      …
    },
    …
  ],
  "pagination": {
    "page": 1,
    "page_size": 36,
    "total_pages": 112,
    "has_more": true,
    "total_results": 4805,
    …
  },
  "category": {
    "id": "3513",
    "title": "Fritteusen"
  },
  …
}

A few details matter when you parse it. The category title and facet names (Hersteller, Produkttyp) are in German, because the source is the German site. price is a number and price_formatted is a display string with a decimal comma, so use price for any calculation. And shipping_costs is a string, not a number, so parse it before adding it to a total.

Note that search matched this query to category 3513 (Fritteusen) on its own, and reports it in the response. This is the first thing to check if results look off.

How do you get the offers for a product?

Pass the id from a search result as product_id to GET /v1/idealo/offers to get the offers for that product. The offer_count in the search result (80 for the Ninja AF500 in the recorded response) gives you a number to compare against what comes back, since the endpoint also takes page and all.

curl "https://api.perceptlayer.com/v1/idealo/offers?product_id=203597427&include_shop_ratings=true" \
  -H "X-API-Key: $API_KEY"
Parameter Type Required Notes
product_id string yes The id from search or products
page integer no Next page of offers
all boolean no Request the full offer list
include_shop_ratings boolean no Add shop ratings to each offer

We haven't recorded an offers response for this guide, so there's no excerpt here. Run the call in the playground on the Idealo offers page with your own key to see the exact fields, and print the keys before you write a parser. That's a better habit than trusting any guide, including this one.

Worked example: from keyword to saved offers

This Python script searches for a keyword, sorts by price, takes the three cheapest products, and fetches the offers for each. It prints what the search response already tells you (title, lowest price, offer count, cheapest shop) and saves each raw offers response to a JSON file for inspection. It needs only requests.

import json
import os
import requests

BASE = "https://api.perceptlayer.com/v1/idealo"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}


def get(path, **params):
    r = requests.get(f"{BASE}/{path}", headers=HEADERS, params=params, timeout=30)
    r.raise_for_status()
    return r.json()


search = get("search", query="air fryer", sort="PRICE_ASC")
offers_by_product = {}

for product in search["results"][:3]:
    cheapest = product.get("cheapest_offer", {})
    print(
        product["title"],
        product["price"],
        product["currency"],
        f'{product["offer_count"]} offers',
        cheapest.get("shop_name"),
    )
    offers_by_product[product["id"]] = get("offers", product_id=product["id"])

for product_id, offers in offers_by_product.items():
    print(product_id, list(offers.keys()))
    with open(f"offers_{product_id}.json", "w") as f:
        json.dump(offers, f, ensure_ascii=False, indent=2)

That is 1 search call plus 3 offers calls: 4 calls × 1 credit = 4 credits, assuming one offers call per product. The final loop prints the top-level keys of each offers response and saves the full body, so you can pick the fields you need before writing real parsing code; the price table is the next step, built from those fields. The search results here are the cheapest matches, not the best matches: use sort=RELEVANCE_DESC (the default in the recorded response) for relevance. Handle failures with the patterns in handling API errors in Python, and read the errors docs for the full list of codes.

What else can you look up for a product?

Once you have a product_id, four more endpoints take it, each at 1 credit. product, reviews (with an optional page) and international-prices take a product_id, and products accepts a list of IDs through ids[] for batch lookups. We haven't recorded responses for these, so check their fields in the playground. Shops have their own pair: shop takes a shop_id, and shop-products takes a shop_id plus a category_id.

Endpoint Required What it adds
/v1/idealo/product product_id Product data for one ID
/v1/idealo/products none (ids[]) Several products in one call
/v1/idealo/reviews product_id Reviews for the product, paged
/v1/idealo/international-prices product_id International prices for the product
/v1/idealo/shop shop_id A shop's profile
/v1/idealo/shop-products shop_id, category_id What one shop lists in a category

Each search result also carries a url field with the product's idealo.de address (for example this Ninja AF500 page), which is handy for spot-checking a result by eye. The shop_id in cheapest_offer (here 301558 for alza.de) is the value the shop endpoints expect. That links the two halves of the data: from a product to the shops selling it, and from a shop back to its catalogue. For discovery without a keyword, brand-products lists products by brand or brand_id, and deals takes a required category_id with an optional deal_type of bargain or short_term.

How much does it cost to monitor prices?

Every Idealo endpoint costs 1 credit per successful call, so cost is the number of calls. The figures below are minimums: they assume one offers call per product. The endpoint also takes page and all, and each extra call you make with them is another credit. Failed calls cost nothing and return X-Credits-Used: 0. A price monitor that refreshes offers for a fixed watchlist spends at least one credit per product per refresh, plus a one-time search or products call to discover the IDs.

Job Calls (minimum) Credits (minimum)
One keyword, offers for the top 3 products 1 + 3 4
200 products, offers refreshed daily for 30 days 200 × 30 × 1 6,000
Same watchlist, refreshed weekly (4 runs) 200 × 4 × 1 800
500 search-plus-offers lookups 500 × 2 × 1 1,000

The free tier's 1,000 monthly credits cover the last row, or the weekly watchlist if every product needs only one call. The daily watchlist (at least 6,000 credits) is a purchase: credits come in prepaid packs starting at 10,000, last 12 months, and have no subscription. See pricing for what credits cost and the credits docs for how they're debited.

If you don't need hourly data, cache responses between runs; the caching guide shows how TTLs turn into saved credits. For paged results, use the pagination guide. For a full scheduler built on a similar source, read building a price tracking agent in Python.

When is the idealo API the wrong tool?

This endpoint set fits one job: you want to compare offers for one product, starting from search results that already show the cheapest shop and its shipping cost. The recorded response is in euros with German-language fields, so that's the market it was recorded against. It's the wrong tool when you need a contractual feed from the shop itself, since Perceptlayer returns publicly available data as found. Check your use case against the site's own terms before building on the data.

The product_id is an idealo ID, so it only works with the idealo endpoints. If you compare idealo prices against another store, plan on matching items yourself; the post on deduplicating listings across sources covers matching without shared IDs. For a US-style product search, the Walmart product search guide is the closer fit, and Mercado Libre covers Latin America.

Two practical limits apply to any live data. Prices change between calls, and a response is what the page showed at that moment. Requests also have no idempotency key, so if a client timeout loses a reply, the call may have succeeded and been billed.

Can an AI agent call the idealo endpoints?

Yes. The Perceptlayer MCP server at https://api.perceptlayer.com/mcp exposes search_endpoints, get_endpoint and call_endpoint. The first two only look up the catalogue and cost nothing; call_endpoint runs an endpoint such as /v1/idealo/search and spends its credits on success only. An agent can then answer "who sells this cheapest?" from live data.

To add it in Claude Code:

claude mcp add --transport http perceptlayer https://api.perceptlayer.com/mcp --header "Authorization: Bearer $API_KEY"

The AI agents docs cover the other clients. Keep in mind that a search response is large (facets, price buckets, related queries), so trim what you hand a model; trimming API responses for LLM context shows how.

Next step: open the playground on the Idealo API page, run a search for a product you care about, then paste its id into the offers endpoint.

APIs in this post

Frequently asked questions

Is there an official idealo API?

The Idealo API on Perceptlayer isn't a feed from the shop itself. Perceptlayer collects data from publicly available sources and returns it as found at the time of the call. If you need contractual terms from the site, ask the site directly and check your use case before building on the data.

How much does an idealo API call cost?

Each of the 13 Idealo endpoints costs 1 credit per successful call. A search followed by an offers lookup is 2 credits. Failed calls cost nothing and return X-Credits-Used: 0. Free accounts get 1,000 credits a month after email verification, with no credit card, and the pricing page lists what paid credits cost.

How do I get all offers for a product?

Call /v1/idealo/offers with the product_id from search. The endpoint also takes page for further results and an all boolean. Compare the offer_count in the search result with what you receive to confirm you've got everything, and print a real response in the playground first to see the field names.

What are the rate limits?

Limits apply per account, counted per minute. Free accounts get 1 request a second (60 a minute), and paying accounts run at least 5 a second (300 a minute). A 429 response includes a Retry-After header with the seconds to wait. The rate limits docs explain how packs set the rate.

Which currency and language do results use?

In the recorded search response the currency is EUR, prices have a numeric price plus a German-formatted price_formatted, and category and facet names are German (Fritteusen, Hersteller). Use the numeric field for calculations. For other countries' prices of the same product, see the international prices endpoint.

  1. Vinted API: Search Second-Hand Items as JSON

    Search Vinted as JSON with 14 optional parameters, then price-check one query across 19 countries. Each call costs 1 credit; failed calls cost nothing.

  2. AliExpress Product API: Search, Reviews and Shipping

    Chain AliExpress search, product, product-reviews and product-shipping, with every required parameter, at 1 credit per call, and cost a 100-product review pull.

  3. Walmart Product Search API: Prices and Product Data

    Search Walmart by keyword and get price, rating, seller and stock as JSON with GET /v1/walmart/search. Parameters, a real response and a credit count.

Start with 1,000 free credits

No password to set. We email you a sign-in link, and your key works on every API.

No credit card. 1,000 free credits a month.