# Gaspedaal.nl API scraper — the Dutch car aggregator: search the combined stock of the Netherlands' vehicle sites in one call and get, for every car, the list of sites that list it (AutoTrack, AutoScout24, ANWB, dealer sites, lease portals) with the click-out that resolves to the real listing. Price, year, mileage, fuel, gearbox, body, colour, power, dealer and town, plus brand/model trees. No account, no browser.

> Search Gaspedaal's aggregated Dutch car stock. Every row is ONE car with sources[] = every site that lists it (measured 1-11 sources per car, mean 4.6 over 500 rows). Rows are de-duplicated by ad_id inside the call and duplicates_dropped says how many repeats the live result set served. 100 cars per full page, which is fixed by the site; total_results is Gaspedaal's own count and the whole set is page-able. Every filter here was measured to change that total in the same run. Call with no parameters to page the whole Dutch market.
> ReefAPI engine `gaspedaal` · 5 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/gaspedaal/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/gaspedaal/v1/search — 3 credits
Search Gaspedaal's aggregated Dutch car stock. Every row is ONE car with sources[] = every site that lists it (measured 1-11 sources per car, mean 4.6 over 500 rows). Rows are de-duplicated by ad_id inside the call and duplicates_dropped says how many repeats the live result set served. 100 cars per full page, which is fixed by the site; total_results is Gaspedaal's own count and the whole set is page-able. Every filter here was measured to change that total in the same run. Call with no parameters to page the whole Dutch market.

**Parameters:**
- `query` (string, optional) — Free text, exactly as typed into Gaspedaal's search box: it matches the trim text, brand, model, dealer name and town.
- `brand` (string, optional) — Brand SLUG as Gaspedaal spells it in its own urls (volkswagen, mercedes-benz, bmw). The brands action lists every slug with its id and live car count.
- `model` (string, optional) — Model SLUG for that brand (golf, polo, 3-serie). Requires brand. The models action lists them.
- `brand_id` (string, optional) — Numeric Gaspedaal brand id, the alternative to brand. Use this when you want the id form (brands returns both).
- `model_id` (string, optional) — Numeric Gaspedaal model id. Requires brand_id.
- `price_min` (integer, optional) — Lowest asking price, EUR.
- `price_max` (integer, optional) — Highest asking price, EUR.
- `year_min` (integer, optional) — Earliest build year.
- `year_max` (integer, optional) — Latest build year.
- `mileage_min` (integer, optional) — Lowest odometer, km.
- `mileage_max` (integer, optional) — Highest odometer, km.
- `power_kw_min` (integer, optional) — Lowest engine power, kW.
- `power_kw_max` (integer, optional) — Highest engine power, kW.
- `engine_cc_min` (integer, optional) — Lowest cylinder capacity, cc.
- `engine_cc_max` (integer, optional) — Highest cylinder capacity, cc.
- `cylinders_min` (integer, optional) — Lowest number of cylinders.
- `cylinders_max` (integer, optional) — Highest number of cylinders.
- `seats_min` (integer, optional) — Lowest number of seats.
- `seats_max` (integer, optional) — Highest number of seats.
- `towing_kg_min` (integer, optional) — Lowest braked towing weight, kg.
- `weight_kg_max` (integer, optional) — Highest kerb weight, kg.
- `road_tax_max` (integer, optional) — Highest Dutch road tax (wegenbelasting) per month, EUR, as Gaspedaal publishes it.
- `ev_range_km_min` (integer, optional) — Lowest electric range, km (electric cars).
- `ev_battery_kwh_min` (integer, optional) — Lowest battery capacity, kWh (electric cars).
- `listed_within_days` (integer, optional) — Only cars Gaspedaal has had on offer for at most this many days.
- `doors` (integer, optional) — Exact number of doors.
- `fuel` (string, optional) — Fuel type. Several may be given comma-separated (petrol,diesel) — Gaspedaal ORs them. [one of: petrol, diesel, electric, lpg, cng, hydrogen, hybrid]
- `transmission` (enum, optional) — Gearbox. [one of: automatic, manual]
- `body_type` (string, optional) — Body style. Several may be given comma-separated. [one of: hatchback, estate, mpv, saloon, suv, van, cabrio, coupe, pickup, camper]
- `colour` (string, optional) — Exterior colour as Gaspedaal classifies it. Several may be given comma-separated. [one of: beige, blue, brown, yellow, gold, grey, green, orange, purple, red, white, silver, black]
- `seller_type` (enum, optional) — Who is selling, using Gaspedaal's own seller classes. [one of: private, brand_dealer_selected_make, official_brand_dealer, subdealer, bovag_garage, independent_garage]
- `warranty` (enum, optional) — Only cars sold with this warranty. [one of: bovag, manufacturer]
- `nap_only` (boolean, optional) — Only cars with a verified Dutch NAP mileage record.
- `vat_deductible` (boolean, optional) — true = VAT-deductible cars only (btw-auto); false = margin cars only (marge-auto).
- `postcode` (string, optional) — Dutch postcode to search around. Needed for radius_km and for sort=distance.
- `radius_km` (integer, optional, default 25) — Radius around postcode. Requires postcode; 25 km is used when a postcode is given without it. Any whole number 1-500 is accepted, the listed values are the ones the site's own form offers. [one of: 5, 10, 15, 25, 50, 75, 100, 150]
- `source_site` (integer, optional) — Only cars that are listed on this source site (its numeric id, which every sources[] entry returns and the source_sites action lists). Measured: id 2 = AutoTrack, 213 002 of 348 971 cars.
- `exclude_source_site` (integer, optional) — Drop this source site from every car's sources[], and drop cars that have no other source left.
- `only_source_site` (integer, optional) — Only cars whose ONLY source is this site — i.e. exclusive to it. Measured: id 2 = 7 700 cars, each with exactly one source.
- `sort` (enum, optional) — Order. Omitted = Gaspedaal's own relevance order. sort=distance needs postcode. [one of: relevance, distance, price_asc, price_desc, mileage_asc, mileage_desc, year_asc, year_desc, newest]
- `page` (integer, optional, default 1) — Result page; 100 cars per full page. The last page of a result set is partial and the page after it returns zero rows.
- `resolve_source_urls` (boolean, optional, default false) — Follow each source site's click-out and return the real listing url on that site in sources[].source_url. Costs one extra request per source, so it is capped by max_resolved_urls and by the call budget; anything not resolved stays null and is counted in source_urls_unresolved.
- `max_resolved_urls` (integer, optional, default 10) — Upper bound on how many source click-outs resolve_source_urls may follow in one call.

