Looking for the overview — what this API returns, what it costs, and a call you can run without a key? See the Kolesa.kz API page →
Classifieds & Second-hand

Kolesa.kz API & Scraper

The Kolesa.kz API returns Kazakhstan's largest car marketplace as clean JSON, in two actions: search and listing.

2 actionsLive JSON1,000 free credits$0.67–$1.50 / 1,000 creditsMCP-ready
Get a free keyOpen in playground

🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.

Kolesa.kz is where Kazakhstan actually buys and sells cars: on 2026-10-02 its live board held 161,697 car ads — 97,702 passenger cars, 47,431 SUVs and pickups, 14,439 minivans and minibuses, 157,033 used and 4,667 brand-new, 10,060 posted by dealers, 48,905 all-wheel-drive, 53,372 manual, 9,578 right-hand-drive Japanese imports, 5,949 diesel and 1,254 electric. By city it was 42,852 in Almaty, 20,391 in Astana and 13,725 in Shymkent. search narrows that by free-text keywords, brand and model, city or region, a price band in tenge, model year, maximum mileage, engine displacement, body style, gearbox, fuel, colour, drivetrain, steering side, new or used, vehicle class, dealers-only, customs-cleared, damaged-only and has-photo, with seven sort orders, and it returns 20 rows a page. Every row carries the advert id, the public URL, the title, the brand and model, the year, the price in tenge together with the exact string Kolesa prints on the card, Kolesa's own average asking price for that brand and model, the condition, body, engine size, fuel, gearbox, steering side, mileage, colour, the option list, the truncated seller description, the city slug and its printed name, the ISO region code, the seller id, whether that seller is a private owner or a business, whether the car is new, whether trade-in and credit are offered, the photo count, the ad status, when it was last updated and until when it is published, which paid placements it has, and a thumbnail. listing adds the complete seller description, every photo at full size, the whole parameter table the ad page prints — generation, body, engine, mileage, gearbox, drivetrain, steering, colour, customs status, VIN where published — and the seller's public block: private owner or business, the dealer's name, verification badge, address, how long they have been on Kolesa and how many ads they have live, plus the phone prefix the page itself shows and how many numbers are on file. Verified on 2026-10-02 across two separate runs: 34 of 34 live checks behaved as expected, 22 of 22 exposed filters measurably narrowed the same-run control, all 12 cohorts — passenger cars, SUVs, minivans, new, used, electric, diesel, dealers, damaged, right-hand-drive, brand+model and city — returned 20 rows each and resolved their first advert to a full detail record, and the price matched the figure Kolesa prints on its own page 12 of 12 with zero mismatches. No Kolesa account — one ReefAPI key and the standard { ok, data, meta, error } envelope.

Reference

What is actually on the board — live ad counts on 2026-10-02

These are counts read off the live index, one call each, not estimates. Each one is the unfiltered 161,697-ad board narrowed by exactly one filter in the same run, which is also how every filter was proven to do something. They move as ads are posted and expire; every search response carries the matching total in the response body.

slicefilterlive ads
Everything(no filter)161,697
Used carscondition=used157,033
Already customs-cleared in Kazakhstancustoms_cleared=true157,582
With at least one photowith_photo=true159,960
Passenger carsvehicle_class=car97,702
SUVs and pickupsvehicle_class=suv-pickup47,431
All-wheel drivedrive=all48,905
Manual gearboxtransmission=manual53,372
Almaty citycity=almaty42,852
Almaty regionregion=almaty-region44,535
1.3–1.6 litre enginesengine_volume 1.3–1.644,208
White carscolor=white31,047
Crossoversbody=crossover30,864
Toyotabrand=toyota29,943
2020 or neweryear_min=202035,261
Astana citycity=astana20,391
2–3 million tengeprice 2,000,000–3,000,000 ₸19,497
Under 50,000 kmmileage_max=5000019,406
Minivans and minibusesvehicle_class=minivan-minibus14,439
Shymkent citycity=shymkent13,725
Keyword "camry"query=camry11,356
Toyota Camrybrand=toyota&model=camry10,454
From dealers and businessesdealers_only=true10,060
Right-hand drivesteering=right9,578
Dieselfuel=diesel5,949
Brand newcondition=new4,667
Toyota Camry in Almatybrand=toyota&model=camry&city=almaty2,514
Damaged / not roadworthydamaged_only=true3,230
Electricfuel=electric1,254

