Looking for the overview — what this API returns, what it costs, and a call you can run without a key? See the Mascus API page →
docs / mascus

Mascus

Mascus

base /mascus/v18 endpoints
post/mascus/v1/detail3 credits

One listing in full, by id or URL. Returns the machine (make, model, model group, year, category path, hour meter, odometer normalised to kilometres), the price block (the seller's own asking price and currency, the EUR equivalent, the VAT rate, whether a price is published at all, and the source's own printed price rows), every technical property the seller typed — each with the source's own label in your chosen language, a language-free field name, and a parsed number and unit where there is one — the accessories list, the seller's free-text description in each language they wrote it in, the auction event with its bidding deadline and the auction house's own lot id, the rental day/week/month rates with and without VAT and the regions it can be hired in, the machine's own town, region, postcode, country and map coordinates, the dealer's business address and years on the marketplace, the finance/insurance/transport services offered, the full-size gallery and any videos, and the category breadcrumb.

ParameterAllowed / rangeDescription
asset_idoptional—The listing id, as every search row returns it in `asset_id` and as the last segment of any listing URL (a full URL is accepted and the id taken out of it; the source ignores every other path segment, so the slug need not be right). 🔴 An id here is not always valid on every front-end: measured, the id the international front-end prints resolves on three front-ends while the id the German one prints for the SAME machine answers HTTP 404 on the other two. Prefer the row's `url`; an id that does not resolve on the `market` asked for is tried on the two widest front-ends and `meta` says which one answered.
urloptional—A listing URL instead of an id — whichever you happen to have. Either `asset_id` or `url` is required.
market = comoptionalcom · uk · ie · au · nz · za · de · at · lu · nl · be · it · pt · mx · pl · cz · sk · hu · ro · bg · hr · si · rs · me · gr · se · no · dk · fi · ee · lt · lv · ua · ua_ru · tr · jp · kr · tw · arWhich country front-end to read. All 39 share ONE catalogue, so this does NOT pick a different inventory: it picks the language of the labels on `detail`, `categories` and `suggest`, and 🔴 the UNITS — the international front-end ('com') reports the odometer in MILES, the other 38 in kilometres. `mileage_km` is normalised on every market and `mileage_km_min/max` is always in kilometres, so you never have to care. Three front-ends the marketplace itself links (mascus.fr, mascus.es, mascus.com.br) answer HTTP 404 for every listing and return MARKET_UNAVAILABLE rather than a half-filled answer.
Try in playground →
post/mascus/v1/categories1 credit

The marketplace's own taxonomy with live per-node listing counts: six sectors (construction 252,476 · transport 96,956 · agriculture 83,644 · material handling 27,455 · forestry 25,707 · groundcare 10,840) and, under each, the categories and sub-categories with the exact codes every other action's `category` and `subcategory` filters take. Pass a `category_code` to get one sector's sub-tree. Every count is the source's own live figure. 🔴 The filter code and the source's URL slug differ on three of the six sectors, so this is the action to read codes from rather than lifting them out of a URL.

ParameterAllowed / rangeDescription
market = comoptionalcom · uk · ie · au · nz · za · de · at · lu · nl · be · it · pt · mx · pl · cz · sk · hu · ro · bg · hr · si · rs · me · gr · se · no · dk · fi · ee · lt · lv · ua · ua_ru · tr · jp · kr · tw · arWhich country front-end to read. All 39 share ONE catalogue, so this picks the LANGUAGE this action answers in, not a different inventory. Three front-ends the marketplace itself links (mascus.fr, mascus.es, mascus.com.br) answer HTTP 404 for every listing and return MARKET_UNAVAILABLE.
category_codeoptional—Return this node's sub-tree instead of the whole taxonomy. Takes a sector code ('construction', 'agriculture') and narrows the answer to that sector's categories and sub-categories with their live counts.
Try in playground →
post/mascus/v1/facets2 credits

