Skip to content

MCP and REST

One question, one answer, for agents too

You create the API key on this page. Four steps: the key, the first request, connecting over MCP or REST, and the limits.

  • Price reads without a key: 10 requests per minute
  • With a key: 60 requests per minute
  • MCP server and REST API with the same answers

1. Create an API key

An API key is the password your AI assistant or bot uses to sign in to Fordeal. You get it right away and it is shown only once, so save it.

The owner's e-mail is the contact of the person responsible for the agent. How it is processed is described on the page Privacy.

2. First request

A request for the lowest price of one product, including shipping to the chosen country.

The samples contain a placeholder key. Once you create a key in step 1, yours is filled in. Without a key the request works too, at 10 requests per minute.

Command line: macOS, Linux, Windows 10 or later.

curl -s "https://fordeal.ai/api/v1/deals/best-price?query=Apple%20iPhone%2017%20256%20GB&deliver_to_country=CZ" \
  -H "Authorization: Bearer fd_live_YOUR_KEY" \
  -H "Accept: application/json"

Below is one call and its shortened answer. headline is the sentence for a person, best.url leads to the shop through /go, and commission_disclosure must be shown to the buyer.

Example answer (illustrative numbers, not today's price)

{"verdict":"buy_now",
 "headline":"Kupte teď v obchodě Datart za 25 990 Kč.",
 "sort":"product",
 "best":{"shop":{"name":"Datart","trust":"verified","rating":0.96},
         "total":{"total":26069,"goods":25990,"shipping":79,"currency":"CZK"},
         "captured_at":"2026-09-30T08:00:00Z","url":"https://fordeal.ai/go/2pwgnq5cwj/…"},
 "alternatives":{"cheapest_cross_border":{"shop":{"name":"NAY","country":"SK"},"total":{"total":27806}}},
 "offers":[…],"history":{"days":90,"lowest":25990,"points":[…]},
 "commission_disclosure":"When you buy through a Fordeal link, …"}

3. Connect over MCP or REST

Streamable HTTP MCP endpoint; add it to Claude, ChatGPT, Cursor or any MCP client.

Addresses

REST request samples

The same tools over HTTP, documented in the OpenAPI file. Results are stored and shareable at /api/v1/deals/results/{slug}. Every offer also carries marketplace (platform, seller, ships-from country, price type; null for an ordinary shop) and total.shippingSource (offer, shop_rule or unknown: where the shipping cost comes from).

GET https://fordeal.ai/api/v1/deals/best-price?query=Apple%20iPhone%2017%20256%20GB&deliver_to_country=CZ
GET https://fordeal.ai/api/v1/deals/best-price?query=Apple%20iPhone%2017%20256%20GB&deliver_to_country=CZ&sort=total
GET https://fordeal.ai/api/v1/deals/history/apple-iphone-17-256-gb?days=365
GET https://fordeal.ai/api/v1/deals/daily?country=CZ&category=televize
GET https://fordeal.ai/api/v1/deals/search?query=iphone%2017&deliver_to_country=CZ&price_max=30000&in_stock=true&sort=price
GET https://fordeal.ai/api/v1/deals/abroad?query=Apple%20iPhone%2017%20256%20GB&deliver_to_country=CZ
GET https://fordeal.ai/api/v1/deals/shops/compared?deliver_to_country=SK
GET https://fordeal.ai/api/v1/digital/compare?category=ai-chat&deliver_to_country=CZ
GET https://fordeal.ai/api/v1/digital/mobile?country=CZ&data_gb=10&minutes=300&no_commitment=true
GET https://fordeal.ai/api/v1/digital/energy?commodity=electricity&distributor=cez-distribuce&rate=D02d&mwh=2.5

4. Limits and terms

The limits apply to MCP and REST together.

Reading needs no key. Every answer carries machine-readable prices: amounts as numbers, ISO 4217 currency, captured_at in ISO 8601, stable product and shop slugs.

  • Without a key: 10 requests per minute per IP address, MCP and REST together.
  • With a key: 60 requests per minute. Generate the key further down this page by entering the agent's name and the owner's e-mail.
  • Over the limit the answer is error.code "rate_limited" with retry_after_seconds.
  • With the live key fd_live_ you also get a test key fd_test_ for the sandbox (simulated providers and fake money of the hidden marketplace); reading prices needs no test mode.

A key is meant for one agent. By using the API you agree to the terms of use. Rules for every answer

In short

The web page, the REST API and the MCP server return the same data: what a person sees, an agent gets. find_best_price with a query and the buyer's country returns the whole card: verdict, main offer (`best`) with product price, shipping and capture time, alternatives and history. Every answer follows the same rules as the website and carries the commission disclosure, which must be shown to the buyer.

Tools

compare_internetIn preparation, unverified: the answer carries status: in_preparation and verified: false; present the result as an estimate, never as a recommendation. Home internet tariffs by monthly price: give the technology, speed and optionally the address or postcode; ranked by the monthly price with the commitment and the one-off fees. In preparation.
search_productsFiltered product search: query or category plus price range, brand, shops, shop country, in stock, on sale, free shipping, minimum shop rating; sort by product price, price with shipping, discount, number of shops or popularity.
cheaper_abroadIs it cheaper in another country? The lowest home offer next to the lowest cross-border one, the saving and what buying abroad means (warranty, returns, delivery days).
list_shopsThe shops compared for a country with rating, rating source and trust label, plus the shops waiting for a feed. Answers "can I trust shop X".
find_best_priceText, model, EAN or a product URL plus deliver_to_country (optionally sort=total to rank with shipping). Returns the card. Send the buyer to best.url and tell them the product price, the shipping and when the price was checked.
get_productA product id you already hold (its slug) plus deliver_to_country: the same card as the product page, without reading a query, so it never lands on another variant. product.variant names the storage, colour, model words and family_id.
product_variantsThe other capacities, colours or sizes of a product, each with a stable id, current, storage, colour, its product price and stock. Pick the exact variant, then call get_product with its id.
price_historyDaily lowest price for up to 365 days plus every current offer. Use it to say whether today is a low.
daily_dealsBiggest price drops of the last 24 hours at rated shops, per country and category.
list_couponsCoupon codes and promotions of compared shops valid today (from the affiliate network eHUB, refreshed every 3 hours), with the validity, the code and the tracked link.
product_rowsThe rows above the product list: deals of the day, trending (new and watched), seasonal gift tips by budget and for whom, with their formulas.
trending_new_productsThe home page's first row: the most searched new products, found by the data (newest model of a line, new in the catalogue, searched, clicked, found on Google, more shops listing it), with the points of every part of the score.
most_searched_productsMost searched products in a country over the last 7 days: Google Trends, our searches and clicks, matched to products with a photo and at least two shops; each row carries the date it was computed.
compare_mobileIn preparation, unverified: the answer carries status: in_preparation and verified: false; present the result as an estimate, never as a recommendation. Mobile tariffs (Czechia and Slovakia) from the operators' official price lists: give data_gb, minutes and optionally no_commitment, five_g, roaming_eu_gb; the cheapest regular price that covers it comes first.
compare_energyHousehold electricity and gas in Czechia: give distributor, rate and yearly MWh; offers ranked by the yearly bill with VAT, split into the regulated and the supplier part, each with the supplier's official price list.
compare_digitalDigital services by price per month: AI subscriptions, API token prices with the cost of a given usage, picture and video tools, streaming, music, VPN, cloud. Prices from official price lists with source and check date.
api_price_breakdownAI API cost split: input, input read from and written into the cache, output and the total per request and month, the other items of the price list (batch discount, long prompts), source and check date.
digital_price_historyRecorded price changes of digital plans (old price, new price, day, source) since tracking_since; nothing back-filled.
compare_energy_from_billElectricity or gas from the values on a bill: distributor, rate, breaker, consumption and the supplier's prices; the same ranking as the comparison, with the saving against today's price list. POST /digital/energy/bill reads the bill (PDF or photo); the file is not stored.
energy_unit_pricesPrice of one kWh of electricity and gas with VAT per distribution area: regulated part, supplier price range, one more kWh and the average with fees, from the official price lists.
energy_price_historyHousehold electricity and gas prices per kWh since 2015 as Eurostat publishes them, half-yearly, with the dataset link.
energy_suppliersEvery household energy supplier with its products, prices from the official price list with dates, and where its customers find the bill.
estimate_appliance_energyYearly kWh and cost of a fridge, a washing machine or heating from the energy label or the building's certificate, at today's price of one more kWh.
energy_watch_statusState of a fixation-end watcher from the token of its e-mail link.
insurance_guideInsurance as a guide: what to compare for each kind and the insurers' official websites, alphabetical; no price, no ranking, no commission (Fordeal is not an insurance intermediary).
price_watch_statusState of one price watch from the link in its e-mail: target, status and when the price last reached it.
check_shop_feedReads a product feed of a shop (address or file) and reports its health and the first issues with a preview of the products. Nothing is stored. Use it before register_shop.
get_shop_registrationStatus of a shop registration by its id: the decision, the feed health and the stored feed report.
get_shop_feed_diagnosticsThe last feed run of a compared shop: how many products were read, what was skipped and why, with the time of the run.

Actions that write

The tools above only read. The ones below write: report_issue may be called by anyone, the account tools only with the signed-in person's access token (Authorization: Bearer, the token the website holds after the e-mail sign-in link). An agent's API key or no key opens no account, and every read and write applies only to the account of the token.

report_issueReports a wrong price, variant, category or shop of one offer. No account needed.
watch_energy_fixation, confirm_energy_watch, cancel_energy_watchFixation-end watcher: the person's e-mail and end date; double opt-in (the person confirms by e-mail), one alert 45 days before the end, cancel link in every mail.
list_my_price_watches, set_price_watch, update_price_watch, delete_price_watchThe person's price watches: list, create, change the target or pause, delete.
list_my_favorites, save_favorite, remove_favoriteThe person's saved products and digital plans.
list_my_comparisons, save_comparison, share_comparison, delete_comparisonThe person's saved comparisons, and a share link for one.

Their REST routes: the same tools under /api/v1/me/… (account) and /api/v1/deals/issues.

POST /api/v1/deals/issues                        report_issue
POST /api/v1/deals/content-notices               report_illegal_content
POST /api/v1/digital/energy/watches              watch_energy_fixation
POST /api/v1/digital/energy/watches/confirm      confirm_energy_watch
POST /api/v1/digital/energy/watches/cancel       cancel_energy_watch
GET /api/v1/me/price-watches                     list_my_price_watches
POST /api/v1/me/price-watches                    set_price_watch
POST /api/v1/me/price-watches/{id}               update_price_watch
POST /api/v1/me/price-watches/{id}/delete        delete_price_watch
GET /api/v1/me/favorites                         list_my_favorites
POST /api/v1/me/favorites                        save_favorite
POST /api/v1/me/favorites/remove                 remove_favorite
GET /api/v1/me/comparisons                       list_my_comparisons
POST /api/v1/me/comparisons                      save_comparison
POST /api/v1/me/comparisons/{id}/share           share_comparison
POST /api/v1/me/comparisons/{id}/delete          delete_comparison
GET /api/v1/me/lists                             list_my_lists
POST /api/v1/me/lists                            create_list
POST /api/v1/me/lists/{id}                       update_list
POST /api/v1/me/lists/{id}/delete                delete_list
POST /api/v1/me/lists/{id}/items                 add_to_list
POST /api/v1/me/lists/{id}/items/remove          remove_from_list
GET /api/v1/me/profile                           get_my_profile
POST /api/v1/me/profile                          update_my_profile
POST /api/v1/me/logout                           sign_out
POST /api/v1/me/account/delete                   delete_my_account
POST /api/v1/price-watches/guest                 watch_product_price
POST /api/v1/price-watches/link                  manage_price_watch
POST /api/v1/shops/register                      register_shop
POST /api/v1/deals/shops/verify-ownership        verify_shop_domain
GET /api/v1/shops/mine                           list_my_shops
GET /api/v1/shops/{slug}/statistics              get_shop_statistics
POST /api/v1/cooperation/inquiries               send_cooperation_inquiry
POST /api/v1/contact/messages                    send_contact_message

Rules every answer follows

  • Ranking is by product price (ČNB rate of the day) and shop trust only; the shipping to the country is on every offer separately and sort=total ranks by the sum. No paid placement.
  • A shop on the ČOI or SOI risk list is never shown. An unrated shop is never best.
  • A price older than 36 hours or an offer with unknown shipping is never best; every offer carries captured_at and blockers.
  • Cross-border offers carry cross_border: EU warranty, returns, support languages.
  • commission_disclosure is part of every answer and must be shown to the buyer.

Examples: requests and answers

Each call as curl (REST) and as an MCP JSON-RPC body, with the answer shortened (arrays show their first element). The test suite runs every one of them against the application, so the field names here are the real ones.

search_products · Search with paging: products matching a query, with total_matches and offset.

REST

curl -s "https://fordeal.ai/api/v1/deals/search?query=iphone+16+128&deliver_to_country=CZ&limit=2&offset=0"

MCP tools/call (POST to the MCP endpoint)

POST https://fordeal.ai/mcp
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_products",
    "arguments": {
      "query": "iphone 16 128",
      "deliver_to_country": "CZ",
      "limit": 2,
      "offset": 0
    }
  }
}