🔴 Paging stops at page 1,000. The site's own page selector says so ("1 из 1000"), and pages 1,001, 1,500 and 4,000 all return exactly what page 1,000 returns. At 20 rows a page that is 20,000 rows per query, so a query on the whole 161,697-ad board can only be walked a quarter of the way. Every response therefore returns both total_results (the site's own count) and reachable_rows (how many paging can actually hand you), so you never have to discover this yourself. Narrow with brand, model, city or a price band and the ceiling stops mattering: every slice in the table above at or below 20,000 ads is fully walkable.

Live example

Real request and response JSON

Captured from the indexed primary action, search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/kolesa/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "brand": "toyota",
    "city": "almaty",
    "max_results": 20
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "kolesa",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 2372.5,
    "record_count": 20,
    "bytes": 184036,
    "cache_hit": false,
    "upstream_requests": 1,
    "exit_country": "kz",
    "source_url": "https://m.kolesa.kz/cars/toyota/almaty/",
    "charged_credits": 1,
    "version": "1.0.0",
    "request_id": "e4ab10266d154398",
    "queue_ms": 1.6
  },
  "data": {
    "total_results": 8372,
    "reachable_rows": 8372,
    "page": 1,
    "page_size": 20,
    "page_count": 419,
    "page_at_ceiling": false,
    "has_more": true,
    "promoted_tiles_excluded": 3,
    "sort": "default",
    "query": null,
    "empty_reason": null,
    "filters": {
      "path": "/cars/toyota/almaty/"
    },
    "listings": [
      {
        "listing_id": "213867547",
        "url": "https://kolesa.kz/a/show/213867547",
        "title": "Toyota Land Cruiser Prado 1998 г.",
        "brand": "Toyota",
        "model": "Land Cruiser Prado",
        "year": 1998,
        "condition": "used",
        "body": "offroad",
        "engine_volume_l": 3.4,
        "fuel": "petrol",
        "transmission": "automatic",
        "steering": null,
        "mileage_km": null,
        "color": "green",
        "options": [
          "металлик",
          "литые диски",
          "тонировка"
        ],
        "description_excerpt": "Продаю надёжный и проходимый Toyota Land Cruiser Prado 90. Машина — европеец, левый руль, двигатель 3.4 бензин, легендарный мотор 5VZ-FE. Автомобиль подходит как для города, так и для дальних поездок, отдыха и лёгкого бездорожья. Комплектация и…",
        "city": "almaty",
        "city_name": "Алматы",
        "region_code": "KZ-ALM",
        "seller_id": 6008261,
        "seller_type_id": 6,
        "seller_kind": "private",
        "is_new": false,
        "is_trade_in": false,
        "credit_available": true,
        "has_video": false,
        "photo_count": 6,
        "status": "live",
        "availability": "В наличии",
        "updated_at": "2026-10-02T03:55:55+05:00",
        "published_until": "2026-10-02T23:59:59+05:00",
        "paid_services": [
          "Поднято наверх"
        ],
        "promoted": true,
        "labels": [],
        "posted_label": "2 октября",
        "image": "https://kolesa-photos.kcdn.online/webp/64/6456ab8d-8f4d-4338-a39c-a145e229ea94/13-160x120.jpg",
        "spec_line": [
          "1998 г.",
          "Б/у внедорожник",
          "3.4 л"
        ],
        "price": 7700000,
        "price_currency": "KZT",
        "price_kind": "fixed",
        "price_display": "7 700 000 ₸",
        "market_avg_price": 7431000
      },
      {
        "listing_id": "216670942",
        "url": "https://kolesa.kz/a/show/216670942",
        "title": "Toyota RAV4 2020 г.",
        "brand": "Toyota",
        "model": "RAV 4",
        "year": 2020,
        "condition": "used",
        "body": "crossover",
        "engine_volume_l": 2,
        "fuel": "petrol",
        "transmission": "cvt",
        "steering": null,
        "mileage_km": 130000,
        "color": "white",
        "options": [
          "металлик",
          "кожа",
          "ГУР"
        ],
        "description_excerpt": null,
        "city": "almaty",
        "city_name": "Алматы",
        "region_code": "KZ-ALM",
        "seller_id": 12109456,
        "seller_type_id": 0,
        "seller_kind": "private",
        "is_new": false,
        "is_trade_in": false,
        "credit_available": true,
        "has_video": false,
        "photo_count": 20,
        "status": "live",
        "availability": "В наличии",
        "updated_at": "2026-10-02T03:09:22+05:00",
        "published_until": "2026-10-02T23:59:59+05:00",
        "paid_services": [
          "Поднято наверх"
        ],
        "promoted": true,
        "labels": [
          "История авто"
        ],
        "posted_label": "2 октября",
        "image": "https://kolesa-photos.kcdn.online/webp/27/27ce5544-1bbe-4fce-a546-a1836b5321ab/1-160x120.jpg",
        "spec_line": [
          "2020 г.",
          "Б/у кроссовер",
          "2 л"
        ],
        "price": 14000000,
        "price_currency": "KZT",
        "price_kind": "fixed",
        "price_display": "14 000 000 ₸",
        "market_avg_price": 14484000
      },
      {
        "listing_id": "231476137",
        "url": "https://kolesa.kz/a/show/231476137",
        "title": "Toyota Camry 2006 г.",
        "brand": "Toyota",
        "model": "Camry",
        "year": 2006,
        "condition": "used",
        "body": "sedan",
        "engine_volume_l": 2.4,
        "fuel": "petrol",
        "transmission": "automatic",
        "steering": null,
        "mileage_km": null,
        "color": null,
        "options": [
          "Родной краска Удар көрмеген Естима мотор Срочно"
        ],
        "description_excerpt": null,
        "city": "almaty",
        "city_name": "Алматы",
        "region_code": "KZ-ALM",
        "seller_id": 31015194,
        "seller_type_id": 6,
        "seller_kind": "private",
        "is_new": false,
        "is_trade_in": false,
        "credit_available": true,
        "has_video": false,
        "photo_count": 14,
        "status": "live",
        "availability": "В наличии",
        "updated_at": "2026-10-02T02:52:44+05:00",
        "published_until": "2026-10-02T23:59:59+05:00",
        "paid_services": [
          "Поднято наверх"
        ],
        "promoted": true,
        "labels": [],
        "posted_label": "2 октября",
        "image": "https://kolesa-photos.kcdn.online/webp/33/332507d6-2298-42cc-8d0f-a2e1700b90d3/1-160x120.jpg",
        "spec_line": [
          "2006 г.",
          "Б/у седан",
          "2.4 л"
        ],
        "price": 5600000,
        "price_currency": "KZT",
        "price_kind": "fixed",
        "price_display": "5 600 000 ₸",
        "market_avg_price": 5097000
      }
    ]
  }
}
Actions

