---
title: "Idealo API: Compare Product Prices Across Shops as JSON"
description: "Search idealo.de by keyword, then pass a product_id to the offers endpoint. Endpoints, parameters, a real search response and the cost at 1 credit per call."
url: https://perceptlayer.com/blog/idealo-api-price-comparison-json
---

[Blog](https://perceptlayer.com/blog) / [API guides](https://perceptlayer.com/blog/category/api-guides)

# Idealo API: Compare Product Prices Across Shops as JSON

22 Oct 2026 Perceptlayer 9 min read

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.

## Key takeaways

-   `/v1/idealo/search` returns products with `price`, `offer_count` and a `cheapest_offer` block (shop name, shipping cost) in a single call.
-   The `id` from a search result is the `product_id` that the product, offers, reviews and international prices endpoints take.
-   Idealo's 13 endpoints cost 1 credit each, so one search plus one offers call is 2 credits.
-   Prices come back as numbers ( `162.9`) with a currency code, and as formatted German-style strings ( `162,90 €`).
-   You get 1,000 free credits a month after verifying an email, enough for 500 search-plus-offers lookups.

## What does the idealo API return?

The [Idealo API](https://perceptlayer.com/apis/idealo) on Perceptlayer exposes 13 endpoints on the price comparison site [idealo.de](https://www.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](https://perceptlayer.com/verticals/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](https://perceptlayer.com/blog/google-shopping-api-product-prices).

## 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](https://perceptlayer.com/signup) 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](https://docs.perceptlayer.com/authentication).

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

```bash
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](https://docs.perceptlayer.com/requests).

## 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 `…`.

```json
{
  "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`.

```bash
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](https://perceptlayer.com/apis/idealo/offers) 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`.

```python
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](https://perceptlayer.com/blog/handle-web-data-api-errors-python), and read [the errors docs](https://docs.perceptlayer.com/errors) 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](https://www.idealo.de/preisvergleich/OffersOfProduct/203597427_-af500-ninja.html)), 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`](https://perceptlayer.com/apis/idealo/brand-products) lists products by `brand` or `brand_id`, and [`deals`](https://perceptlayer.com/apis/idealo/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](https://perceptlayer.com/pricing) for what credits cost and [the credits docs](https://docs.perceptlayer.com/credits) for how they're debited.

If you don't need hourly data, cache responses between runs; the [caching guide](https://perceptlayer.com/blog/cache-web-data-api-responses) shows how TTLs turn into saved credits. For paged results, use the [pagination guide](https://perceptlayer.com/blog/paginate-web-data-api-python). For a full scheduler built on a similar source, read [building a price tracking agent in Python](https://perceptlayer.com/blog/price-tracking-agent-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](https://perceptlayer.com/blog/deduplicate-listings-across-sources) covers matching without shared IDs. For a US-style product search, the [Walmart product search guide](https://perceptlayer.com/blog/walmart-product-search-api) is the closer fit, and [Mercado Libre](https://perceptlayer.com/blog/mercado-libre-api-product-search) 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:

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

The [AI agents docs](https://docs.perceptlayer.com/ai-agents) 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](https://perceptlayer.com/blog/trim-api-responses-llm-context) shows how.

Next step: open the playground on the [Idealo API page](https://perceptlayer.com/apis/idealo), run a search for a product you care about, then paste its `id` into the offers endpoint.

## APIs in this post

-   [Idealo **1 credit per call** · 13 endpoints](https://perceptlayer.com/apis/idealo)

## 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](https://perceptlayer.com/pricing) 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](https://docs.perceptlayer.com/rate-limits) 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](https://perceptlayer.com/apis/idealo/international-prices).

price comparison idealo europe ecommerce offers

## More from the blog

1.  [API guides](https://perceptlayer.com/blog/category/api-guides) 14 Oct 2026 Perceptlayer 6 min read
    
    ## [Vinted API: Search Second-Hand Items as JSON](https://perceptlayer.com/blog/vinted-api-search-items-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.  [API guides](https://perceptlayer.com/blog/category/api-guides) 2 Oct 2026 Perceptlayer 6 min read
    
    ## [AliExpress Product API: Search, Reviews and Shipping](https://perceptlayer.com/blog/aliexpress-api-product-search-reviews)
    
    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.  [API guides](https://perceptlayer.com/blog/category/api-guides) 21 Aug 2026 Updated 26 Oct 2026 Perceptlayer 7 min read
    
    ## [Walmart Product Search API: Prices and Product Data](https://perceptlayer.com/blog/walmart-product-search-api)
    
    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.