Answer, HTTP 200, shortened

{
  "deliver_to": "CZ",
  "currency": "CZK",
  "total_matches": 40,
  "offset": 0,
  "products": [
    {
      "slug": "apple-iphone-16-128-gb",
      "name": "Apple iPhone 16 128 GB",
      "match": "exact",
      "match_note": null,
      "total": 22990,
      "recommended": true,
      "currency": "CZK",
      "goods": 22990,
      "shipping": 0,
      "shipping_known": true,
      "in_stock": true,
      "shops": 1,
      "shop": {
        "slug": "planeo-cz",
        "name": "Planeo Elektro",
        "country": "CZ",
        "trust": "rated"
      },
      "captured_at": "2026-10-12T12:02:37Z"
    }
  ],
  "next_actions": [
    {
      "tool": "find_best_price",
      "description": "Every offer of the first product with the verdict.",
      "params": {
        "query": "Apple iPhone 16 128 GB",
        "deliver_to_country": "CZ"
      }
    }
  ]
}

find_best_price · Lowest product price for a query: verdict, the recommended offer with its source, shipping and capture time, every offer with its blockers.

REST

curl -s "https://fordeal.ai/api/v1/deals/best-price?query=Apple+iPhone+16+128+GB&deliver_to_country=CZ&locale=en"

