# Trovaprezzi.it API — Italy's price comparison: search offers, every shop's price, shipping and total for a product, specs and 6-month price history

> Keyword search on trovaprezzi.it. The answer is a list of shop OFFERS (each with price, shipping, total, availability, shop and its rating) — trovaprezzi's search lists offers, not catalogue entries. `result_type` tells where the query landed: `product` (an exact product match — `product.product_id` then works in `product`, `offers`, `price_history`), `offer_list` (a curated offer list for that query) or `category_choice` (the query spans several categories: no offers, but the categories with their offer counts and the catalogue products trovaprezzi proposes, each with a product_id for `offers`). No match answers an empty list with total 0. Offers that belong to a catalogue product carry `variant_product_id`.
> ReefAPI engine `trovaprezzi` · 4 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/trovaprezzi/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http). Send the key as `Authorization: Bearer <key>`, or put it in the URL (`?key=<key>`) when the client has no header field, as ChatGPT does.

## Endpoints

### POST https://api.reefapi.com/trovaprezzi/v1/search — 3 credits
Keyword search on trovaprezzi.it. The answer is a list of shop OFFERS (each with price, shipping, total, availability, shop and its rating) — trovaprezzi's search lists offers, not catalogue entries. `result_type` tells where the query landed: `product` (an exact product match — `product.product_id` then works in `product`, `offers`, `price_history`), `offer_list` (a curated offer list for that query) or `category_choice` (the query spans several categories: no offers, but the categories with their offer counts and the catalogue products trovaprezzi proposes, each with a product_id for `offers`). No match answers an empty list with total 0. Offers that belong to a catalogue product carry `variant_product_id`.

**Parameters:**
- `query` (string, required) — Search words, as typed in trovaprezzi's search box (Italian or brand/model names, e.g. `lavatrice 9 kg`, `cuffie bluetooth`, `iphone 17`).
- `sort` (enum, optional, default "relevance") — Offer order. `relevance` keeps trovaprezzi's own default for that page (price ascending on product pages, popularity on curated lists). [one of: relevance, price_asc, price_desc, popularity, total_price_asc]
- `min_price` (integer, optional) — Minimum item price in EUR (whole euros).
- `max_price` (integer, optional) — Maximum item price in EUR (whole euros).
- `filter` (string, optional) — One facet key from `offer_filters` / `facets` of a previous answer (e.g. a brand `jabra`, a memory size `256gb`, a colour `blu-colore`). One value per call.
- `page` (integer, optional, default 1) — Offer page, 20 offers per page. A page past the last answers NOT_FOUND.