What the Kolesa.kz API does

ActionDescriptionConcrete use caseKey params
searchSearch Kolesa.kz car classifieds. Every parameter is optional — with none of them you get the whole board, newest first — and each filter below was measured narrowing the same 161 697-row control in the same run. Returns 20 rows a page with the source's own total, and tells you how many of those rows paging can actually reach (the source stops at page 1000).Price-intelligence teams call search to search Kolesa.kz car classifieds.query, brand, model, city, region, ...
listingFull detail of one advert by id or URL: the complete seller description, every photo at full size, the price with the source's own printed string, the entire parameter table, the option list, and the seller's public block (kind, dealer name, verification badge, address, ads on file, phone prefix and how many numbers are on file). A removed or non-existent advert returns NOT_FOUND. The seller's phone number itself is never requested and never returned, and a PRIVATE seller's display name is not published on this page at all — `seller.name` is null there and `seller.name_published` says so.Classifieds aggregators call listing to get full detail of one advert by id or URL.listing_id, url
Code samples

Call search from your stack

curl -X POST https://api.reefapi.com/kolesa/v1/search \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"brand":"toyota","city":"almaty","max_results":20}'
MCP one-liner
Ask your MCP-connected assistant: call reefapi.kolesa.search with {"brand":"toyota","city":"almaty","max_results":20}.
Use cases

Who uses this API and why

  • Price used stock for a Central Asian dealer or exporter: pull every Toyota Camry on the board (10,454 ads, 2,514 of them in Almaty), keep each asking price in tenge beside Kolesa's own average for the model, and filter by year, mileage and gearbox to compare like with like.
  • Track the Japanese right-hand-drive import market that Kazakhstan runs on: 9,578 RHD cars live, filterable by brand, mileage and whether they are already customs-cleared (157,582 of 161,697 are), each with the full description and every photo.
  • Watch Kazakhstan's EV adoption with a number instead of a press release: 1,254 electric cars live out of 161,697, 0.8 % of the board — page the whole slice, since it is far inside the 20,000-row reach, and re-run it on a schedule to get the curve.
  • Monitor dealer inventory and pricing: 10,060 ads come from businesses, and any one of their adverts returns the dealer's name, official-dealer badge, address, years on Kolesa and live ad count — so you can follow a competitor's stock and asking prices without an account.
  • Build a saved-search alert for buyers: sort by newest, poll the first page of a narrow query (brand, city, price band), and use total_results as a cheap signal that the matching set moved before you pull more pages.
