# Ricardo API scraper - Switzerland's #1 marketplace (ricardo.ch): auction and fixed-price article search with the current asking price, buy-now price, bid count, condition, shipping and pickup, seller and promoted flags; the live bid ladder and full bid history for any article; the seller's listings; the category tree; and keyword suggestions. Swiss francs, de/fr/it. No account, no browser.

> Search ricardo.ch by keyword and/or category: article id, title, image, condition, the current asking price (next bid) and buy-now price in CHF, bid count, closing time, shipping cost and pickup location, seller id and promoted/highlight flags. Filter by offer type (auction / buy-now), condition, shipping or pickup, price range, location (zip + radius), seller type and 'has bids'; sort by relevance, ending soon, newest, price or bids. Promoted 'Top-Angebot' rows are dropped and counted; a misspelling returns its matches plus the site's spelling suggestion.
> ReefAPI engine `ricardo` · 5 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/ricardo/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, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /ricardo/v1/search — 1 credit
Search ricardo.ch by keyword and/or category: article id, title, image, condition, the current asking price (next bid) and buy-now price in CHF, bid count, closing time, shipping cost and pickup location, seller id and promoted/highlight flags. Filter by offer type (auction / buy-now), condition, shipping or pickup, price range, location (zip + radius), seller type and 'has bids'; sort by relevance, ending soon, newest, price or bids. Promoted 'Top-Angebot' rows are dropped and counted; a misspelling returns its matches plus the site's spelling suggestion.

**Parameters:**
- `query` (string, optional) — Free-text keyword as typed into ricardo's search box (de/fr/it).
- `category` (string, optional) — A ricardo category: its slug (velos-82249), a /c/<slug>/ URL, or a numeric id (resolved to the slug for `language`). `categories` and search rows list them. Combine with query to search within a category.
- `offer_type` (enum, optional) — auction, fixed_price or auction_with_buynow. [one of: auction, fixed_price, auction_with_buynow]
- `condition` (array, optional) — One or more of new, like_new, used, defective, antique. [one of: new, like_new, used, defective, antique]
- `shipping` (enum, optional) — free_shipping, paid_shipping or pickup. [one of: free_shipping, paid_shipping, pickup]
- `seller_type` (enum, optional) — private, private_commercial or dealer. [one of: private, dealer]
- `price_min` (number, optional) — Lowest item price in CHF (bid or buy-now).
- `price_max` (number, optional) — Highest item price in CHF.
- `zip_code` (string, optional) — Swiss postcode to search around (with radius).
- `radius` (integer, optional) — Kilometres around zip_code.
- `with_bids_only` (boolean, optional) — Only auctions that already have at least one bid.
- `sort` (enum, optional, default "relevance") — Order. Only orderings measured to change the results are accepted. [one of: relevance, ending_soon, newest, price_asc, price_desc, most_bids, total_price_asc, total_price_desc]
- `page` (integer, optional, default 1) — Result page, 1-based (60 articles per page). A page past the end returns an empty list.
- `include_sponsored` (boolean, optional, default false) — ricardo promotes 'Top-Angebot' articles at the top, ignoring the sort. They are dropped by default and counted in sponsored_dropped; true returns them with is_promoted: true. count is the organic rows.
- `language` (enum, optional, default "de") — Site language for titles and category slugs: de, fr or it (ricardo.ch is Swiss). [one of: de, fr, it]
- `max_rotations` (integer, optional, default 5) — Advanced: how many fresh exits to try when Cloudflare challenges (1-6).

**Returns:** articles[]{article_id, title, url, image, thumbnail, category_id, condition (new|like_new|used|defective|antique), currency (CHF), offer_type (auction|fixed_price|auction_with_buynow), is_auction, is_buy_now, next_bid_price (the current ASKING price / next bid, CHF; NOT the current highest bid), current_bid (null on rows - use article/bids), bids_count, has_bids, buy_now_price, can_make_offer, money_guard, start_date, end_date, created_date, seller_id, brand, size, product_type, co2_savings, shipping[]{method (pickup|shipping|freight), cost, currency, zip_code, city}, pickup_location{zip_code, city}, is_promoted, promo_tier, highlight}, count, total_results, sponsored_dropped, spellcheck{from,to,corrected_total}, page, page_size, has_more

**Example request body:**
```json
{
  "query": "velo"
}
```

### POST /ricardo/v1/seller/articles — 1 credit
Every live article a ricardo seller currently has listed, by seller nickname - same rows as search, with the same filters and sorts. ricardo does not publish a browser-free seller rating/score.

