# buycycle Used Bike & Sports Gear Marketplace (Europe)

> Search buycycle, Europe's largest marketplace for pre-owned bikes and sports gear: ~125,000 live listings from private sellers and shops across 28 storefront countries. Free text plus the site's own filters — department, discipline, category, brand, model family, frame/wheel/clothing/shoe size, frame material, brake type, shifting type, colour, condition, seller type, the country the item is in, price, model year, e-bike, frameset and high-demand — and its four working sort orders. Nothing is required: with no parameters it browses the live catalogue. Bike-specific values (frame size, model year, groupset, frameset flag, discipline) come back as their own fields, not buried in the title.
> ReefAPI engine `buycycle` · 6 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/buycycle/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/buycycle/v1/search — 2 credits
Search buycycle, Europe's largest marketplace for pre-owned bikes and sports gear: ~125,000 live listings from private sellers and shops across 28 storefront countries. Free text plus the site's own filters — department, discipline, category, brand, model family, frame/wheel/clothing/shoe size, frame material, brake type, shifting type, colour, condition, seller type, the country the item is in, price, model year, e-bike, frameset and high-demand — and its four working sort orders. Nothing is required: with no parameters it browses the live catalogue. Bike-specific values (frame size, model year, groupset, frameset flag, discipline) come back as their own fields, not buried in the title.