MCP tools/call (POST to the MCP endpoint)

POST https://fordeal.ai/mcp
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "find_best_price",
    "arguments": {
      "query": "Apple iPhone 16 128 GB",
      "deliver_to_country": "CZ",
      "locale": "en"
    }
  }
}

Answer, HTTP 200, shortened

{
  "product": {
    "slug": "apple-iphone-16-128-gb",
    "name": "Apple iPhone 16 128 GB",
    "brand": "Apple",
    "category": "mobily",
    "variant": {
      "id": "apple-iphone-16-128-gb",
      "family_id": "line:apple-iphone-16",
      "family_kind": "line",
      "storage": "128 GB",
      "ram": null,
      "color": null,
      "color_id": null,
      "model": [],
      "connectivity": [],
      "size": null
    },
    "variants_url": "/api/v1/deals/products/apple-iphone-16-128-gb/variants"
  },
  "match": "exact",
  "match_note": null,
  "verdict": "buy_now",
  "headline": "Buy now at Planeo Elektro for CZK 22,990 in total.",
  "reasons": [
    "at_90d_low"
  ],
  "warnings": [
    "The shop has customer ratings but no verified-shop badge."
  ],
  "best": {
    "offer_id": "f8edb345-e97e-4599-99e3-3c9240481aee",
    "shop": {
      "slug": "planeo-cz",
      "name": "Planeo Elektro",
      "country": "CZ",
      "trust": "rated",
      "rating": 0.84,
      "rating_source": "google",
      "rating_captured_at": "2026-10-09T11:18:24Z"
    },
    "title": "Apple iPhone 16 128GB Black",
    "source": "scrape",
    "source_name": "planeo-cz-page",
    "price": 22990,
    "currency": "CZK",
    "in_stock": true,
    "condition": "new",
    "delivery_days": null,
    "unknown": [
      {
        "field": "delivery_days",
        "reason": "not_stated"
      }
    ],
    "total": {
      "deliverTo": "CZ",
      "currency": "CZK",
      "goods": 22990,
      "shipping": 0,
      "shippingUnknown": false,
      "shippingApproximate": false,
      "total": 22990,
      "fx": null,
      "crossBorder": false
    },
    "url": "https://fordeal.ai/go/7a2gxvdd36/f8edb345-e97e-4599-99e3-3c9240481aee",
    "direct_url": "https://www.planeo.cz/apple-iphone-16-128gb-black",
    "captured_at": "2026-10-12T12:02:37Z",
    "age_hours": 21.6,
    "stale": false,
    "blockers": []
  },
  "offers": [
    {
      "offer_id": "f8edb345-e97e-4599-99e3-3c9240481aee",
      "shop": {
        "slug": "planeo-cz",
        "name": "Planeo Elektro",
        "country": "CZ",
        "trust": "rated",
        "rating": 0.84,
        "rating_source": "google",
        "rating_captured_at": "2026-10-09T11:18:24Z"
      },
      "title": "Apple iPhone 16 128GB Black",
      "source": "scrape",
      "source_name": "planeo-cz-page",
      "price": 22990,
      "currency": "CZK",
      "in_stock": true,
      "condition": "new",
      "delivery_days": null,
      "unknown": [
        {
          "field": "delivery_days",
          "reason": "not_stated"
        }
      ],
      "total": {
        "deliverTo": "CZ",
        "currency": "CZK",
        "goods": 22990,
        "shipping": 0,
        "shippingUnknown": false,
        "shippingApproximate": false,
        "total": 22990,
        "fx": null,
        "crossBorder": false
      },
      "url": "https://fordeal.ai/go/7a2gxvdd36/f8edb345-e97e-4599-99e3-3c9240481aee",
      "direct_url": "https://www.planeo.cz/apple-iphone-16-128gb-black",
      "captured_at": "2026-10-12T12:02:37Z",
      "age_hours": 21.6,
      "stale": false,
      "blockers": []
    }
  ],
  "hidden_risky_shops": 0,
  "history": {
    "days": 90,
    "currency": "CZK",
    "lowest": 22990,
    "highest": 22990,
    "points": [
      {
        "date": "2026-10-01",
        "price": 22990
      }
    ]
  },
  "deliver_to": "CZ",
  "currency": "CZK",
  "fx_date": "2026-10-12",
  "data_source": "stored",
  "refresh_pending": false,
  "commission_disclosure": "When you buy through a Fordeal link, the shop pays Fordeal a commission. It does not raise your price and it never affects the order: offers are ranked by product price and shop trust only; shipping is shown separately for each offer."
}

