# traktorpool API — live used and new agricultural machinery listings from traktorpool.de, a German farm-machinery marketplace (about 150,000 listings: tractors, combines, balers, tillage, sprayers, telehandlers, parts). Search by keyword, machine group, machine type, manufacturer or seller and read every listing in full: net and gross price with the seller's VAT rate, year of construction, hour meter, engine power, condition, location, the full technical table, extras, description, photos and the dealer behind it. No login, no API key.

> Search or browse the marketplace by keyword, machine group/type, manufacturer, model, seller, seller type, condition, year, net price, hour meter, engine power, seller country, postal code + radius and listing age; every filter measured to bite against an unfiltered control. An empty call browses all ~150,000 listings. Returns the organic rows plus the paid top-offer cards the page shows (flagged), with the source's own exact total. 25/50/100 rows a page, at most 15 pages.
> ReefAPI engine `traktorpool` · 2 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/traktorpool/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/traktorpool/v1/search — 3 credits
Search or browse the marketplace by keyword, machine group/type, manufacturer, model, seller, seller type, condition, year, net price, hour meter, engine power, seller country, postal code + radius and listing age; every filter measured to bite against an unfiltered control. An empty call browses all ~150,000 listings. Returns the organic rows plus the paid top-offer cards the page shows (flagged), with the source's own exact total. 25/50/100 rows a page, at most 15 pages.

**Parameters:**
- `query` (string, optional) — Free-text search, as typed into the site's own search box. Combines with the category, manufacturer and seller filters. Measured: 'vario' 3,910 listings across the marketplace, 2,282 inside category 24 (tractors).
- `category_id` (integer, optional) — Top-level machine group id, the number in the site's own '/gebraucht/a-<name>/<id>/' URLs and the `category_group_id` of a detail record. Examples: 24 Traktoren, 6 Erntemaschinen, 11 Grünlandgeräte, 4 Bodenbearbeitung, 23 parts market, 14 yard loaders/excavators/forklifts.
- `subcategory_id` (integer, optional) — Machine type id inside a group (the '/b-<name>/<id>/' URL part, `category_id` of a detail record), e.g. 95 = Traktoren inside group 24. Requires `category_id`.
- `manufacturer_id` (integer, optional) — Manufacturer id, the number in '/gebraucht/c-<name>/<id>/' and `manufacturer_id` of a detail record. Examples: 159 Fendt, 85 John Deere, 39 Claas, 163 New Holland, 161 Massey Ferguson, 157 Deutz-Fahr, 155 Case IH, 805 Valtra, 308 Kubota.
- `model` (string, optional) — Model text as the source matches it. Fendt + model 828: 253 listings, 24 of 24 rows carry 828.
- `seller_id` (integer, optional) — Only this seller's listings (the `seller_id` of a search row or detail record).
- `seller_type` (enum, optional) — Dealer or private seller. Fendt: commercial 4,914 + private 137 = 5,051 (an exact split). [one of: commercial, private]
- `condition` (enum, optional) — The source's own condition values. Fendt: used 3,654 / new 697 of 5,051. [one of: used, new, demonstration, showroom_machine, accident_or_fire_damage]
- `year_min` (integer, optional) — Earliest year of construction, inclusive. Measured: Fendt 5,051 -> 943 with year_min=2024, 0 of 24 rows outside.
- `year_max` (integer, optional) — Latest year of construction, inclusive. Fendt 2015-2020: 984 listings, 0 of 21 rows outside.
- `price_min` (number, optional) — Lowest price in EUR, net of VAT (the figure the rows return as price_net).
- `price_max` (number, optional) — Highest price in EUR, net of VAT. Fendt 10,000-50,000: 587 listings, 0 of 23 rows outside.
- `operating_hours_min` (integer, optional) — Hour meter at least this. NEEDS subcategory_id: without a machine type the source ignores it (measured: Fendt 5,051 -> 5,051, 6 of 9 rows outside), so the call is refused. Fendt tractors (subcategory 95) >= 10,000 h: 412 listings, 0 of 25 rows outside.
- `operating_hours_max` (integer, optional) — Hour meter at most this. NEEDS subcategory_id. Fendt tractors <= 2,000 h: 738 of 2,888, 0 of 24 rows outside. Listings that do not state hours are dropped by the source, and its 'may still match' padding after the real matches is cut.
- `power_kw_min` (integer, optional) — Engine power at least this many kW. NEEDS subcategory_id (same rule as hours).
- `power_kw_max` (integer, optional) — Engine power at most this many kW. NEEDS subcategory_id. Fendt tractors 150-250 kW: 986, 0 of 23 rows outside.
- `country` (string, optional) — Seller country, ISO 3166 alpha-2 (the source's own list of 190 codes). Fendt in NL: 565, 0 of 25 rows outside the Netherlands.
- `zip_code` (string, optional) — Postal code to search around; needs `country` and `radius_km`. The distance is to the postal code you give, not to anything on our side. Fendt, DE 80331, 50 km: 13 listings.
- `radius_km` (enum, optional) — Radius around zip_code, the source's own steps. [one of: 10, 25, 50, 100, 150, 200, 300, 400]
- `listed_within_days` (enum, optional) — Only listings published in the last N days (the source's own choices). Fendt, 7 days: 394. [one of: 1, 2, 3, 7, 14, 30, 90, 365]
- `with_images` (boolean, optional) — Only listings with photos.
- `with_videos` (boolean, optional) — Only listings with a video. Fendt: 17.
- `sort` (enum, optional, default "relevance") — Order of the result list, the site's own six orders. [one of: relevance, newest, price_asc, price_desc, year_asc, year_desc]
- `page` (integer, optional, default 1) — Result page. Capped at 15: deeper pages are refused by the source's own anti-bot layer (page 20, 50 and 202 measured refused). Use page_size=100 to read further (up to 1,500 rows per query) or narrow the query.
- `page_size` (enum, optional, default "25") — Organic rows per page, the source's own choices. Paid top-offer cards come on top (5 extra cards on a 25-row page). [one of: 25, 50, 100]

**Returns:** data.listings[]: listing_id, url, title, manufacturer, model, category_slug, condition, price_net (EUR, VAT excluded as the source prints it), price_printed, price_mismatch, currency, price_on_request, vat_note, vat_rate, location, location_zip_city, location_country, year, power_kw, operating_hours, summary, seller_name, seller_id, image_url, image_count, badges, is_top_offer, rank. data.total = the source's own exact match count; data.pagination = page, page_size, last_page, has_more.

**Example request body:**
```json
{
  "manufacturer_id": 159,
  "category_id": 24
}
```

### POST https://api.reefapi.com/traktorpool/v1/detail — 3 credits
One listing in full by its listing number.

**Parameters:**
- `listing_id` (string, required) — The listing number ('Inserats-Nr.'), the `listing_id` of a search row.

**Returns:** data.listing: listing_id, url, title, manufacturer(+_id), model, category_group(+_id), category(+_id), condition, condition_label, seller_type, year, operating_hours, power_kw, price_net, price_gross, vat_rate, currency, price_printed, price_gross_printed, price_on_request, price_mismatch, finance_example_monthly, location, location_zip_city, location_country, specs[] {label, value} (every row of the technical table as the seller filled it, German labels), extras[], description, images[], breadcrumbs[], seller {seller_id, name, address, verified, member_since, listings_online, imprint, listings_url}.

**Example request body:**
```json
{
  "listing_id": "9000462"
}
```

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