FAQ

Questions developers ask before integrating

Which currency are the prices in?

Tenge (KZT), whole units, with no sub-unit — and nothing else: every price on every page we sampled was in tenge, and there is no second currency on this site. Each row returns price as an integer plus price_display, the exact string Kolesa prints on its own card ("350 000 ₸", "71 500 000 ₸"), so you can check our number against the source's own rendering rather than trusting us. Across 12 cohorts, the integer and the printed string agreed 12 of 12, with zero mismatches. We do not convert anything to dollars: a converted price is our arithmetic, not the seller's asking price.

What is market_avg_price?

Kolesa's own average asking price for that brand and model, which it prints next to its own listings. It is the site's figure, not our calculation, and we pass it through unchanged — so a 350,000 ₸ Toyota Corsa comes back with market_avg_price 429,000 and a 1,150,000 ₸ Lada Priora with 1,493,000. It is not on every row: Kolesa publishes it for models it has enough data on, and where it does not, the field is null rather than a guess.

How do I tell a dealer from a private owner?

Every search row and every detail record carries seller_kind, which is either private or business, and we did not infer it from the ad's wording. Kolesa's own dealer filter narrowed the 161,697-ad board to 10,060, and on that filtered page all 20 rows came back business while all 20 rows of the unfiltered control came back private — a clean 40-row split. Set dealers_only to get only businesses; to get only private owners, filter the rows on seller_kind, because Kolesa's own who parameter returns an empty page for every value we tried and we will not ship a handle that does nothing.

What do I get about the seller?

What the ad page itself shows, unmodified. For a dealer that is the business name, the "official dealer" badge, the street address, how long they have been on Kolesa and how many ads they have live — on one sampled dealer: Porsche Centre Astana, official dealer, Астана, Проспект Туран 74/1, 2 years on Kolesa.kz, 72 ads. For a private owner it is the seller id, the kind, and the phone prefix the page prints (for example "+7 775") with how many numbers are on file. 🔴 A private owner's display name is NOT published on the ad page at all — Kolesa only reveals it together with the phone number — so seller.name is null there and seller.name_published tells you so. We would rather say that than show you an empty string and let you guess.

Do I get the seller's phone number?

No. Kolesa keeps the number behind a separate request on its own site, and this API never makes it and never returns it. What you do get is what the ad page itself prints: the dialling prefix (for example "+7 775"), how many numbers the seller has on file, and whether the seller has chosen to hide them.

Does a filter actually do anything, or does the site just ignore it?

Every filter we expose was measured against the same-run unfiltered control of 161,697 ads, and only the ones that moved the total are offered — 22 for 22. Some examples: Toyota 29,943, Toyota Camry 10,454, Almaty 42,852, a 2–3 million tenge band 19,497, under 50,000 km 19,406, crossover 30,864, manual 53,372, electric 1,254, white 31,047, right-hand drive 9,578, all-wheel drive 48,905, brand new 4,667, dealers 10,060, damaged 3,230. Two things the site accepts and then ignores are deliberately not exposed: an unknown parameter name (we passed a nonsense key and got the identical 161,697 rows back) and an unknown sort value (the row order did not budge). So an unknown enum or sort gets INVALID_PARAM from us instead of a convincing wrong answer from the site.

How many ads can I page through?