get_product · The same card by product id, as the product page shows it.

REST

curl -s "https://fordeal.ai/api/v1/deals/products/apple-iphone-16-128-gb?deliver_to_country=CZ&locale=en"

MCP tools/call (POST to the MCP endpoint)

POST https://fordeal.ai/mcp
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_product",
    "arguments": {
      "product": "apple-iphone-16-128-gb",
      "deliver_to_country": "CZ",
      "locale": "en"
    }
  }
}

Answer, HTTP 200, shortened

{
  "product": {
    "slug": "apple-iphone-16-128-gb",
    "name": "Apple iPhone 16 128 GB",
    "brand": "Apple",
    "category": "mobily",
    "variant": {
      "id": "apple-iphone-16-128-gb",
      "family_id": "line:apple-iphone-16",
      "family_kind": "line",
      "storage": "128 GB",
      "ram": null,
      "color": null,
      "color_id": null,
      "model": [],
      "connectivity": [],
      "size": null
    },
    "variants_url": "/api/v1/deals/products/apple-iphone-16-128-gb/variants"
  },
  "match": "exact",
  "match_note": null,
  "verdict": "buy_now",
  "headline": "Buy now at Planeo Elektro for CZK 22,990 in total.",
  "reasons": [
    "at_90d_low"
  ],
  "warnings": [
    "The shop has customer ratings but no verified-shop badge."
  ],
  "best": {
    "offer_id": "f8edb345-e97e-4599-99e3-3c9240481aee",
    "shop": {
      "slug": "planeo-cz",
      "name": "Planeo Elektro",
      "country": "CZ",
      "trust": "rated",
      "rating": 0.84,
      "rating_source": "google",
      "rating_captured_at": "2026-10-09T11:18:24Z"
    },
    "title": "Apple iPhone 16 128GB Black",
    "source": "scrape",
    "source_name": "planeo-cz-page",
    "price": 22990,
    "currency": "CZK",
    "in_stock": true,
    "condition": "new",
    "delivery_days": null,
    "unknown": [
      {
        "field": "delivery_days",
        "reason": "not_stated"
      }
    ],
    "total": {
      "deliverTo": "CZ",
      "currency": "CZK",
      "goods": 22990,
      "shipping": 0,
      "shippingUnknown": false,
      "shippingApproximate": false,
      "total": 22990,
      "fx": null,
      "crossBorder": false
    },
    "url": "https://fordeal.ai/go/7a2gxvdd36/f8edb345-e97e-4599-99e3-3c9240481aee",
    "direct_url": "https://www.planeo.cz/apple-iphone-16-128gb-black",
    "captured_at": "2026-10-12T12:02:37Z",
    "age_hours": 21.6,
    "stale": false,
    "blockers": []
  },
  "offers": [
    {
      "offer_id": "f8edb345-e97e-4599-99e3-3c9240481aee",
      "shop": {
        "slug": "planeo-cz",
        "name": "Planeo Elektro",
        "country": "CZ",
        "trust": "rated",
        "rating": 0.84,
        "rating_source": "google",
        "rating_captured_at": "2026-10-09T11:18:24Z"
      },
      "title": "Apple iPhone 16 128GB Black",
      "source": "scrape",
      "source_name": "planeo-cz-page",
      "price": 22990,
      "currency": "CZK",
      "in_stock": true,
      "condition": "new",
      "delivery_days": null,
      "unknown": [
        {
          "field": "delivery_days",
          "reason": "not_stated"
        }
      ],
      "total": {
        "deliverTo": "CZ",
        "currency": "CZK",
        "goods": 22990,
        "shipping": 0,
        "shippingUnknown": false,
        "shippingApproximate": false,
        "total": 22990,
        "fx": null,
        "crossBorder": false
      },
      "url": "https://fordeal.ai/go/7a2gxvdd36/f8edb345-e97e-4599-99e3-3c9240481aee",
      "direct_url": "https://www.planeo.cz/apple-iphone-16-128gb-black",
      "captured_at": "2026-10-12T12:02:37Z",
      "age_hours": 21.6,
      "stale": false,
      "blockers": []
    }
  ],
  "hidden_risky_shops": 0,
  "history": {
    "days": 90,
    "currency": "CZK",
    "lowest": 22990,
    "highest": 22990,
    "points": [
      {
        "date": "2026-10-01",
        "price": 22990
      }
    ]
  },
  "deliver_to": "CZ",
  "currency": "CZK",
  "fx_date": "2026-10-12",
  "data_source": "stored",
  "refresh_pending": false,
  "commission_disclosure": "When you buy through a Fordeal link, the shop pays Fordeal a commission. It does not raise your price and it never affects the order: offers are ranked by product price and shop trust only; shipping is shown separately for each offer."
}