The source's own live filter counts for a query: which makes, countries, regions, categories, conditions, advert types, accessories and emission levels have stock and how much of it. This is how you learn the exact spelling a filter wants (the source wants 'CAT', not 'Caterpillar', and region NAMES rather than codes) and how to split a query that is deeper than the 10,000-row retrievable ceiling. Every group says in `value_kind` whether its values are names, ISO codes or the source's own numeric property ids — the ids are what the filter takes, so they are published as they are rather than guessed at.

ParameterAllowed / rangeDescription
market = comoptionalcom · uk · ie · au · nz · za · de · at · lu · nl · be · it · pt · mx · pl · cz · sk · hu · ro · bg · hr · si · rs · me · gr · se · no · dk · fi · ee · lt · lv · ua · ua_ru · tr · jp · kr · tw · arWhich country front-end to read. All 39 share ONE catalogue, so this does NOT pick a different inventory: it picks the language of the labels on `detail`, `categories` and `suggest`, and 🔴 the UNITS — the international front-end ('com') reports the odometer in MILES, the other 38 in kilometres. `mileage_km` is normalised on every market and `mileage_km_min/max` is always in kilometres, so you never have to care. Three front-ends the marketplace itself links (mascus.fr, mascus.es, mascus.com.br) answer HTTP 404 for every listing and return MARKET_UNAVAILABLE rather than a half-filled answer.
currency = EURoptional—The currency to convert into, one of the 131 the source supports (EUR, USD, GBP, PLN, SEK, CZK, HUF, TRY, JPY, ZAR…). 🔴 Two measured consequences. (1) `price_min`/`price_max` are bands IN THIS CURRENCY: the same 10,000-50,000 band answers 19,366 rows in EUR and 18,583 in USD. (2) The conversion appears as `price_converted` + `price_converted_currency`, never as `price` — `price` and `currency` are always the seller's own asking price and do not move with this parameter.
queryoptional—Free-text keyword, as typed into the marketplace's own search box: a machine type ('excavator', 'bagger'), a make, a model, or several words. Extra words NARROW here rather than widen — measured: 'excavator' 46,033 rows, 'caterpillar 320' 2,273 — and an unmatched word gives an honest empty answer. 🔴 FREE TEXT IS SCORED IN THE CHOSEN FRONT-END'S OWN LANGUAGE, so the same word is a different query per market: 'excavator' answered 46,041 rows on the international front-end and 46,118 on the German one, and the first 40 rows of the two had NOT ONE listing in common (a make-and-model query such as 'Kubota M5-111D' does match identically on both). A result set that must be reproducible across markets has to be pinned with the typed filters or a dealer, not with free text.
catalogoptionalconstruction · cargo-transport · agriculture · materialhandling · forestry · groundscareOne of the marketplace's six sectors. Comma-separate for several. 🔴 The value is the sector CODE, which differs from the URL slug on three of the six ('cargo-transport' not 'transportation', 'materialhandling' not 'material-handling', 'groundscare' not 'groundcare') — a value guessed off a URL returns zero rows, so the codes are published and validated here.
categoryoptional—Category code inside a sector, as the `categories` action returns it ('excavators', 'tractors', 'trucks', 'forklifts'). Comma-separate for several. An unknown code is answered honestly with zero rows rather than ignored, but reading the code out of `categories` or `suggest` is the way to be sure.
subcategoryoptional—The third taxonomy level ('crawlerexcavators', 'miniexcavators', 'wheelexcavators'), from the `categories` action with a `category_code` set. This is how you get from 40,068 excavators to the 20,806 crawler excavators.
brandoptional—Make, spelled the way the source's own facet spells it ('CAT' not 'Caterpillar', 'John Deere', 'Volvo', 'Mercedes-Benz'). Case does not matter, the spelling does — read it from `facets` or let `suggest` map what a user typed. Measured to bite: 46,035 rows for 'excavator' → 9,913 for CAT.
modeloptional—Model name, as the source's own type-ahead spells it. Only works with `brand` — a bare model name is ambiguous across makes, so it is rejected rather than returning an answer that looks filtered. Measured: brand=CAT + model=320 → 1,553 rows.
countryoptional—Seller country, 2-letter ISO code. Comma-separate for several. 80 countries have stock on a typical query; the `facets` action lists them with counts. Measured to bite: 46,035 → 3,494 for DE.
regionoptional—Seller region or province, by the NAME the source prints ('Bayern', 'Tennessee', 'Västernorrlands län') — not a code; `facets` returns the names that have stock. Measured to bite: 'Bayern' → 132 rows.
conditionoptionalused · new · reconditioned · remanufactured · demo · vintage · damaged · dismantled · operates_with_deficiencies · rental_possibilityCondition class. Comma-separate for several. The source stores these as numeric property ids; this takes the words and sends the ids. Measured: 46,035 → 4,458 for 'new'.
ad_typeoptionalusedad · auctionad · rentaladThe structural kind of advert. 🔴 An unknown value is NOT an error on this source: it is dropped and you get the whole unfiltered catalogue with HTTP 200, so this endpoint validates it instead of forwarding it. Measured to bite: 46,035 → 5,116 auction lots, → 333 rental machines.
year_minoptional1900–2100Earliest year of construction, inclusive. 🔴 The source's own name for this filter is not the obvious one and the obvious one is accepted with HTTP 200 and then ignored, so a naive year window returns the unfiltered catalogue looking filtered. Here it bites: 46,035 → 11,205 for 2015-2020.
year_maxoptional1900–2100Latest year of construction, inclusive. Note the source carries seller-entered years as far ahead as 2027, so an open-ended upper bound is not the same as 'up to this year'.
price_minoptional0–Lowest price to include, 🔴 IN THE `currency` YOU ASKED FOR (default EUR), not in the seller's currency. Measured: the same 10,000-50,000 band answers 19,366 rows in EUR and 18,583 in USD. Any price bound also excludes the listings that publish no price at all and the source's own 0 and 1 placeholder prices.
price_maxoptional0–Highest price to include, 🔴 in the `currency` you asked for (default EUR), not in the seller's currency. Setting it also excludes every listing that publishes no price at all.
operating_hours_minoptional0–Lowest hour-meter reading to include, in hours — the field a used-plant buyer prices on. Verified front-end independent, unlike the odometer: the 0-2,000 h band answers the same 412 rows on the international and the German front-end.
operating_hours_maxoptional0–Highest hour-meter reading to include, in hours. Measured to bite: 46,035 → 412 for 0-2,000 h on the transport sector.
mileage_km_minoptional0–Lowest odometer reading to include, 🔴 ALWAYS IN KILOMETRES. The source filters in the front-end's own unit — the same 0-100,000 band answers 9,811 rows on the international front-end (miles) and 7,051 on the German one — so the unit is fixed at kilometres here and converted before the request leaves. Separate from `operating_hours_*` on purpose: the source publishes only one of the two per machine and they are not comparable.
mileage_km_maxoptional0–Highest odometer reading to include, 🔴 always in kilometres whatever `market` is set to — the source filters in the front-end's own unit and this endpoint converts before the request leaves.
with_price = falseoptional—Only listings that publish a price. Most of this marketplace does not — auction lots carry none at all and many dealers list 'price on request' — so this is the most useful narrowing filter for a pricing job. Measured: 46,035 → 32,305.
dealer_idoptional—Restrict to one dealer's stock, by the 8-character id the source's own dealer links use (also on every row as `seller.dealer_id`). 🔴 The full GUID is accepted by the source and answers 125 rows from FOUR different companies because its middle segment is shared, so a full GUID passed here is shortened for you and the answer is checked to contain exactly one company before it is returned.
Try in playground →
post/mascus/v1/suggest1 credit