Twenty thousand per query, and we say so in every response. Kolesa stops at page 1,000 — its own page selector reads "1 из 1000", and pages 1,001, 1,500 and 4,000 all return exactly the rows page 1,000 returns. At 20 rows a page that is 20,000 rows, so the full 161,697-ad board cannot be walked in one query. Every search response carries total_results (Kolesa's own count) and reachable_rows (the smaller, honest number), plus page_at_ceiling so a crawler knows to stop. The fix is to split the query: by brand, by city, by price band or by year. Every slice at or below 20,000 ads — Toyota Camry, Astana, a 2–3 million tenge band, electric, new, dealers, diesel, right-hand drive — is reachable to its last row.

How many rows per page, and can I ask for more?

Twenty, and it is fixed — there is no page-size parameter on this site and we do not pretend otherwise. We measured 20 rows on pages 1, 2, 3, 7, 50, 300 and 1,000, and the response reports page_size from what actually came back rather than from a constant. Each page also carries up to three paid "VIP" placement cards that Kolesa itself does not count as results; those are excluded and the number removed is reported as promoted_tiles_excluded, so your row count is never quietly different.

Why is mileage null on some cars?

Because the card did not print one. Kolesa's search cards show a chip row — year, condition and body, engine size, fuel, steering side, gearbox, mileage, colour, then options — and not every ad fills every chip: a 1995 Toyota Corsa came back with 420,000 km and no gaps, while a 2012 Lada Priora on the same page printed no mileage and no steering side at all. We return null for what the source did not publish instead of a zero, and the raw chip list is in spec_line on every row so you can see exactly what the card said. If you need mileage guaranteed, call listing: the detail page's own parameter table carries it where the seller entered it.

Can I filter by minimum mileage, or by mileage range?

Only a maximum. Kolesa publishes an upper mileage bound in its own form and no lower one, so mileage_max exists (measured: 161,697 to 19,406 at 50,000 km) and mileage_min does not. We would rather leave it out than ship a parameter the site throws away — on this site an unknown parameter is accepted silently and changes nothing, which is exactly how a useless filter looks like a working one.

Can I search by brand and model without knowing Kolesa's ids?

Yes — brand and model are Kolesa's own URL slugs, so toyota, bmw, mercedes-benz, hyundai, lada, camry, land-cruiser and x5 are what you pass, and every search row returns its own brand and model so the spelling never has to be guessed twice. Two honest limits: model only works together with brand (Kolesa answers a bare model with a 404, and we return MISSING_PARAM with that reason rather than a mysterious empty page), and an unknown brand slug comes back as NOT_FOUND because that is literally what the site answers.

Can I combine a city and a region?

No, and we block it rather than answer the wrong question. City goes into Kolesa's URL path and region into its query string, and when both are present the region silently wins: /cars/almaty/ with the Almaty-region filter added returned 44,537 ads — the region's number — not Almaty city's 42,852. So the pair returns INVALID_PARAM with that measurement in the message. Pass one: city for a single city (almaty 42,852, astana 20,391, shymkent 13,725), region for a whole oblast.

What does listing add over a search row?

The complete seller description instead of the truncated card text — 356 and 731 characters on the two ads we sampled, with the site's <br> tags and HTML entities already cleaned out — plus every photo at full size (7 and 34 on those two ads, matching Kolesa's own photo count exactly both times), the entire parameter table the ad page prints as label/value rows (10 and 9 rows on those two: city, generation, body, engine, mileage, gearbox, drivetrain, steering, colour, customs status), the option list, and the seller block described above. Everything in the search row is in there too, and an advert id taken from search resolved to the same record every time we checked.

What happens if I ask for an advert that has been removed?

You get NOT_FOUND with a message saying the advert is removed or never existed, never a blank success you have to interpret — Kolesa answers a dead id with a real 404 and we pass that through as the answer it is. A search that genuinely matches nothing is a different thing and treated as one: ok with zero rows, total_results 0, and an empty_reason saying the site returned its own "nothing found" page. We measured both, on two separate runs.

docs / kolesa

Kolesa.kz

Kazakhstan's biggest car marketplace as JSON: 161,697 live car ads with price in tenge, brand, model, year, mileage, city, dealer-or-owner and Kolesa's own average market price.

base /kolesa/v12 endpoints
post/kolesa/v1/listing2 credits

Full detail of one advert by id or URL: the complete seller description, every photo at full size, the price with the source's own printed string, the entire parameter table, the option list, and the seller's public block (kind, dealer name, verification badge, address, ads on file, phone prefix and how many numbers are on file). A removed or non-existent advert returns NOT_FOUND. The seller's phone number itself is never requested and never returned, and a PRIVATE seller's display name is not published on this page at all — `seller.name` is null there and `seller.name_published` says so.

ParameterAllowed / rangeDescription
listing_idoptional—Advert id — the number at the end of every kolesa.kz/a/show/<id> URL and the `listing_id` of every search row. Give this or `url`.
urloptional—Full advert URL exactly as `search` returns it; the id is taken from its /a/show/<id> tail. Give this or `listing_id`.
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.