product_variants · The variants of the product with stable ids.

REST

curl -s "https://fordeal.ai/api/v1/deals/products/apple-iphone-16-128-gb/variants?deliver_to_country=CZ&locale=en"

MCP tools/call (POST to the MCP endpoint)

POST https://fordeal.ai/mcp
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "product_variants",
    "arguments": {
      "product": "apple-iphone-16-128-gb",
      "deliver_to_country": "CZ",
      "locale": "en"
    }
  }
}

Answer, HTTP 200, shortened

{
  "slug": "apple-iphone-16-128-gb",
  "family_id": "line:apple-iphone-16",
  "family_kind": "line",
  "axes": [
    "storage",
    "color"
  ],
  "currency": "CZK",
  "variants": [
    {
      "id": "apple-iphone-16-128-gb",
      "slug": "apple-iphone-16-128-gb",
      "current": true,
      "storage": "128 GB",
      "size": "128 GB",
      "color": null,
      "color_id": null,
      "total": 22990,
      "in_stock": true,
      "url": "https://fordeal.ai/en/p/apple-iphone-16-128-gb"
    }
  ]
}

price_history · Daily lowest price for 90 days and where each price comes from.

REST

curl -s "https://fordeal.ai/api/v1/deals/history/apple-iphone-16-128-gb?days=90&currency=CZK"