**Returns:** {total_results, page, page_size, pages, has_more, count, duplicates_dropped, sources_total, source_sites_seen, source_urls_resolved, source_urls_unresolved, price_conflicts, sort_applied, filters_applied{}, search_url, cars[{ad_id, gaspedaal_url, title, brand, model, trim, price_eur, price_eur_schema, price_conflict, currency, year, mileage_km, mileage_conflict, fuel, fuel_source, transmission, transmission_source, body_type, body_type_source, colour, colour_source, doors, engine_cc, power_kw, power_hp, condition, listed_at, photo_url, photo_url_small, seller{name, schema_name, schema_type, page_url, city, province, province_code, country}, source_count, sources[{site, site_id, kind, site_ad_id, click_out_url, source_url, logo_url}]}]}

**Example request body:**
```json
{
  "brand": "volkswagen",
  "model": "golf",
  "max_results": 20
}
```

### POST https://api.reefapi.com/gaspedaal/v1/listing — 3 credits
One car by its Gaspedaal ad id, with the complete source group: every site that lists it, the click-out for each and — unless you switch it off — the resolved real listing url on each source site. Same fields as a search row, both price witnesses compared. A dead or removed ad id returns NOT_FOUND (the site answers HTTP 200 with zero rows, which this engine does NOT pass off as an empty success).

**Parameters:**
- `ad_id` (string, required) — The Gaspedaal ad id, as every search row returns it. Dutch car ads turn over fast, so take a fresh id from search.
- `resolve_source_urls` (boolean, optional, default true) — Resolve each source site's click-out into the real listing url on that site. On by default for a single car; set false to save the extra requests.
- `max_resolved_urls` (integer, optional, default 10) — Upper bound on how many source click-outs resolve_source_urls may follow in one call.

**Returns:** {car{…same shape as a search row…}, source_urls_resolved, source_urls_unresolved}

**Example request body:**
```json
{
  "ad_id": "141844812"
}
```

### POST https://api.reefapi.com/gaspedaal/v1/brands — 2 credits
Every car brand Gaspedaal has stock for, with the slug the search action takes, the numeric brand id, and the live number of cars the site itself prints next to the brand.

**Parameters:** none

**Returns:** {count, total_cars, brands[{brand_id, slug, name, car_count, popular}]}

### POST https://api.reefapi.com/gaspedaal/v1/models — 2 credits
Every model Gaspedaal lists for one brand, with the slug and id the search action takes. Give brand as a slug or brand_id as the numeric id — one of the two is required; calling with neither returns MISSING_PARAM.

**Parameters:**
- `brand` (string, optional) — Brand slug (volkswagen). Give this OR brand_id — one of the two is required.
- `brand_id` (string, optional) — Numeric brand id. Give this OR brand.

**Returns:** {brand{brand_id, slug, name}, count, models[{model_id, slug, name, parent_slug}]}

**Example request body:**
```json
{
  "brand": "volkswagen"
}
```

### POST https://api.reefapi.com/gaspedaal/v1/source_sites — 3 credits
Which Dutch sites Gaspedaal is aggregating right now, counted from a live sample of its own result pages: site name, the numeric id the search filters take, the kind of site (dealer / other / financial / garageconcept) and how many cars of the sample it appeared on. This is a SAMPLE, not a registry — sample_cars says how big it was.

**Parameters:**
- `pages` (integer, optional, default 1) — How many 100-car result pages to sample. More pages find more of the long-tail sites and cost one request each.

**Returns:** {sample_cars, sample_pages, count, sites[{site_id, site, kind, cars_seen, share_pct}]}

**Example request body:**
```json
{
  "pages": 1
}
```

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