**Returns:** result_type (product|offer_list|category_choice|none), total (the site's own offer count), page, has_more, results[]{position, offer_id, title, description, image, price, shipping_cost, shipping_text, total_price, total_mismatch, currency=EUR, availability (available|limited), availability_text, is_secondary_offer, shop{id, name, url, logo, rating (0-5), review_count, badges[]}, payment_methods[], variant_product_id, offer_url} + product{product_id, title, url} (when the query matched a product) + categories[]{category_id, category_name, offer_count, is_main, url} + products[]{product_id, title, price_from, image, url} (category_choice) + facets[]{group, key, label, count} + list_title + landing_url

**Example request body:**
```json
{
  "query": "lavatrice 9 kg"
}
```

### POST https://api.reefapi.com/trovaprezzi/v1/product — 3 credits
One trovaprezzi product page: title, brand, images, description, category path, the lowest price (checked against the page's structured data and the first offer), the highest offer price, how many offers, the product's review score and count, the full spec sheet (group / label / value), the offer filters with their counts (memory, colour, condition…) and the variant id whose price history the page charts. Use `offers` for the per-shop list.

**Parameters:**
- `product_id` (string, optional) — Trovaprezzi product id `<category>/<product>` — the part of a product URL around `/prezzi-scheda-prodotto/` (trovaprezzi.it/cellulari/prezzi-scheda-prodotto/apple_iphone_17 → `cellulari/apple_iphone_17`). Returned by `search` as `product.product_id` and per offer as `variant_product_id`. Provide product_id OR url.
- `url` (string, optional) — A trovaprezzi.it product page URL; alternative to product_id.

**Returns:** product{product_id, title, brand, url, image, images[], description, category_path[]{name, url}, lowest_price, highest_price, currency=EUR, offer_count, availability, rating, review_count, price_mismatch, price_witnesses, specs[]{group, label, value}, offer_filters[]{group, key, label, count}, price_history_variant}

**Example request body:**
```json
{
  "product_id": "cellulari/apple_iphone_17"
}
```

### POST https://api.reefapi.com/trovaprezzi/v1/offers — 3 credits
Every shop offer for one trovaprezzi product, 20 per page, in the order you ask for: item price, shipping cost (0 when free), the site's own total, availability, the shop (id, name, page, logo, star rating 0-5, review count, Trusted / Feedaty badges), accepted payment methods, the offer's own title and image. Filters: price range and one offer facet (memory size, colour…). `total` is the site's own count for the filter you set.

**Parameters:**
- `product_id` (string, optional) — Trovaprezzi product id `<category>/<product>` — the part of a product URL around `/prezzi-scheda-prodotto/` (trovaprezzi.it/cellulari/prezzi-scheda-prodotto/apple_iphone_17 → `cellulari/apple_iphone_17`). Returned by `search` as `product.product_id` and per offer as `variant_product_id`. Provide product_id OR url.
- `url` (string, optional) — A trovaprezzi.it product page URL; alternative to product_id.
- `sort` (enum, optional, default "relevance") — Offer order. `relevance` keeps trovaprezzi's own default for that page (price ascending on product pages, popularity on curated lists). [one of: relevance, price_asc, price_desc, popularity, total_price_asc]
- `min_price` (integer, optional) — Minimum item price in EUR (whole euros).
- `max_price` (integer, optional) — Maximum item price in EUR (whole euros).
- `filter` (string, optional) — One facet key from `offer_filters` / `facets` of a previous answer (e.g. a brand `jabra`, a memory size `256gb`, a colour `blu-colore`). One value per call.
- `page` (integer, optional, default 1) — Offer page, 20 offers per page. A page past the last answers NOT_FOUND.

**Returns:** product{product_id, title, url, lowest_price, offer_count} + total, page, has_more, offers[]{position, offer_id, title, description, image, price, shipping_cost, shipping_text, total_price, total_mismatch, currency=EUR, availability, availability_text, is_secondary_offer, shop{id, name, url, logo, rating, review_count, badges[]}, payment_methods[], variant_product_id, offer_url} + count

**Example request body:**
```json
{
  "product_id": "cellulari/apple_iphone_17"
}
```

### POST https://api.reefapi.com/trovaprezzi/v1/price_history — 3 credits
Daily lowest-price history of a trovaprezzi product over the last 6 months, as the site charts it (Andamento prezzi), plus today's price and shop, yesterday's price, the 6-month mean and the 6-month high with its date. Trovaprezzi charts ONE variant per product (the variant of the best offer, e.g. 256 GB) — the answer names it.

**Parameters:**
- `product_id` (string, optional) — Trovaprezzi product id `<category>/<product>` — the part of a product URL around `/prezzi-scheda-prodotto/` (trovaprezzi.it/cellulari/prezzi-scheda-prodotto/apple_iphone_17 → `cellulari/apple_iphone_17`). Returned by `search` as `product.product_id` and per offer as `variant_product_id`. Provide product_id OR url.
- `url` (string, optional) — A trovaprezzi.it product page URL; alternative to product_id.
- `variant` (string, optional) — The variant id to chart, as returned by `product` in `price_history_variant`. With it, only the chart is fetched (one request instead of two).

**Returns:** product{product_id, title, url} + variant + points[]{date, lowest_price} + count + first_date + last_date + today_price + today_shop + yesterday_price + mean_price_6m + max_price_6m + max_price_note + all_time_lowest{price, date} + currency=EUR

**Example request body:**
```json
{
  "product_id": "cellulari/apple_iphone_17"
}
```

## At scale
- **Volume:** 5M+ requests a day, measured at 60 requests a second across the fleet with no
  central bottleneck. Per-key limits are raised for high-volume accounts; volume pricing on request.
- **Missing a source:** tell us a site we do not cover and it becomes an engine. A customer asked
  for bestprice.gr on 21 Sep 2026 and it was in the catalog on 22 Sep.
- **Support:** 2 minute median time from a question in the live chat to the first answer. Setup
  help included, no support tier to buy.
- **One key, one credit pool** across every API. No per-site plans, no separate subscriptions.

## More
- Try it live, no code: https://reefapi.com/playground?engine=trovaprezzi
- Human docs page: https://reefapi.com/docs/trovaprezzi
- Overview page: https://reefapi.com/trovaprezzi-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
