Kolesa.kz API

Kazakhstan's biggest car marketplace, as one JSON API

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

no credit card1,000 free credits · instant API key · pay by card or crypto
Missing a Kolesa.kz endpoint, or need a source we don't have yet?Contact us real people · same-day reply.
K
/kolesa/v1

2 active endpoints. Every call is 2 credits.

  • POST/kolesa/v1/search
  • POST/kolesa/v1/listing

What Kolesa.kz endpoints does ReefAPI ship?

2 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.

2 endpoints

search

2 cr

Search Kolesa.kz car classifieds.

required
—
optional
query, brand, model, city, region, price_min, price_max, year_min, year_max, mileage_max, engine_volume_min, engine_volume_max, body, transmission, fuel, color, steering, drive, condition, vehicle_class, dealers_only, customs_cleared, damaged_only, with_photo, sort, page

listing

2 cr

Full detail of one advert by id or URL.

required
—
optional
listing_id, url

Every parameter, every allowed value →

Kolesa.kz API

2 of 2 endpoints, ready to run

View docs ↗

Live Kolesa.kz car ads with the matching total: advert id, URL, title, brand, model, year, price in tenge, Kolesa's own average for the model, mileage, body, engine, gearbox, fuel, steering side, colour, city, ISO region, private-or-business seller, photo count and a thumbnail.

2 credits0 required · 26 optional
POST/kolesa/v1/search
idle
// 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 Kolesa.kz API works

Kolesa.kz is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.

01
Authenticate
x-api-key header

No OAuth app, no request signing, no per-site account. One key covers all 438 engines.

02
Call
POST /kolesa/v1/…

Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.

03
Pay
2 credit per call

Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.

04
Read
{ ok, data, meta, error }

One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.

Every Toyota Camry in Almaty under 5 million tenge, with the full advert and the seller's status

Two calls: search, then listing.

01search
POST/kolesa/v1/search

Call search with brand toyota and model camry to size the market — 10,454 live ads on 2026-10-02 — and read total_results and reachable_rows from the response.

02listing
POST/kolesa/v1/listing

Add city almaty and price_max 5000000 to cut it to a slice you can walk end to end; Toyota Camry in Almaty was 2,514 ads, well inside the 20,000-row reach, so no listing is out of range.

03listing
POST/kolesa/v1/listing

Set sort to price_asc and page through 20 rows at a time until page_at_ceiling or has_more goes false, keeping each row's listing_id, price, mileage_km, year and market_avg_price — Kolesa's own average for the model, which is how you spot an ad priced under the market.

04listing
POST/kolesa/v1/listing

Filter the rows on seller_kind to separate private owners from dealers, or re-run with dealers_only to see only the trade's 10,060 ads.

05listing
POST/kolesa/v1/listing

Call listing for the ids you want: the complete description, every photo at full size, the whole parameter table and the seller block with the dealer's name, badge, address and how many ads they have live.

Ten credits for the 5 calls: search 2, listing 2, listing 2, listing 2, listing 2. Failed calls are free: a timeout, a block or a capacity error costs nothing.

request
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}'
response envelope
{
  "ok": true,
  "data": { … },
  "meta": {
    "api": "kolesa",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": …,
    "record_count": …
  },
  "error": null
}

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.

What is measured, and what is not there

Every figure on this page was read off the live source in the run recorded for it, not estimated.

Market

Kazakhstan — kolesa.kz, cars section, 161,697 live ads on 2026-10-02

Board breakdown

97,702 passenger cars · 47,431 SUVs and pickups · 14,439 minivans and minibuses · 157,033 used · 4,667 new · 10,060 from dealers

By city

Almaty 42,852 · Astana 20,391 · Shymkent 13,725 (plus every other city slug Kolesa uses)

Niches

9,578 right-hand drive · 5,949 diesel · 1,254 electric · 3,230 damaged or not roadworthy · 157,582 already customs-cleared

Page size

20 rows, fixed — the site has no page-size parameter; measured 20 on pages 1, 2, 3, 7, 50, 300 and 1,000

Paging ceiling

page 1,000 = 20,000 rows per query; the site's own selector says "1 из 1000" and pages 1,001, 1,500 and 4,000 repeat page 1,000. Every response returns reachable_rows and page_at_ceiling

Filters that narrow

22 of 22 exposed filters measured narrowing the same-run 161,697-ad control; an unknown parameter name and an unknown sort value are both swallowed by the site, so unknown values are rejected here instead

Price

tenge (KZT) only, whole units, and it matched the string Kolesa prints on its own page 12 of 12 across 12 cohorts

Market average

Kolesa's own average asking price for the brand and model, passed through unchanged where the site publishes it; null where it does not

Seller kind

private or business on every row, taken from the site's own seller type and cross-checked 40 rows for 40 against its dealer filter

Seller detail

dealers publish name, official-dealer badge, address, years on Kolesa and live ad count. 🔴 A private owner's display name is not published on the ad page at all — null, with name_published false

Photos

every photo at full size on detail; the count matched Kolesa's own photo_count exactly on both sampled adverts (7 of 7 and 34 of 34)

Spec fields

year, condition, body, engine size, fuel, gearbox, steering, mileage and colour parsed from the card's own chips, with the raw chip list kept in spec_line. Not every ad prints every chip — a 2012 Lada Priora published no mileage and no steering side — and what the source omits is null, never 0

Not available

no phone numbers, no private-seller names, no mileage_min (the site publishes no lower bound), no sold-price history, no page-size control, and no brand/model catalogue endpoint — brand and model come back on every row as the site's own slugs

Live checks

34 of 34 passed on two separate runs; 9 of 9 error cases returned the right code; all 12 cohorts returned rows and resolved their first advert to a full detail record

What people build with Kolesa.kz

The jobs this data is most often used for.

2

endpoints

2

credits per call

01

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.

02

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.

03

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.

04

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.

What Kolesa.kz data costs

The cheapest call here is 2 credits, so $15/mo (Pro) buys 5,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.

Full pricing →
$0.67–$1.50 / 1,000 credits
  • 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
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}'
python
import requests

r = requests.post(
    "https://api.reefapi.com/kolesa/v1/search",
    headers={"x-api-key": REEF_KEY},
    json={
  "brand": "toyota",
  "city": "almaty",
  "max_results": 20
},
)
print(r.json()["data"])
FAQ

Have a question? We got answers.

The questions people actually ask before wiring up Kolesa.kz.

Get a free key →
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.

99 Classifieds & Second-hand APIs on the same key

One key, one credit pool, one response envelope. If you are pulling Kolesa.kz, 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.

0/4000

No account needed · we reply from [email protected]

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-02.