MCP tools/call (POST to the MCP endpoint)

POST https://fordeal.ai/mcp
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "price_history",
    "arguments": {
      "product": "apple-iphone-16-128-gb",
      "days": 90,
      "currency": "CZK"
    }
  }
}

Answer, HTTP 200, shortened

{
  "product": {
    "slug": "apple-iphone-16-128-gb",
    "name": "Apple iPhone 16 128 GB",
    "variant": {
      "id": "apple-iphone-16-128-gb",
      "family_id": "line:apple-iphone-16",
      "family_kind": "line",
      "storage": "128 GB",
      "ram": null,
      "color": null,
      "color_id": null,
      "model": [],
      "connectivity": [],
      "size": null
    }
  },
  "history": {
    "days": 90,
    "currency": "CZK",
    "lowest": 22990,
    "highest": 22990,
    "points": [
      {
        "date": "2026-10-01",
        "price": 22990
      }
    ]
  },
  "offers": [
    {
      "shop": "Planeo Elektro",
      "shop_slug": "planeo-cz",
      "title": "Apple iPhone 16 128GB Black",
      "price": 22990,
      "currency": "CZK",
      "condition": "new",
      "source_name": "planeo-cz-page",
      "in_history": true,
      "captured_at": "2026-10-12T12:02:37Z"
    }
  ]
}

