Search 125,567 used bikes by frame size, groupset and condition, then read the whole listing and its seller
buycycle is a European marketplace for pre-owned bikes, bike parts, cycling gear, running, winter-sports and outdoor equipment, and this API reads it as JSON.
6 active endpoints, on 1, 2 and 3 credit tiers.
- POST/buycycle/v1/search
- POST/buycycle/v1/detail
- POST/buycycle/v1/seller
- POST/buycycle/v1/filters
- POST/buycycle/v1/suggest
- POST/buycycle/v1/markets
What buycycle endpoints does ReefAPI ship?
6 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
buycycle API
6 of 6 endpoints, ready to run
Carbon Specialized Tarmacs in very good condition, dearest first
// Press "Try it" and this pane shows exactly what the // live site returned this second — including an empty // result, if that is the truth. No key, no account.
How the buycycle API works
buycycle is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 438 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
From a model name to a priced, comparable used-bike feed
Find the exact slugs buycycle filters on, page the listings, open the ones worth opening, then look at who is selling them.
Every live value with its count: brands, 52 disciplines, 261 categories, the 10 frame sizes, materials, brake and shifting types, and the price and model-year ranges. This is where the slugs for the next call come from.
52 rows a page with brand, model year, frame size, groupset, condition, price, currency, the country the bike is in and the seller id. total is buycycle's own filter-aware count and last_page is where paging stops.
The whole listing: frame material, brake and shifting type, recommended rider height, every component, the seller's description and its translation, images, the buyer-protection total, shipping cost, return window and buycycle's market-price verdict.
Private or commercial, country and city, star rating, reviews, items for sale, items sold, followers and member-since, with their live listings.
A dated feed of used bikes you can actually compare: same model, same frame size, same condition grade, priced in one currency, with the seller's track record next to each one.
curl -X POST https://api.reefapi.com/buycycle/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"specialized tarmac","condition":["VERY_GOOD"],"frame_material":["carbon"],"sort":"price_desc"}'{
"ok": true,
"data": { … },
"meta": {
"api": "buycycle",
"endpoint": "search",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}What a buycycle field actually contains
Fields that read differently from how they look. Every row was measured against live buycycle responses on 2026-10-08.
| Field | What it holds |
|---|---|
| total | buycycle's own filter-aware count, and it is the real one. The raw counter the search index returns stops at 10,000 no matter how many matches there are; total is read from the count the index keeps per result set, which agrees to the item with the site's own shop page (125,653 on the page, the same figure from the API in the same minute) and with narrow queries where nothing is capped (Specialized 5,851, Canyon 2,326, Specialized or Canyon 8,177). total_capped tells you the raw counter was at its ceiling, which never changes total. |
| last_page, result_window | buycycle serves the first 10,000 rows of any result, whatever the total. At 52 rows a page the last page with rows is 193 and it holds exactly 16; at 200 rows a page it is 50. Asking past that is rejected with the number, not answered with an empty page. Narrow with filters to reach deeper. |
| frame_size vs size | Two different vocabularies, both as the listing prints them. frame_size is the bike measurement ("54 cm", "MD", "L") and arrives on 50 of 50 bike rows and none of the gear rows. size is the letter or number vocabulary used by clothing, shoes and helmets. The size FILTER takes one list covering all of them: frame sizes xxxs to xxl, wheel sizes 26 / 27-5-650b / 28-700c / 29, clothing clothing-size-s to 3xl, shoes eu-42 / eu-42-5, helmets helmet-size-m. filters returns the live list grouped per vocabulary. |
| condition | Four grades the filter accepts - NEW (40,917 listings), VERY_GOOD (54,056), GOOD (28,598), FAIR (1,988) - plus a fifth, NEW_WITH_WARRANTY, that buycycle stamps on some shop listings and its own filter cannot select. condition_label is the wording the page shows. The grades are not numbered in quality order upstream, so read the names, not an index. |
| price and currency | price is in the currency of the storefront you asked for, and currency says which. The same bike reads 2,730 EUR on the German storefront and 69,291 CZK on the Czech one; listing_currency keeps the currency the seller listed in. total_with_buyer_protection is the same bike with buycycle's buyer-protection fee added (2,730 becomes 2,799), and shipping_cost is quoted separately. |
| msrp, msrp_shown | The recommended retail price, when buycycle shows one - 42 of 50 bike rows. It arrives as 0 rather than empty on listings with none, and a few listings carry an MSRP below the asking price, so read msrp_shown before you compute a discount from it. |
| is_price_reduced | buycycle's own flag that the asking price came down. It does not publish what it came down FROM: on every listing we checked that carried the flag, the source's "original" price was the same number as the current one. We do not invent the old figure. |
| groupset | The drivetrain as buycycle names it - "Shimano Ultegra Di2", "SRAM Force eTap AXS", "Sram Eagle Transmission GX". On 50 of 50 bike rows, and on no gear rows. |
| seller | A display name as buycycle shows it ("Alban M."), the numeric seller id, the profile link, the star rating, the review count and when they were last active. 94,955 of the 125,567 listings are from private people and 30,638 from commercial shops; seller_type filters either way. No e-mail, phone or surname - buycycle does not publish them. |
| country vs market | Two different things. country filters by where the item physically is (Germany 24,877 listings, France 20,013) and every row carries country_code. market picks which of the 28 buycycle storefronts to read, which sets the currency and the page language. The catalogue is pan-European and identical in every storefront. |
| sort | relevance is buycycle's reranked default and it is not reproducible - two identical calls a second apart returned different first rows. newest, oldest, price_asc and price_desc are stable, and newest really is newest (top rows timestamped minutes before the call). |
| total moves while you read it | buycycle is live: the unfiltered total read 125,555, 125,567 and 125,653 in three calls within the same hour, and the newest listings in a newest-first page were timestamped minutes before the call. Treat any count here as a reading with a timestamp, not a constant. |
| description | What the seller wrote, on 47 of 50 bike rows, plus buycycle's own translation of it on detail (a French listing came back with an English version alongside). description_tags are the badges buycycle derives from that text - "Recently serviced", "Low mileage", "New chain". |
Kilometres ridden is NOT a field buycycle publishes - it only ever appears inside a seller's free text and as a "Low mileage" badge, so we do not fake it. Sold and withdrawn listings leave every buycycle surface: those return NOT_FOUND, not a stale record.
buycycle coverage, measured
Every number below was read from live buycycle responses on 2026-10-08, two runs per endpoint, 27 of 27 calls in the pricing pass answered with one upstream request each.
125,567 live listings: bikes 53,759, cycling gear 48,134, running 15,245, winter sports 6,628, outdoor 924, ball sports 392, water sports 225, racket sports 145, other 212. 52 disciplines, 261 leaf categories, 120 groupsets, 80 size values. The brand and model-family lists both come back at exactly 500 values, which looks like the index's own ceiling rather than the real number - buycycle's own filter panel prints 499 brands.
28 storefronts, all 28 called and all 28 answered with the same listing: EUR 2,730 - CZK 69,291 - DKK 21,228 - HUF 1,037,602 - PLN 12,417 - SEK 31,958 - CHF 2,659 - USD 3,192 - GBP 2,408. One pan-European catalogue; the storefront sets language and currency, not the result set.
Against an unfiltered 125,567 in the same run: bikes 53,759, road and gravel 33,847, road 24,739, Specialized 5,851, Canyon 2,326, both 8,177, Tarmac 1,354, frame size M 21,120, 28-700c wheels 5,762, carbon 38,297, black 30,096, disc brakes 42,457, electronic shifting 19,499, New 40,917, Fair 1,989, commercial sellers 30,638, in Germany 24,877, in France 20,013, 1,000-4,000 34,093, years 2023-2024 21,853, e-bikes 6,380, framesets 3,805, in-demand 766.
Eight listings compared against three independent things buycycle publishes - the search index, the product page and the page's own structured data - plus buycycle's own plain-text rendering: price 8/8 on all four, condition 8/8, model year 8/8. Search to detail: price, currency, brand, year, frame size, condition, groupset and seller id 8/8 each, MSRP 7/7. Round-trip 12/12 ids across three departments.
On 200 search rows across four departments: id, title, url, brand, category, discipline, price, currency, condition, country, seller id, listing date and image 200/200; seller description 192/200; model year 166/200. Bike columns on 50 of 50 bike rows and, by design, none of the gear rows: frame size 50/50, groupset 50/50. On detail, bikes carry frame material, brake type, shifting type, colour, recommended height, groupset and the component list 4/4; gear, running and winter pages publish condition, year, category and colour only, because that is all buycycle prints for them.
10,000 rows per query. 193 pages of 52 (the last holds exactly 16) or 50 pages of 200, which is buycycle's own cap on page size. Asking past the window is refused with the number instead of answered with an empty page.
Kilometres ridden is not a buycycle field - it lives in the seller's free text and in a "Low mileage" badge. buycycle flags that a price was reduced but never publishes the old price, so we do not either. Relevance order is reranked per request and is not reproducible between two identical calls; use a price or date sort for a stable page. A fifth condition grade, "Brand new with warranty", appears on listings but buycycle's own filter cannot select it. Seller reviews are behind a tab we do not read yet, so seller returns the rating and the review count but not the review texts, and only the first page of a seller's listings.
What people build with buycycle
The jobs this data is most often used for.
endpoints
credits per call
Price a used bike before buying or selling: filter by brand, model family, model year, frame size and condition, sort by price, and read the asking price next to the MSRP and buycycle's own market-price verdict.
Track the European second-hand market for one model over time - Tarmac, Aeroad, Stumpjumper - with live counts per brand, family, frame material and condition.
Feed a bike-shop or trade-in tool: pull commercial sellers only, with frame size, groupset and condition on every row, and the shipping cost and buyer-protection total on detail.
Build a cross-border deal finder: the same catalogue priced in nine currencies across 28 storefronts, with a filter for the country the bike physically sits in.
What buycycle data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 438 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
curl -X POST https://api.reefapi.com/buycycle/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"specialized tarmac","condition":["VERY_GOOD"],"frame_material":["carbon"],"sort":"price_desc"}'import requests
r = requests.post(
"https://api.reefapi.com/buycycle/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"query": "specialized tarmac",
"condition": [
"VERY_GOOD"
],
"frame_material": [
"carbon"
],
"sort": "price_desc"
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up buycycle.
Get a free key →Do I need a buycycle account?▾
No. Everything here is read logged out, and you call reefapi.com from anywhere.
Which countries does it cover?▾
One pan-European catalogue of 125,567 listings, readable through any of 28 storefronts: Germany, Austria, Switzerland, France, Italy, Spain, Portugal, Netherlands, Belgium, Luxembourg, Ireland, Denmark, Sweden, Finland, Poland, Czech Republic, Slovakia, Hungary, Romania, Bulgaria, Croatia, Slovenia, Greece, Estonia, Latvia, Lithuania, Monaco and the United States. We called all 28 with the same listing and all 28 answered, each in its own currency: EUR 2,730, CZK 69,291, DKK 21,228, HUF 1,037,602, PLN 12,417, SEK 31,958, CHF 2,659, USD 3,192, GBP 2,408.
Can I filter the way the website does?▾
Yes, and every filter was checked against the unfiltered count of 125,567 in the same run: bikes 53,759, road and gravel 33,847, road bikes 24,739, Specialized 5,851, Canyon 2,326, the Tarmac family 1,354, frame size M 21,120, carbon 38,297, disc brakes 42,457, electronic shifting 19,499, e-bikes 6,380, framesets 3,805, commercial sellers 30,638, items in Germany 24,877, 1,000 to 4,000 of price 34,093, model years 2023-2024 21,853. Combining them narrows properly: road and gravel 33,838, plus carbon 27,939, plus Very good 13,549, plus commercial sellers 2,180.
How do I get from a search row to the full bike?▾
Pass the row's id to detail - the slug or the full product URL work too. Twelve ids taken from search across bikes, cycling gear and running all resolved to the same record, 12 of 12.
How accurate are the prices?▾
We compared eight listings against three things buycycle publishes independently of each other: the search index, the product page, and the page's own structured data. All three agreed on all eight, and so did buycycle's own plain-text rendering of the same listings. Brand, model year, frame size, groupset and condition also matched on 8 of 8 between search and detail.
How deep can I page?▾
10,000 rows per query - 193 pages of 52, or 50 pages of 200, which is buycycle's own hard limit on page size. The response tells you last_page up front and refuses anything past it instead of returning an empty page.
Do you return e-bikes, framesets and parts separately?▾
Yes. ebike=true returns the 6,380 assisted bikes, frameset=true the 3,805 frame-only listings, and main_type separates bikes from cycling gear, running, winter sports, outdoor, ball, water and racket sports. An e-bike's detail adds its motor, fork, rear shock and the rest of the component list.
What about kilometres ridden?▾
buycycle does not publish it as a field. We return the seller's description, where riders usually write it, and the "Low mileage" badge buycycle derives from that text - but we will not manufacture a number that is not there.
What is the buycycle API?▾
buycycle API is a ReefAPI endpoint group for europe's largest used-bike marketplace: listings with brand, model year, frame size, groupset, frame material, condition, price and the seller, across 28 storefront countries. It returns live JSON through POST requests under /buycycle/v1.
Is the buycycle API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. buycycle calls use the same shared credit balance as every other ReefAPI engine.
Do I need a buycycle login or account?▾
No login to buycycle is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the buycycle data?▾
The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the buycycle API use?▾
buycycle actions currently cost 1-3 credits per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.
Can I call buycycle from an AI assistant or MCP client?▾
Yes. Connect ReefAPI once through MCP and your assistant can call buycycle actions with the same key, credit pool and JSON envelope used by normal REST requests.
191 E-commerce & Marketplaces APIs on the same key
One key, one credit pool, one response envelope. If you are pulling buycycle, you are one call away from the rest of the category — no second contract, no second integration.
Need something this API does not do?
Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 437 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-10-08.