The marketplace's own type-ahead for whatever a user has typed, in one list where every entry is tagged with its kind: make, model, model group, category (with the code the `category`/`subcategory` filters take) and dealer (with the id the `seller` action takes). Use it to turn free text into values the filters will actually match, instead of guessing a spelling the source answers with zero rows.

ParameterAllowed / rangeDescription
queryrequired—What the user has typed so far, from 2 characters up. The answer mixes makes, models, model groups, categories and dealers, each tagged with its kind and carrying the value the matching filter wants — so a UI never has to guess a spelling the source would answer with zero rows.
market = comoptionalcom · uk · ie · au · nz · za · de · at · lu · nl · be · it · pt · mx · pl · cz · sk · hu · ro · bg · hr · si · rs · me · gr · se · no · dk · fi · ee · lt · lv · ua · ua_ru · tr · jp · kr · tw · arWhich country front-end to read. All 39 share ONE catalogue, so this picks the LANGUAGE this action answers in, not a different inventory. Three front-ends the marketplace itself links (mascus.fr, mascus.es, mascus.com.br) answer HTTP 404 for every listing and return MARKET_UNAVAILABLE.
Try in playground →
post/mascus/v1/brands1 credit

The makes the marketplace itself promotes per sector, with a live listing count each — the source's own shortlist of the biggest manufacturers in construction, transport, agriculture, material handling, forestry and groundcare. A cheap, single-call answer to 'what is actually traded here and in what volume'. For the COMPLETE make list of a specific query, including the long tail, use `facets` and read its `brand` group.