**Parameters:**
- `seller` (string, required) — The seller's ricardo nickname (a search/bids row's seller nickname).
- `offer_type` (enum, optional) — auction, fixed_price or auction_with_buynow. [one of: auction, fixed_price, auction_with_buynow]
- `condition` (array, optional) — One or more of new, like_new, used, defective, antique. [one of: new, like_new, used, defective, antique]
- `shipping` (enum, optional) — free_shipping, paid_shipping or pickup. [one of: free_shipping, paid_shipping, pickup]
- `price_min` (number, optional) — Lowest item price in CHF (bid or buy-now).
- `price_max` (number, optional) — Highest item price in CHF.
- `sort` (enum, optional, default "relevance") — Order. Only orderings measured to change the results are accepted. [one of: relevance, ending_soon, newest, price_asc, price_desc, most_bids, total_price_asc, total_price_desc]
- `page` (integer, optional, default 1) — Result page, 1-based (60 articles per page). A page past the end returns an empty list.
- `include_sponsored` (boolean, optional, default false) — ricardo promotes 'Top-Angebot' articles at the top, ignoring the sort. They are dropped by default and counted in sponsored_dropped; true returns them with is_promoted: true. count is the organic rows.
- `language` (enum, optional, default "de") — Site language for titles and category slugs: de, fr or it (ricardo.ch is Swiss). [one of: de, fr, it]
- `max_rotations` (integer, optional, default 5) — Advanced: how many fresh exits to try when Cloudflare challenges (1-6).

**Returns:** articles[]{article_id, title, url, image, thumbnail, category_id, condition (new|like_new|used|defective|antique), currency (CHF), offer_type (auction|fixed_price|auction_with_buynow), is_auction, is_buy_now, next_bid_price (the current ASKING price / next bid, CHF; NOT the current highest bid), current_bid (null on rows - use article/bids), bids_count, has_bids, buy_now_price, can_make_offer, money_guard, start_date, end_date, created_date, seller_id, brand, size, product_type, co2_savings, shipping[]{method (pickup|shipping|freight), cost, currency, zip_code, city}, pickup_location{zip_code, city}, is_promoted, promo_tier, highlight}, count, total_results, sponsored_dropped, spellcheck{from,to,corrected_total}, page, page_size, has_more

### POST /ricardo/v1/article/bids — 1 credit
The live bid ladder and full bid history for one article: current highest bid, start price, next minimum bid, bid increment, bid count, the time left, and every bid (amount, masked bidder nick, time, winning/autobid) - all in CHF. This is ricardo's auction core; the rich static record (description, photo gallery, seller score) is not available browser-free (see the docs).

**Parameters:**
- `article_id` (string, required) — The ricardo article id (the number in an article URL), or the URL itself.
- `language` (enum, optional, default "de") — Site language for titles and category slugs: de, fr or it (ricardo.ch is Swiss). [one of: de, fr, it]
- `max_rotations` (integer, optional, default 5) — Advanced: how many fresh exits to try when Cloudflare challenges (1-6).

**Returns:** article_id, currency (CHF), current_bid (highest bid, null if none), start_price, next_minimum_bid, bid_increment, maximum_bid, bids_count, has_bids, end_date, remaining_time_seconds, is_open, bids[]{bid_id, amount, currency, time, bidder (masked), is_winning, is_autobid, transaction_method}

**Example request body:**
```json
{
  "article_id": "1308678306"
}
```

### POST /ricardo/v1/categories — 1 credit
ricardo's category tree in the chosen language: id, name, slug, parent id and top-level flag. Use a slug (or id) as search's category. Filter by parent_id, or top_level for the top categories only.

**Parameters:**
- `parent_id` (integer, optional) — Only categories directly under this category id.
- `top_level` (boolean, optional, default false) — Only the ~28 top-level categories.
- `language` (enum, optional, default "de") — Site language for titles and category slugs: de, fr or it (ricardo.ch is Swiss). [one of: de, fr, it]
- `max_rotations` (integer, optional, default 5) — Advanced: how many fresh exits to try when Cloudflare challenges (1-6).

**Returns:** categories[]{category_id, name, display_name, slug, parent_id, is_top_level}, count

**Example request body:**
```json
{
  "top_level": true
}
```

### POST /ricardo/v1/suggest — 1 credit
ricardo's own keyword suggestions for the start of a search term, each with the category it points to when ricardo attaches one.

**Parameters:**
- `query` (string, required) — The start of a keyword.
- `language` (enum, optional, default "de") — Site language for titles and category slugs: de, fr or it (ricardo.ch is Swiss). [one of: de, fr, it]
- `max_rotations` (integer, optional, default 5) — Advanced: how many fresh exits to try when Cloudflare challenges (1-6).

**Returns:** suggestions[]{label, type, category_id, category_name, category_slug}, count

**Example request body:**
```json
{
  "query": "velo"
}
```

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