**Parameters:**
- `query` (string, optional) — Free text, matched the way the site's own search box matches it (brand, model, family, component). Leave it out to browse the whole catalogue with filters only.
- `main_type` (array, optional) — Top-level department. One or more of: ball-sports, bikes, cycling-gear, other, outdoor, racket-sports, running, water-sports, winter-sports. [one of: ball-sports, bikes, cycling-gear, other, outdoor, racket-sports, running, water-sports, winter-sports]
- `discipline` (array, optional) — The riding/sport discipline slug a listing sits under: road-gravel, mountainbike, urban-touring, wheels, drivetrain, clothing, running-shoes, skiing… List the live set with the `filters` action.
- `category` (array, optional) — Leaf category slug (road, gravel, enduro, crosscountry, helmet, saddle…). `filters` lists every live one with its count.
- `brand` (array, optional) — Brand slug, lower-case and hyphenated as buycycle writes it (specialized, canyon, cannondale, santa-cruz). Several brands are OR-ed together.
- `family` (array, optional) — Model family slug within a brand (tarmac, aeroad, stumpjumper). `filters` lists them.
- `size` (array, optional) — One size vocabulary covers the whole site: bike frame sizes (xxxs, xxs, xs, s, m, l, xl, xxl, one-size-bike, youth), wheel sizes (26, 27-5-650b, 28-700c, 29), clothing (clothing-size-s … 3xl), shoes (eu-42, eu-42-5) and helmets (helmet-size-m). `filters` returns the live list grouped per vocabulary.
- `frame_material` (array, optional) — Frame material. [one of: carbon, aluminum, steel, titanium, magnesium]
- `brake_type` (array, optional) — Brake system (bikes and framesets). [one of: disc, rim, coaster, drum, other]
- `shifting` (array, optional) — Shifting system (bikes and framesets). [one of: mechanical, electronic, other]
- `colour` (array, optional) — Colour, given as the site's own swatch code: 000000 black, FFFFFF white, 3B82F6 blue, D1D5DB light grey, EF4444 red, 80BE70 green, F59E0B orange, 9A2DF0 purple. A listing carries one swatch, the one the seller picked. [one of: 000000, FFFFFF, 3B82F6, D1D5DB, EF4444, 80BE70, F59E0B, 9A2DF0]
- `condition` (array, optional) — Seller-declared condition. NEW is the site's own top grade for an unused item, then VERY_GOOD, GOOD, FAIR. [one of: NEW, VERY_GOOD, GOOD, FAIR]
- `seller_type` (array, optional) — Private seller or commercial shop. [one of: private, commercial]
- `country` (array, optional) — Where the item physically is, as an ISO-2 code (de, fr, it, es, nl, at, ch…). This is the listing's own location, not the storefront — use `market` for that.
- `min_price` (number, optional) — Lowest asking price, in the listing's own currency as the index stores it (EUR for almost every listing).
- `max_price` (number, optional) — Highest asking price.
- `min_year` (integer, optional) — Earliest model year.
- `max_year` (integer, optional) — Latest model year.
- `ebike` (boolean, optional) — true = only e-bikes, false = only non-assisted.
- `frameset` (boolean, optional) — true = only framesets (frame, no build), false = only complete products.
- `high_demand` (boolean, optional) — true = only listings the site is currently flagging as in high demand.
- `sort` (enum, optional, default "relevance") — Result order. `relevance` is the site's reranked default and is NOT stable between identical calls; the price and date orders are. [one of: relevance, newest, oldest, price_asc, price_desc]
- `page` (integer, optional, default 1) — 1-based page. The source serves at most 10,000 rows per query, so the last page with rows is 10000/page_size; the response carries `last_page`.
- `page_size` (integer, optional, default 52) — Rows per page, 1-200 (200 is the source's own hard limit). The site itself asks for 52.
- `include_pii` (boolean, optional, default false) — Kept for gateway compatibility. buycycle publishes a seller's display name, city and ratings on the public page and this engine returns them either way; it never returns an e-mail, phone or surname because the site does not show one.

**Returns:** {query, total, total_capped, page, page_size, last_page, has_more, result_window, sort, filters_applied, products[]}. Each product: {id, title, url, slug, product_type, main_type, brand, category, discipline, year, frame_size, size, groupset, description, condition, condition_label, price, currency, msrp, msrp_shown, is_price_reduced, is_high_demand, favorite_count, buyer_offers, country_id, country_code, seller_id, listed_at, listed_at_ts, updated_at, image, images[], images_count}. `total` is the source's filter-aware group count; `total_capped` is true when the source's own counter sits at its 10,000 ceiling, which never changes `total`. Pass a row's `id` to `detail` for specs, components, seller and shipping, and its `seller_id` to `seller`.

**Example request body:**
```json
{
  "query": "specialized tarmac",
  "condition": [
    "VERY_GOOD"
  ],
  "frame_material": [
    "carbon"
  ],
  "sort": "price_desc"
}
```

### POST https://api.reefapi.com/buycycle/v1/detail — 3 credits
One buycycle listing in full, exactly what the product page publishes: title, brand, model, year, condition with the site's own grading note, asking price, the original price, the total including buyer protection, shipping cost and destination, return window, MSRP, frame size with the recommended rider height, frame material, brake and shifting type, suspension, wheel size, colour, groupset, every component the seller listed (original and replaced), the seller's own description and buycycle's translation of it, every image, the city and country the item is in, the seller (name, rating, reviews, profile) and buycycle's own market-price rating for the asking price.

**Parameters:**
- `id` (string, optional) — A listing's numeric id (the `id` on every search row) or its slug. The full product URL works too.
- `market` (enum, optional, default "de") — Which buycycle storefront to read: the ISO-2 country code of the shop, which sets the page language and the currency prices are shown in. The catalogue itself is pan-European and identical in every storefront. [one of: at, be, bg, ch, cz, de, dk, ee, es, fi, fr, gr, hr, hu, ie, it, lt, lu, lv, mc, nl, pl, pt, ro, se, si, sk, us]
- `language` (enum, optional, default "en") — Page language for this call; English by default, and every storefront serves it. Ask for the storefront's own language (de, fr, it, es, nl, pl, cs, da, fi, pt) and the spec labels, condition wording and country name come back in that language, which is what the shopper sees — the normalised fields (frame_material, brake_type, shifting_type, wheel_size, colour, condition) are read off the English labels and come back empty in other languages. `specs[]` always carries exactly what the page printed. [one of: cs, da, de, en, es, fi, fr, it, nl, pl, pt]
- `include_pii` (boolean, optional, default false) — Kept for gateway compatibility. buycycle publishes a seller's display name, city and ratings on the public page and this engine returns them either way; it never returns an e-mail, phone or surname because the site does not show one.

**Returns:** {id, listing_id, title, slug, url, status, product_type, brand, model, year, condition, condition_label, condition_note, price, price_display, price_original, is_price_reduced, currency, display_currency, msrp, msrp_shown, total_with_buyer_protection, shipping_cost, shipping_currency, ships_to, return_days, availability, discipline, category, breadcrumb[], frame_size, size, recommended_height, seller_fit_opinion, frame_material, brake_type, shifting_type, suspension_type, wheel_size, colour, groupset, receipt, specs[{name,value,note}], components[], components_original[], components_replaced[], description, description_translated, description_tags[], images[], images_count, favorite_count, listing_age, can_buy, accepts_offers, location{city,country}, price_rating, seller{id,name,profile_url,rating,reviews_count,last_active}, market, schema_price, schema_currency, price_mismatch}. `price` and `total_with_buyer_protection` are in the STOREFRONT's currency (`currency`); `listing_currency` is the currency the seller listed in. `schema_price` is the page's own schema.org figure, kept as an independent witness, and `price_mismatch` says whether the two disagree. buycycle does not publish mileage/km as a field, nor a pre-reduction price: it flags `is_price_reduced` without printing the old figure.

**Example request body:**
```json
{
  "id": "2688396",
  "market": "de"
}
```

### POST https://api.reefapi.com/buycycle/v1/seller — 2 credits
A buycycle seller's public profile and the listings on it: private or commercial, country and city, star rating, review count, items for sale, items sold, followers, member-since, verification and top-seller badges, plus the first page of their live listings with prices and condition.

**Parameters:**
- `seller_id` (integer, required) — The seller's numeric id — `seller_id` on every search row, or the number at the end of a /seller-profile/ URL.
- `market` (enum, optional, default "de") — Which buycycle storefront to read: the ISO-2 country code of the shop, which sets the page language and the currency prices are shown in. The catalogue itself is pan-European and identical in every storefront. [one of: at, be, bg, ch, cz, de, dk, ee, es, fi, fr, gr, hr, hu, ie, it, lt, lu, lv, mc, nl, pl, pt, ro, se, si, sk, us]
- `language` (enum, optional, default "en") — Page language for this call; English by default, and every storefront serves it. Ask for the storefront's own language (de, fr, it, es, nl, pl, cs, da, fi, pt) and the spec labels, condition wording and country name come back in that language, which is what the shopper sees — the normalised fields (frame_material, brake_type, shifting_type, wheel_size, colour, condition) are read off the English labels and come back empty in other languages. `specs[]` always carries exactly what the page printed. [one of: cs, da, de, en, es, fi, fr, it, nl, pl, pt]
- `include_pii` (boolean, optional, default false) — Kept for gateway compatibility. buycycle publishes a seller's display name, city and ratings on the public page and this engine returns them either way; it never returns an e-mail, phone or surname because the site does not show one.

**Returns:** {seller{id, name, first_name, profile_url, type, type_label, status, is_verified, is_top_seller, about, avatar, country, country_code, city, rating, reviews_count, listings_count, sold_count, followers_count, member_since, created_at, response_time}, listings[{id, title, slug, url, product_type, brand, year, frame_size, size, groupset, condition, condition_label, price, price_display, currency, msrp, msrp_shown, category, discipline, status, city, favorite_count, image}], listings_returned}

**Example request body:**
```json
{
  "seller_id": 4773757,
  "market": "de"
}
```

### POST https://api.reefapi.com/buycycle/v1/filters — 2 credits
Every filter value buycycle currently offers, with the live count behind each one: departments, disciplines, categories, brands, model families, sizes per vocabulary, frame materials, brake and shifting types, groupsets, colours, conditions, seller types, e-bike/frameset flags and the price and year ranges. Use it to discover the exact slugs `search` filters on, and as a market-size report in its own right (how many carbon road bikes, how many Canyons).

**Parameters:**
- `query` (string, optional) — Narrow the facet counts to one search term, exactly as `search` would.
- `main_type` (array, optional) — Narrow the facet counts to one department. [one of: ball-sports, bikes, cycling-gear, other, outdoor, racket-sports, running, water-sports, winter-sports]
- `discipline` (array, optional) — Narrow the facet counts to one discipline slug.
- `brand` (array, optional) — Narrow the facet counts to one or more brand slugs.
- `max_values` (integer, optional, default 50) — How many values to return per facet, most-listed first.
- `include_pii` (boolean, optional, default false) — Kept for gateway compatibility. buycycle publishes a seller's display name, city and ratings on the public page and this engine returns them either way; it never returns an e-mail, phone or surname because the site does not show one.

**Returns:** {query, total, total_capped, groups[{group, label, count}], facets{<source facet name>: {display_name, type, search_param, values[{value, label, count}], value_count, min, max}}, facet_count}. `search_param` names the `search` parameter a facet feeds (brand_slug -> brand, type_slug -> discipline, condition_code -> condition, user_type -> seller_type …) and is null for the facets buycycle keeps but this API does not expose as filters — including `gender`, whose values mix numeric ids with free text in four languages, and `bike_component_id`, whose values are bare ids with no label anywhere in the payload.

**Example request body:**
```json
{
  "main_type": [
    "bikes"
  ],
  "max_values": 25
}
```

### POST https://api.reefapi.com/buycycle/v1/suggest — 1 credit
buycycle's own search-box suggestions for a few letters: the completion terms it would offer and the products it would preview under them.

**Parameters:**
- `query` (string, required) — What the shopper has typed so far.
- `include_pii` (boolean, optional, default false) — Kept for gateway compatibility. buycycle publishes a seller's display name, city and ratings on the public page and this engine returns them either way; it never returns an e-mail, phone or surname because the site does not show one.

**Returns:** {query, suggestions[{text, group}], products[{id, title, url, brand, price, currency, image}]}

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

### POST https://api.reefapi.com/buycycle/v1/markets — 3 credits
The storefronts buycycle runs, straight from the site's own country table: country code and name, the currency that storefront prices in, and the languages it serves. These are the values `market`, `language` and the search filter `country` take.

**Parameters:**
- `include_pii` (boolean, optional, default false) — Kept for gateway compatibility. buycycle publishes a seller's display name, city and ratings on the public page and this engine returns them either way; it never returns an e-mail, phone or surname because the site does not show one.

**Returns:** {count, markets[{country_id, code, code_iso3, name, native_name, currency, currency_id, default_language, languages[]}]}

## 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=buycycle
- Human docs page: https://reefapi.com/docs/buycycle
- Overview page: https://reefapi.com/buycycle-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