ParameterAllowed / rangeDescription
market = comoptionalcom · uk · ie · au · nz · za · de · at · lu · nl · be · it · pt · mx · pl · cz · sk · hu · ro · bg · hr · si · rs · me · gr · se · no · dk · fi · ee · lt · lv · ua · ua_ru · tr · jp · kr · tw · arWhich country front-end to read. All 39 share ONE catalogue, so this picks the LANGUAGE this action answers in, not a different inventory. Three front-ends the marketplace itself links (mascus.fr, mascus.es, mascus.com.br) answer HTTP 404 for every listing and return MARKET_UNAVAILABLE.
Try in playground →
post/mascus/v1/seller2 credits

One dealer's public business profile by id: company name, postal address (street, postcode, town, region, country), visiting address where they publish one, website, logo, their own description of the business, the makes they list themselves under, their branch outlets, map coordinates, and how long they have traded on this marketplace with the date that count runs from. 🔴 The source also returns a named salesperson, a direct e-mail, a mobile and a switchboard number on this object; none of it is returned here on any action. Use `seller_listings` for this dealer's stock.

ParameterAllowed / rangeDescription
dealer_idrequired—The dealer's 8-character id, as every search row returns it in `seller.dealer_id`, as `suggest` returns it for a dealer match, and as the source's own dealer links carry it. A full GUID is shortened for you.
market = comoptionalcom · uk · ie · au · nz · za · de · at · lu · nl · be · it · pt · mx · pl · cz · sk · hu · ro · bg · hr · si · rs · me · gr · se · no · dk · fi · ee · lt · lv · ua · ua_ru · tr · jp · kr · tw · arWhich country front-end to read. All 39 share ONE catalogue, so this picks the LANGUAGE this action answers in, not a different inventory. Three front-ends the marketplace itself links (mascus.fr, mascus.es, mascus.com.br) answer HTTP 404 for every listing and return MARKET_UNAVAILABLE.
Try in playground →
post/mascus/v1/seller_listings3 credits

One dealer's full stock, as rows identical to `search`, with every `search` filter and sort available on top. 🔴 This is the action the source makes easiest to get wrong: handing its dealer filter the complete GUID answers HTTP 200 with 125 rows from FOUR different companies, because the GUID's middle segment is shared. This endpoint sends only the short id the source's own dealer links use, and then checks that what came back really belongs to one company before returning it — if it does not, you get an error rather than four dealers' machines labelled as one.