compare_digital · Digital services by price per month, each with its official price list and check date.

REST

curl -s "https://fordeal.ai/api/v1/digital/compare?category=ai-chat&deliver_to_country=CZ"

MCP tools/call (POST to the MCP endpoint)

POST https://fordeal.ai/mcp
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "compare_digital",
    "arguments": {
      "category": "ai-chat",
      "deliver_to_country": "CZ"
    }
  }
}

Answer, HTTP 200, shortened

{
  "category": "ai-chat",
  "currency": "CZK",
  "fx_date": "2026-10-12",
  "rows": [
    {
      "id": "claude-free",
      "provider": "Anthropic",
      "service": "Claude",
      "plan": "Free",
      "monthly": {
        "amount": 0,
        "currency": "EUR"
      },
      "monthlyLocal": {
        "amount": 0,
        "currency": "CZK",
        "rate": 24.39,
        "rateDate": "2026-10-12"
      },
      "sourceUrl": "https://claude.com/pricing",
      "verifiedOn": "2026-10-05"
    }
  ]
}

price_history · Unknown product: HTTP 404, error.code not_found.

REST

curl -s "https://fordeal.ai/api/v1/deals/history/no-such-product"

MCP tools/call (POST to the MCP endpoint)

POST https://fordeal.ai/mcp
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "price_history",
    "arguments": {
      "product": "no-such-product"
    }
  }
}

Answer, HTTP 404, shortened

{
  "error": {
    "code": "not_found",
    "message": "unknown product no-such-product",
    "fix": "Use `product.slug` from a find_best_price answer."
  }
}

/deals/search · A wrong parameter: HTTP 400, error.code validation with the list of issues.

REST

curl -s "https://fordeal.ai/api/v1/deals/search?query=iphone&limit=abc"

Answer, HTTP 400, shortened

{
  "error": {
    "code": "validation",
    "message": "invalid request: limit: Invalid input: expected number, received string",
    "fix": "Fix the listed fields. GET /api/openapi.json documents every parameter.",
    "details": {
      "issues": [
        "limit: Invalid input: expected number, received string"
      ]
    }
  }
}

/deals/shops/compared · Over the limit: HTTP 429 with Retry-After.

REST

curl -s "https://fordeal.ai/api/v1/deals/shops/compared?country=CZ"

Answer, HTTP 429, shortened

{
  "error": {
    "code": "rate_limited",
    "message": "rate limit of 10 requests per minute reached",
    "fix": "Wait 42 s and retry (Retry-After). Without an API key the limit is 10 requests per minute per IP address; generate a free key at https://fordeal.ai/agents#klic and send Authorization: Bearer <key> for 60 per minute.",
    "details": {
      "limit_per_min": 10,
      "retry_after_seconds": 42,
      "window_seconds": 60,
      "limit": 10,
      "remaining": 0,
      "reset": 42,
      "reset_at": "2026-10-28T09:15:00.000Z",
      "anonymous": true,
      "get_a_key": "https://fordeal.ai/agents#klic"
    }
  }
}

