Europe's refurbished marketplace, one country at a time, as JSON
The Refurbed API returns refurbed, the Vienna-based refurbished-electronics marketplace, as clean JSON across every one of its 24 European storefronts, in five actions: search, product, categories, filters and compare_countries.
5 active endpoints, on 3 and 5 credit tiers.
- POST/refurbed/v1/search
- POST/refurbed/v1/product
- POST/refurbed/v1/categories
- POST/refurbed/v1/filters
- POST/refurbed/v1/compare_countries
What Refurbed endpoints does ReefAPI ship?
5 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
Refurbed API
5 of 5 endpoints, ready to run
Live refurbed offers from one storefront with that storefront's own exact total: offer id, product URL, brand, category path, variant, appearance grade, price in the local currency, the printed price string and the new-retail reference price.
// 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 Refurbed API works
Refurbed 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.
Read the storefront's own taxonomy, scope a shelf, open one offer in full, then price it across Europe
The step people skip is filters: refurbed's attribute set is per category, so a brand or colour value guessed from one shelf can be wrong on the next. Resolve it, filter on it, and every response hands you refurbed's own exact total so you can see the filter bite.
{"country": "de"}The German storefront's 60 live category slugs with labels. Take one verbatim — smartphones, macbooks, kitchen-appliances, consoles.
{"category": "smartphones", "country": "de"}That shelf's real taxonomy: 10 attributes including Brand with its live value list, Storage and Screen Size with min and max, plus the shelf's price range 35.66 to 2,844.60 EUR and the EUR symbol.
{"category": "smartphones", "country": "de", "brand": "Apple", "price_max": 300, "sort": "price_asc"}Cheapest-first Apple phones under 300 EUR. meta.total_results was 21 against an unfiltered 506, and meta.filters_applied_by_source is the storefront echoing back what it recognised. Take products[].product_id, products[].slug and products[].grade_code.
{"product_id": 14162, "slug": "iphone-13", "country": "de", "grade": "c"}That exact offer in full: grade Good at 264.99 EUR with refurbed's ladder beside it (Very good +13.01, Excellent +35.01, Premium +74.01), the battery option, 18 colour and storage variants, 24 spec rows, 4 images, rating 4.77 from 4,505 reviews, a minimum 12-month warranty and a free 30-day return window.
{"query": "iphone 13", "countries": "de,gb,ch,se,pl"}The same model's cheapest live offer in five storefronts, each in its own currency — EUR, GBP, CHF, SEK and PLN — with each storefront's own match count.
The storefront's real taxonomy, a scoped shelf with an auditable total, one offer with its full condition ladder and spec sheet, and the same model priced across five European markets — five calls against one schema.
curl -X POST https://api.reefapi.com/refurbed/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"iphone 13","country":"de"}'{
"ok": true,
"data": { … },
"meta": {
"api": "refurbed",
"endpoint": "search",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}The 24 storefronts, their currency and their live smartphone shelf on 2026-10-01
Every row was fetched live. The currency is the ISO code that storefront publishes in its own structured data, not an assumption from the domain — and not the code in refurbed's analytics payload, which says EUR on all 24 including the British, Swiss, Swedish, Danish, Polish and Czech ones. Offers move daily; every search response carries that storefront's own exact total for your query.
| country | storefront | currency | smartphone offers |
|---|---|---|---|
| de | refurbed.de | EUR | 506 |
| nl | refurbed.nl | EUR | 488 |
| fr | refurbed.fr | EUR | 480 |
| be | refurbed.be | EUR | 480 |
| at | refurbed.at | EUR | 474 |
| it | refurbed.it | EUR | 474 |
| es | refurbed.es | EUR | 473 |
| dk | refurbed.dk | DKK | 472 |
| lu | refurbed.lu | EUR | 466 |
| pl | refurbed.pl | PLN | 463 |
| cz | refurbed.cz | CZK | 456 |
| se | refurbed.se | SEK | 452 |
| fi | refurbed.fi | EUR | 449 |
| pt | refurbed.pt | EUR | 447 |
| bg | refurbed.bg | EUR | 440 |
| ie | refurbed.ie | EUR | 439 |
| ee | refurbed.ee | EUR | 438 |
| sk | refurbed.sk | EUR | 434 |
| hr | refurbed.hr | EUR | 433 |
| si | refurbed.si | EUR | 433 |
| lt | refurbed.lt | EUR | 433 |
| lv | refurbed.lv | EUR | 412 |
| ch | refurbed.ch | CHF | 136 |
| gb | refurbed.co.uk | GBP | 105 |
Switzerland and the United Kingdom are genuinely smaller shelves, not a parsing problem — both answered with 16 rows and a full price string, and their own category pages reported the same 136 and 105. Other shelves on refurbed.de the same day: laptops 1,204, smartphones 506, kitchen appliances 210, smartwatches 97, consoles 74. Results come 16 per page on every page we measured, which is refurbed's own page size and not a parameter; meta.pagination.has_more is refurbed's own has-more flag.
What refurbed publishes, what it does not, and what we measured
Measured on 2026-10-01 against the live storefronts, on two separate runs with the same code: all 24 storefronts answered with 16 rows and a local-currency price, every exposed filter narrowed the set in the same run, field fill was counted over hundreds of rows spanning five categories, and the grade pairing was checked on 32 rows. Five of these lines go against us.
All 24 refurbed country storefronts answered: Germany, Austria, France, Italy, Spain, Netherlands, Belgium, Ireland, United Kingdom, Switzerland, Sweden, Denmark, Poland, Czechia, Bulgaria, Croatia, Finland, Portugal, Slovakia, Slovenia, Lithuania, Latvia, Estonia and Luxembourg. The currency comes from each storefront's own structured data: EUR on 19, GBP on refurbed.co.uk, CHF on refurbed.ch, SEK on refurbed.se, DKK on refurbed.dk, PLN on refurbed.pl, CZK on refurbed.cz. Nothing unverified is listed, and countries are not inferred from the domain.
Premium (screen and body identical to new), Excellent (screen like new, no scratches from close distance), Very good (no visible screen scratches when on, minimal body wear) and Good (no visible screen scratches when on, small body marks) — refurbed's own wording, with its own letters AA, A, B and C. The letter and the code agreed on 32 of 32 live rows. The product action returns the whole in-stock ladder with refurbed's own price step and each grade's offer id; on the iPhone 13 sampled that was Good 264.99 EUR, Very good +13.01, Excellent +35.01, Premium +74.01. Battery is a second, independent ladder on phones (Optimal or New, +10.02 there). A result card prints the letter rather than the display name, so on a search row grade is resolved from that letter through refurbed's own letter-to-name table, with grade_letter and grade_code returned beside it; the letter and the code agreed on 32 of 32 rows, and the product action reads the name straight off the page.
On /en-de/search/?query=iphone+13 three of the 16 rows had a data-layer price below the price the card printed — offer 407267 printed 1,293.99 EUR against 1,283.99, offer 407253 1,390.00 against 1,380.00, offer 395939 579.99 against 559.99 — always a round 10 or 20 units, always lower. We re-fetched two of those product pages and refurbed's own structured product data agreed with the PRINTED number both times, so the data layer is the stale one. The API therefore publishes the printed price as price, keeps the data-layer figure as price_feed, sets price_mismatch on the row and counts the flagged rows in meta. Taking the convenient structured field instead would have quoted prices up to 20 units too low on roughly a fifth of rows.
price_new_reference is the brand-new retail reference refurbed shows next to its own price, and refurbed's own tooltip describes it as the device's new retail price averaged from an independent price-comparison portal and recalculated daily. It is published as its own field with its own printed string, never folded into a discount we computed, and it is null whenever the storefront prints no strikethrough — which it often does not. A zero is never returned as a price either, in any field.
The nonsense keyword zzqqxxnotathingqq returned 300 rows on refurbed.de. refurbed's keyword matching is a relevance ranking, not a containment filter, and it has no no-results state to read. This is documented rather than papered over: when you need exactness, browse a category and add brand, colour and a price range, all of which were measured to change the total.
Against an unfiltered 506 German smartphone offers in one run: brand=Apple 43, brand=Apple,Samsung 172, colour=Black 313, price_min=800 70, price_max=200 224, price 200 to 400 218, brand=Apple with price_max=300 21. Seven of seven bit, with a 0.1 percent tolerance because the live total drifts between calls. Sorting is checkable the same way: price_asc's first row was 35.66 EUR and price_desc's was 2,844.60, exactly the lowest and highest price that category publishes for itself. A brand the storefront does not stock returns a real zero and meta.warnings says the storefront did not recognise the value, so an unknown value never looks like an empty shelf. Nothing is exposed that refurbed accepts and ignores.
refurbed is a managed marketplace and its public product page names no selling merchant, no shop page and no per-merchant rating. We probed for it rather than assuming: the words seller and merchant appear on the page only inside its return-policy structured data. So there is no seller object here, and the field is left out instead of being filled with nulls. What you do get is the storefront entity (refurbed Deutschland, refurbed UK and so on), the product rating with its review count, the storefront's stated minimum warranty, the return window in days, whether returns are free, the shipping cost and the handling and transit day ranges.
Every result page we measured returned exactly 16 rows — keyword search page 1, page 2 and page 9, category page 1, and all 24 storefronts — so the engine states 16 rather than inventing a configurable size, and meta.rows reports what actually arrived. meta.total_results is refurbed's own exact match count and meta.pagination.has_more is its own has-more flag, so you page until it says to stop. On a category page refurbed also publishes the shelf's own offer count, lowest and highest price, and those agreed with the result total on all 24 storefronts.
Always present on every result row sampled across smartphones, laptops, kitchen appliances, consoles and smartwatches: product_id, model_id, name, url, slug, brand, price, currency, currency symbol, image, the three-level category path, the variant label, the grade letter and the grade code. Conditional, and documented as such: the printed price string, the new-retail reference price, the product rating and the promo tags, none of which refurbed publishes on every card. On the product record, the spec sheet, every image, the grade ladder, the variant list, the rating with its count, the warranty text, the return window, shipping cost and the handling and transit ranges were present on every product sampled; the battery ladder only exists on devices that have one. Each missing value is null, never a guess.
refurbed has no id-only product route: /p/14162c/ answers 404 and /p/<wrong-slug>/14162c/ answers HTTP 400, both measured. So slug is required alongside product_id, and both come off any search row or straight out of a product URL. A mismatched slug is reported as INVALID_PARAM with that explanation, because a URL of ours being wrong is never typed as the site refusing us. Passing a row's grade_code as grade lands you on exactly that offer; without it you get refurbed's default grade for the device, which is a different price — stated rather than left to surprise you.
An offer id that is not live in that storefront is NOT_FOUND. A country, category, grade or sort value refurbed does not have is rejected with the allowed list. search with neither query nor category is MISSING_PARAM that names both. compare_countries with one country, or with more than six, is rejected with the reason. A brand the storefront genuinely does not stock is ok with zero rows and a warning, because an empty answer is an answer and not an error.
What people build with Refurbed
The jobs this data is most often used for.
endpoints
credits per call
Run cross-border price intelligence on refurbished hardware: one compare_countries call gives the same model's cheapest live offer in up to six storefronts, each in its own currency, so arbitrage and local-pricing questions get a measured answer instead of a guess.
Build a condition-aware buying tool: pull one device's full appearance-grade ladder with refurbed's own price step per grade and its battery option, and show a buyer what Very good actually saves over Excellent on that exact unit.
Monitor a competitor's or your own refurbished range across 24 European markets: browse a category per country, filter by brand and price band, and track the exact offer count and price distribution each storefront publishes for itself.
Feed a sustainability or circular-economy dashboard with real secondary-market supply: 1,204 live laptop offers and 506 smartphone offers on refurbed.de alone on the day this was measured, broken down by brand, colour and price band.
What Refurbed data costs
The cheapest call here is 3 credits, so $15/mo (Pro) buys 3,333 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/refurbed/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"iphone 13","country":"de"}'import requests
r = requests.post(
"https://api.reefapi.com/refurbed/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"query": "iphone 13",
"country": "de"
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up Refurbed.
Get a free key →Do I get refurbed's condition grades, or your interpretation of them?▾
refurbed's own, word for word. It grades device appearance in four categories and the product page prints them as Premium, Excellent, Very good and Good, while its data layer labels the same four AA, A, B and C. Both are returned: grade is the display name, grade_letter is refurbed's letter and grade_code is the lowercase short form. The pairing was checked on 32 live rows and agreed 32 of 32, with no exceptions. Nothing is translated into a scale of ours. A result card prints the letter rather than the name, so on a search row the name is resolved through refurbed's own letter-to-name table, the same one its product page prints; that pairing agreed on 32 of 32 live rows, so the name repeats refurbed rather than inferring anything.
How much does the grade change the price?▾
That is the question the product action is built to answer. It returns grade_options for the device you asked about: every appearance grade refurbed currently has in stock, each with refurbed's own price difference and its own offer id. On the iPhone 13 we sampled on refurbed.de, Good was 264.99 EUR and refurbed printed Very good as +13.01, Excellent as +35.01 and Premium as +74.01 against it. Battery is a separate ladder on phones — Optimal or New, +10.02 there — and comes back as battery_options. When refurbed has only one grade of a device left there is no ladder to return, so grade_options is null and grade still tells you which one it is.
Which country's price am I getting?▾
The one you asked for, and the response says so. country is required in practice — it defaults to de — and every response echoes meta.country, meta.locale, meta.currency and meta.currency_symbol. The currency is read from the storefront's own structured data, which matters: refurbed's analytics payload reports EUR on all 24 storefronts including refurbed.co.uk, so taking the obvious field would have published British prices labelled EUR. Across the 24 storefronts the live values are EUR on 19, GBP, CHF, SEK, DKK, PLN and CZK on the other five. If a storefront ever changes currency, the engine returns the live value and says so in meta.warnings instead of staying wrong quietly.
Can I compare the same device across countries in one call?▾
Yes, that is compare_countries. Give it a keyword or a category and 2 to 6 country codes and it reads each storefront's own search page inside one time budget, returning each one's cheapest matching offer with that country's currency and its own total. Six is the cap so a single call cannot outgrow its budget, and any storefront that did not finish is counted in meta.countries_failed with the reason rather than dropped silently.
Why do you return two prices, and why is one sometimes higher than what I expect?▾
price is what the storefront prints to a buyer, and price_new_reference is the brand-new retail reference refurbed shows struck through next to it. The second one is not a refurbed price and we do not call it one: refurbed's own tooltip describes it as the device's new retail price averaged from an independent price-comparison portal and recalculated daily. It is null whenever the storefront prints no strikethrough. There is also price_feed, which is the number in the storefront's own data layer for the same row — and it disagrees with the printed price on roughly a fifth of rows, always by a round 10 or 20 units and always lower. We publish the printed price, keep the data-layer number beside it, flag the row with price_mismatch and count the flagged rows in meta, because that disagreement is real and hiding it would mean quoting people prices that are too low.
Does a keyword search only return things that match my keyword?▾
No, and this is worth knowing before you build on it. refurbed's keyword search is fuzzy and it never reports a miss: the nonsense keyword zzqqxxnotathingqq still returned 300 rows on refurbed.de on 2026-10-01. A keyword result is a relevance list, not a containment filter. When you need an exact scope, browse a category slug and add brand, colour and a price range — those are real filters and every one of them was measured to change the total.
How do I know a filter actually did something?▾
Every search response reports meta.total_results, refurbed's own exact match count, plus meta.filters_requested and meta.filters_applied_by_source, which is the storefront echoing back which filters it recognised. In one run against an unfiltered 506 German smartphone offers: brand=Apple 43, brand=Apple,Samsung 172, colour=Black 313, price_min=800 70, price_max=200 224, price 200 to 400 218, and Apple under 300 EUR 21. Sorting is verifiable the same way — sort=price_asc returned 35.66 EUR as its first row and sort=price_desc returned 2,844.60, which are exactly the lowest and highest price that category publishes for itself. A brand the storefront does not stock comes back as a real zero and meta.warnings says the storefront did not recognise the value, so you can tell that apart from an empty shelf.
Do you tell me which merchant is selling the item?▾
No, because refurbed does not publish it. refurbed is a managed marketplace and its public product page names no merchant, no shop and no per-merchant rating anywhere — we probed for it rather than assuming. What the page does publish, and what you get, is the storefront entity (refurbed Deutschland, refurbed UK, and so on), the product rating with its review count, the stated warranty, the return window and the shipping and delivery-time ranges. Rather than fill a seller field with nulls, the API leaves it out.
What do I need to pull one product?▾
The offer id and the slug, both of which every search row gives you, and both of which are in any product URL: refurbed.de/en-de/p/iphone-13/14162c/ is slug iphone-13, id 14162 and grade code c. The slug is mandatory because refurbed has no id-only product route and answers HTTP 400 for an id with the wrong slug — we measured that rather than offering you a handle that does not work. Pass the row's grade_code as grade and you land on exactly that offer; leave it out and you get refurbed's default grade for that device, which is usually a different price.
What does product add over a search row?▾
The full spec sheet as refurbed labels it (24 rows on the iPhone 13: battery capacity, camera, connectivity, connectors, dimensions, display type, operating system, processor, weight and so on), every gallery image in display order, all colour and storage variants with their own price and offer id (18 on that iPhone 13), the appearance-grade ladder and the battery option, the product rating with its review count, the storefront's stated guarantees including the minimum warranty, the return window in days and whether returns are free, the shipping cost and the handling and transit day ranges, and the breadcrumb path. Everything in the search row is in there too.
How do I find out which categories and filter values exist?▾
Two cheap actions. categories returns that storefront's live category tree read off its own navigation — 60 slugs with labels on refurbed.de, 58 on refurbed.co.uk — and a returned slug goes straight into search's category. filters returns the live filter taxonomy for one search or category: refurbed's own attribute ids and labels with the exact value list of every enum and the min and max of every numeric one, plus that result set's price range and currency symbol. Smartphones exposed 10 attributes, laptops 15 — the taxonomy is per category, which is exactly why you should read it rather than guess it.
What happens if I ask for something that is not there?▾
You get a reason, never an empty success to interpret. An offer id that is not live in that storefront is NOT_FOUND. A slug that does not belong to the id is INVALID_PARAM with an explanation, because that is our URL being wrong and not the site refusing us. A country, category, grade or sort value refurbed does not have is rejected with the allowed list. Calling search with neither query nor category is MISSING_PARAM that says so, rather than dumping the whole catalogue on you.
What is the Refurbed API?▾
Refurbed API is a ReefAPI endpoint group for europe's refurbished-electronics marketplace as json: 24 country storefronts, each with its own price list and currency, refurbed's own four appearance grades and the price step between them. It returns live JSON through POST requests under /refurbed/v1.
Is the Refurbed API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. Refurbed calls use the same shared credit balance as every other ReefAPI engine.
191 E-commerce & Marketplaces APIs on the same key
One key, one credit pool, one response envelope. If you are pulling Refurbed, 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-01.