ParameterAllowed / rangeDescription
dealer_idrequired—The dealer's 8-character id, as every search row returns it in `seller.dealer_id`, as `suggest` returns it for a dealer match, and as the source's own dealer links carry it. A full GUID is shortened for you.
market = comoptionalcom · uk · ie · au · nz · za · de · at · lu · nl · be · it · pt · mx · pl · cz · sk · hu · ro · bg · hr · si · rs · me · gr · se · no · dk · fi · ee · lt · lv · ua · ua_ru · tr · jp · kr · tw · arWhich country front-end to read. All 39 share ONE catalogue, so this does NOT pick a different inventory: it picks the language of the labels on `detail`, `categories` and `suggest`, and 🔴 the UNITS — the international front-end ('com') reports the odometer in MILES, the other 38 in kilometres. `mileage_km` is normalised on every market and `mileage_km_min/max` is always in kilometres, so you never have to care. Three front-ends the marketplace itself links (mascus.fr, mascus.es, mascus.com.br) answer HTTP 404 for every listing and return MARKET_UNAVAILABLE rather than a half-filled answer.
currency = EURoptional—The currency to convert into, one of the 131 the source supports (EUR, USD, GBP, PLN, SEK, CZK, HUF, TRY, JPY, ZAR…). 🔴 Two measured consequences. (1) `price_min`/`price_max` are bands IN THIS CURRENCY: the same 10,000-50,000 band answers 19,366 rows in EUR and 18,583 in USD. (2) The conversion appears as `price_converted` + `price_converted_currency`, never as `price` — `price` and `currency` are always the seller's own asking price and do not move with this parameter.
queryoptional—Free-text keyword, as typed into the marketplace's own search box: a machine type ('excavator', 'bagger'), a make, a model, or several words. Extra words NARROW here rather than widen — measured: 'excavator' 46,033 rows, 'caterpillar 320' 2,273 — and an unmatched word gives an honest empty answer. 🔴 FREE TEXT IS SCORED IN THE CHOSEN FRONT-END'S OWN LANGUAGE, so the same word is a different query per market: 'excavator' answered 46,041 rows on the international front-end and 46,118 on the German one, and the first 40 rows of the two had NOT ONE listing in common (a make-and-model query such as 'Kubota M5-111D' does match identically on both). A result set that must be reproducible across markets has to be pinned with the typed filters or a dealer, not with free text.
catalogoptionalconstruction · cargo-transport · agriculture · materialhandling · forestry · groundscareOne of the marketplace's six sectors. Comma-separate for several. 🔴 The value is the sector CODE, which differs from the URL slug on three of the six ('cargo-transport' not 'transportation', 'materialhandling' not 'material-handling', 'groundscare' not 'groundcare') — a value guessed off a URL returns zero rows, so the codes are published and validated here.
categoryoptional—Category code inside a sector, as the `categories` action returns it ('excavators', 'tractors', 'trucks', 'forklifts'). Comma-separate for several. An unknown code is answered honestly with zero rows rather than ignored, but reading the code out of `categories` or `suggest` is the way to be sure.
subcategoryoptional—The third taxonomy level ('crawlerexcavators', 'miniexcavators', 'wheelexcavators'), from the `categories` action with a `category_code` set. This is how you get from 40,068 excavators to the 20,806 crawler excavators.
brandoptional—Make, spelled the way the source's own facet spells it ('CAT' not 'Caterpillar', 'John Deere', 'Volvo', 'Mercedes-Benz'). Case does not matter, the spelling does — read it from `facets` or let `suggest` map what a user typed. Measured to bite: 46,035 rows for 'excavator' → 9,913 for CAT.
modeloptional—Model name, as the source's own type-ahead spells it. Only works with `brand` — a bare model name is ambiguous across makes, so it is rejected rather than returning an answer that looks filtered. Measured: brand=CAT + model=320 → 1,553 rows.
countryoptional—Seller country, 2-letter ISO code. Comma-separate for several. 80 countries have stock on a typical query; the `facets` action lists them with counts. Measured to bite: 46,035 → 3,494 for DE.
conditionoptionalused · new · reconditioned · remanufactured · demo · vintage · damaged · dismantled · operates_with_deficiencies · rental_possibilityCondition class. Comma-separate for several. The source stores these as numeric property ids; this takes the words and sends the ids. Measured: 46,035 → 4,458 for 'new'.
ad_typeoptionalusedad · auctionad · rentaladThe structural kind of advert. 🔴 An unknown value is NOT an error on this source: it is dropped and you get the whole unfiltered catalogue with HTTP 200, so this endpoint validates it instead of forwarding it. Measured to bite: 46,035 → 5,116 auction lots, → 333 rental machines.
year_minoptional1900–2100Earliest year of construction, inclusive. 🔴 The source's own name for this filter is not the obvious one and the obvious one is accepted with HTTP 200 and then ignored, so a naive year window returns the unfiltered catalogue looking filtered. Here it bites: 46,035 → 11,205 for 2015-2020.
year_maxoptional1900–2100Latest year of construction, inclusive. Note the source carries seller-entered years as far ahead as 2027, so an open-ended upper bound is not the same as 'up to this year'.
price_minoptional0–Lowest price to include, 🔴 IN THE `currency` YOU ASKED FOR (default EUR), not in the seller's currency. Measured: the same 10,000-50,000 band answers 19,366 rows in EUR and 18,583 in USD. Any price bound also excludes the listings that publish no price at all and the source's own 0 and 1 placeholder prices.
price_maxoptional0–Highest price to include, 🔴 in the `currency` you asked for (default EUR), not in the seller's currency. Setting it also excludes every listing that publishes no price at all.
operating_hours_minoptional0–Lowest hour-meter reading to include, in hours — the field a used-plant buyer prices on. Verified front-end independent, unlike the odometer: the 0-2,000 h band answers the same 412 rows on the international and the German front-end.
operating_hours_maxoptional0–Highest hour-meter reading to include, in hours. Measured to bite: 46,035 → 412 for 0-2,000 h on the transport sector.
with_price = falseoptional—Only listings that publish a price. Most of this marketplace does not — auction lots carry none at all and many dealers list 'price on request' — so this is the most useful narrowing filter for a pricing job. Measured: 46,035 → 32,305.
sort = relevanceoptionalrelevance · price_asc · price_desc · year_desc · year_asc · newest · oldest · hours_asc · hours_desc · mileage_asc · mileage_desc · brand_asc · brand_desc · model_asc · model_desc · country_asc · country_descResult order. Every value was checked to change the DATA, not merely be accepted; 🔴 a value outside this list is accepted with HTTP 200 and then ignored, so it is validated here. Read the notes on `price_asc` and `hours_asc` first: both change WHICH rows you get, not only their order.
page = 1optional1–Page number, from 1. 🔴 `page x page_size` must stay at or below 10,000: past that the source answers HTTP 200 and serves PAGE 1'S ROWS under the page number you asked for (measured at four page sizes), so the combination is refused rather than letting a paging loop re-ingest the first page for ever. `meta.pagination` publishes `last_page`, `retrievable_max` and an honest `has_more`.
page_size = 40optional1–200Rows per page, 1-200 (the source's own default is 40). A large page is the cheap way to the 10,000-row ceiling: at 200 it takes 50 calls instead of 250.
Try in playground →
Built for volume
5M+ requests a day

Measured at 60 requests a second across the fleet, with no central bottleneck. Volume pricing is on request, and per-key limits are raised for high-volume accounts.

Missing a source?
We build it

Tell us a site we do not cover yet and it becomes an engine. A customer asked for bestprice.gr on a Sunday and it was in the catalog the next day.

Support
2 minute median reply

Median time from a question in the live chat to the first answer, measured across every answered conversation. Setup help included, no support tier to buy.

One key, one balance
Every API included

No per-site plans and no separate subscriptions. One key and one credit pool across the whole catalog, so adding a source costs nothing up front.

Planning something large? Tell us the volume and the sources and we will come back with what it costs and what we would have to build.