Paging, limits, errors and unknown values

Paging

search_products and GET /deals/searchlimit (1 to 100, default 20) and offset (default 0); total_matches counts every match before paging.
GET /deals/productslimit up to 500 and offset; total counts the matching products. facets=true adds brands, shops, price range and attribute values over the whole filtered list.
A page past the end returns an empty list with the same total.

Limits

Without a key10 requests per minute per IP address, MCP tool calls and REST together.
With a key60 requests per minute.
Over the limitHTTP 429 with a Retry-After header in seconds, error.code rate_limited and error.details.retry_after_seconds, over MCP too.

Errors

  • Every error has the shape {"error":{"code","message","fix"}}: code is stable and machine-readable, fix says what to change.
  • validation 400 (details.issues lists the wrong parameters), country_not_supported 400, invalid_input 400, unauthorized 401, forbidden 403, not_found 404, rate_limited 429, not_available 503.
  • Over MCP an error is a tool result with isError: true and the same body in structuredContent.

Unknown values, estimates and stale data

A value we do not know is null and says why: each offer lists unknown[] (delivery_days not_stated, shipping not_stated or approximate, shop_rating unrated).
total.shippingUnknown truethe total is the goods price only and the offer is never best; total.shippingApproximate true: shipping is the shop's lowest stated rate, an estimate.
Every offer carries captured_at and age_hours; stale is true after 36 hours and such an offer is never best; refresh_pending is true while prices are being read again.
match close with match_notethe product is the nearest variant, not the one asked for; product.variant and product_variants give the exact ids.
history.since is the first day with dataa 90-day window may hold fewer days.

Answer fields, estimates and pages

  • labels on every offer, the same words the website prints: lowest_price only on the lowest product price among the new offers shown; recommended on the trust-recommended offer when it is not the lowest product price (never call it the cheapest); lowest_verified_total on the cheapest total with a stated (not "from") shipping when it is not the lowest product price.
  • shipping_is_estimate true: the shipping is only a "from" rate or unknown, so the total is a lower bound; saving_is_estimate true (an offer's savings_vs_best, recommended_surcharge): the difference rests on such a shipping. Say "estimated saving at the stated minimum shipping", never a certain saving.
  • saving_kind is always "estimate" where a saving or difference is stated (an offer's savings_vs_best, recommended_surcharge, a cross-border saving, an energy saving_year): it is a difference at the prices and shipping captured on the days in saving_basis, never a guaranteed result. Write "estimated saving" and name the capture date, not "you save".
  • price_verdict {level low|usual|high|short_history|stale, percentile, days, basis} on find_best_price, get_product and price_history rates the latest price against the last 90 days of our own captured daily lows. Under 14 days of history it makes no judgement (short_history); it is never a discount claim.
  • daily_deals and GET /deals/daily list the biggest measured drops of the last 24 hours at rated shops, spread over shops and categories (max_per_shop, the website asks 4; also category, country, min_percent); the pool for Slovakia holds the euro shops that deliver there.
  • report_issue and POST /deals/issues take the offer_id of the offer in question (from the card), so a wrong price or variant of one row reaches the person who reads the queue with that row; the website has the same report control on every offer row.
  • The pages "cheapest X" (/nejlevnejsi/<model>) and "X vs Y" (/srovnani/<a>-vs-<b>) have no endpoints of their own: they read GET /deals/products (query, category, slugs, deliver_to_country; search_products, product_variants), and compare_digital and compare_mobile for services and operators. Ask the same question with the same tools.
  • Links to a provider on a /digitalni comparison go through /go/plan/<id>, a counted redirect (plan key, page type, our own page; nothing personal; robots flagged). GET /deals/plan-clicks/{kind}/{id} (kind plan|energy|insurance|mobile) returns the provider URL without counting; an offer's own link is its url (/go/<shop>/<offer_id>).
  • GET /deals/coverage (per shop) and GET /deals/coverage/groups (per category group) give today's coverage: products with a stored price, shops pricing and shops waiting for a feed. The numbers change daily, so read them instead of quoting a figure from a document.