Serbia's biggest classifieds site, as one JSON API
The KupujemProdajem API returns Serbia's largest general classifieds site as clean JSON, in four actions: search, listing, count and categories.
4 active endpoints, on 1 and 2 credit tiers.
- POST/kupujemprodajem/v1/search
- POST/kupujemprodajem/v1/listing
- POST/kupujemprodajem/v1/count
- POST/kupujemprodajem/v1/categories
What KupujemProdajem endpoints does ReefAPI ship?
4 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
KupujemProdajem API
4 of 4 endpoints, ready to run
Live KupujemProdajem ads with the matching total: ad id, URL, title, price in the seller's own currency, category and sub-group, town, condition, offer or wanted, posted and renewed time, view and favourite counts, seller id and a photo.
// 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 KupujemProdajem API works
KupujemProdajem is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 438 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
Every flat for sale in one Serbian town, with the full ad and the lister's track record
Four calls: categories, then count, then search, then listing.
Call categories and take the id for Nekretnine | Prodaja — 2821 on 2026-10-01, with 49,267 live ads.
Call count with category 2821 to see the live total before you pay for pages, then add a price band in EUR to size the slice you want.
Call search with category 2821, per_page 200 and sort newest, and read location_id and location_name off the rows to pick the town you care about; a category search has no 20,000-row ceiling, so you can walk the whole set.
Re-run search with that location id to get only that town, and keep each row's listing_id.
Call listing for the ids you want: the full description, every photo, the expiry date, and the seller block with member-since, positive and negative review counts and the verification badges — then pass seller_id back to search to see everything else that lister has live.
Five credits for the 5 calls: categories 0, count 0, search 2, search 2, listing 1. Failed calls are free: a timeout, a block or a capacity error costs nothing.
curl -X POST https://api.reefapi.com/kupujemprodajem/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"iphone","max_results":20}'{
"ok": true,
"data": { … },
"meta": {
"api": "kupujemprodajem",
"endpoint": "search",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}What is actually on the site — live ad counts on 2026-10-01
These are counts read off the live index, one call each, not estimates. They move as ads are posted and expire; the count action returns today's number the same way, and every search response carries the matching total in the response body.
| category | category id | live ads | price published? |
|---|---|---|---|
| Bela tehnika i kućni aparati (white goods, home appliances) | 15 | 127,585 | yes, EUR or RSD |
| Sport i razonoda (sport and leisure) | 34 | 76,629 | yes, EUR or RSD |
| Odeća | Ženska (womenswear) | 743 | 64,090 | yes, EUR or RSD |
| Audio | Vinili, CD i kasete (records, CDs, tapes) | 1176 | 53,103 | yes, EUR or RSD |
| Nekretnine | Prodaja (property for sale) | 2821 | 49,267 | yes, usually EUR |
| Nameštaj (furniture) | 1268 | 48,904 | yes, EUR or RSD |
| Obuća | Ženska (women's shoes) | 1077 | 39,959 | yes, EUR or RSD |
| Mobilni telefoni (mobile phones) | 23 | 35,174 | yes, EUR or RSD |
| Bicikli (bicycles) | 912 | 14,337 | yes, EUR or RSD |
| Automobili (cars) | 2919 | 11,129 | yes, usually EUR |
| Časopisi i stripovi (magazines, comics) | 1296 | 11,033 | yes, mostly RSD |
| Nekretnine | Izdavanje (property to rent) | 2850 | 10,289 | yes, monthly rent |
| Transportna vozila (commercial vehicles) | 2329 | 3,116 | yes, EUR or RSD |
| Poslovi (jobs) | 2546 | 505 | no — a job ad has no price |
| Usluge | Auto-moto (one of 22 service categories) | 1410 | 365 | yes, usually RSD |
That is 15 of the 89 live categories; the categories action lists all of them (66 goods, 22 services, 1 jobs) with their ids. Keyword searches are much larger than any single category: audi 309,442 live ads, iphone 84,726, stan (flat) 72,115, bicikl 41,714, ps5 9,754 on the same day. 🔴 A keyword search can only be paged to 20,000 rows: iphone reports 20,000 over 667 pages and page 668 is empty, while count says 84,726 for the same words — so the API returns both figures and flags which one is capped. A category search has no such ceiling: category 743 reported 64,085 rows over 2,137 pages and page 2,137 served its last 7 rows.
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.
89 live (66 goods, 22 services, 1 jobs), each with its id and filter-capability flags
white goods 127,585 · sport and leisure 76,629 · womenswear 64,090 · records and CDs 53,103 · property for sale 49,267 · furniture 48,904 · phones 35,174 · cars 11,129 · property to rent 10,289
audi 309,442 · iphone 84,726 · stan 72,115 · bicikl 41,714 · ps5 9,754 live ads on 2026-10-01
30 by default, 1 to 500 honoured exactly (59 KB to 956 KB of response)
20,000 rows on a keyword search (667 pages, page 668 empty); no ceiling on a category search (64,085 rows over 2,137 pages, all reachable)
13 of 13 exposed filters measured narrowing the same-run control; the 2 the site accepts and ignores are not exposed
227 of 300 sampled rows carry one, in the seller's own EUR or RSD, and it matched the site's own printed string 15 of 15
73 of 300 — job posts, wanted ads and price-on-request. Returned as null with the reason, never as 0
180 of 300 rows — property, jobs and services have no condition field; the categories action flags which do
296 of 300 rows have one; details carried 1 to 15 photos each
present on 10 of 10 details: name, person or company, town, member since, positive and negative reviews, phone and bank verification, company tax and registry id
filled on 4 of 10 sampled details (vehicles and property); empty on most goods ads, and returned as empty
no phone numbers, no public town catalogue, no public sub-group catalogue, no sold-price history — ids for town and sub-group come back on the rows instead
22 of 22 passed on two separate runs; 7 of 7 error cases returned the right code; 15 of 15 ids from search resolved to the same record
What people build with KupujemProdajem
The jobs this data is most often used for.
endpoints
credits per call
Track Serbian residential property supply and asking prices: 49,267 flats and houses for sale and 10,289 to rent on 2026-10-01, filterable by town and price band, each with the full description, every photo and the lister's review history.
Price used stock for a Balkan e-commerce or repair business: pull the same model across 35,174 phone ads or 127,585 appliance ads, keep each seller's own currency, and use has_price and condition to compare like with like.
Find demand instead of supply: 2,487 of a 4,595-ad control were people asking to buy. Filter listing_type=buy by category and town to see what the market is short of before you stock it.
Monitor a competitor or a shop account: pass their seller_id to search for every ad they have live, and read their public review counts and verification badges from any one of their ads.
What KupujemProdajem data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,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 →- 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 -X POST https://api.reefapi.com/kupujemprodajem/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"iphone","max_results":20}'import requests
r = requests.post(
"https://api.reefapi.com/kupujemprodajem/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"query": "iphone",
"max_results": 20
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up KupujemProdajem.
Get a free key →Which currency are the prices in?▾
The one the seller chose, per ad — KupujemProdajem lets a seller quote in EUR or in RSD, and both appear in the same result set. We measured furniture rows coming back as 7,899 RSD and 150 EUR side by side. So every row carries price together with price_currency, and the listing action also returns price_display, which is the exact string KupujemProdajem prints on the ad page ("8.500 €", "2.500 din"), so you can check our number against the source's own rendering. On 15 ads sampled across ten categories the two agreed 15 of 15, with zero mismatches. We do not convert anything: a converted price is our arithmetic, not the seller's offer.
Why is price null on some ads?▾
Because those ads have no price, and a zero would be a lie. Across 300 sampled rows in ten categories, 227 carried a price and 73 did not: job posts, wanted ads where the poster is buying rather than selling, and ads where the seller asks you to enquire. KupujemProdajem writes a 0 into those, so the API returns null and puts the reason in price_kind — not_priced_job, not_priced_wanted or not_priced — alongside the site's own label ("Posao" for a job, "Kupujem" for a wanted ad). If you only want ads with a real number, set has_price: it narrowed a 4,595-ad control to 1,989.
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, and only the ones that moved the total are offered. Against a control of 4,595 ads (keywords telefon, category 23): location=1 (Belgrade) 2,842, a 100-200 EUR band 137, condition=new 481, condition=as-new 1,909, condition=used 1,956, condition=damaged 47, listing_type=sell 2,108, listing_type=buy 2,487, has_price 1,989, has_photo 4,565, exchange_only 128, immediate_available 1,249, group=489 (Apple iPhone) 721. Thirteen for thirteen. Two filters the site accepts but does not usefully apply are deliberately not exposed, because a handle that does nothing is worse than no handle. And an unknown condition or sort value is rejected with INVALID_PARAM rather than passed through, because the site would answer a typo with a convincing empty page.
How many ads can I actually page through?▾
All of them in a category search, and 20,000 in a keyword search. Measured both ways: category 743 reported 64,085 matching ads over 2,137 pages and page 2,137 really did serve the last 7 rows, with the site's own counter agreeing to the row. The keyword search keywords=iphone reported 20,000 over 667 pages, page 667 returned 19 rows and page 668 returned none — exactly 20,000 — while count for the same words said 84,726. So search returns total_results, total_capped and total_available, and you can see at a glance whether you are looking at the whole set. If you need past 20,000 on a keyword, add a category, a town or a price band and the ceiling stops mattering.
How many rows per page, and is it fixed?▾
Thirty by default, and it is a real parameter, not a fixed page size: we measured 30, 60, 100, 120, 200 and 500 rows per page all honoured exactly, at roughly 59 KB, 118 KB, 193 KB, 231 KB, 384 KB and 956 KB of response. One search credit covers whichever you pick, so a bulk pull is cheaper at 200 or 500 and a UI feed is leaner at 30.
What do I get about the seller?▾
What the ad page itself shows, unmodified: the display name, whether the account is a person or a company, their town, the date they joined, their positive and negative review counts, whether their phone and their bank account are verified, their stated reply habit, their profile note, and — for company accounts — the Serbian tax (PIB) and registry (MBR) ids. On one sampled seller that was 1,326 reviews, 1,326 positive, 0 negative, a member since 2017-06-03, phone and bank account both verified. The seller block was present on 10 of 10 details we sampled. You can also pull every ad one seller has: pass their seller_id to search.
Do I get the seller's phone number?▾
No. KupujemProdajem keeps the phone behind a separate click on its own site, and this API never asks for it and never returns it. What you do get is the site's own has_phone flag, so you know whether a phone exists on the ad without us going after it.
What does listing add over a search row?▾
The full description instead of the snippet — 221 to 3,635 characters on the ads we sampled, with the site's bold tags and HTML entities already cleaned out — plus every photo at full size and as a 300x300 thumbnail (1 to 15 per ad in our sample), the ad status and its expiry date, courier-delivery and local-pickup availability, the paid-placement type, and the category-specific fields where they exist: ISBN for books, OEM code for parts, VIN, mileage and registration status for vehicles. Everything in the search row is in there too, and an ad id taken from search resolved to the same record 15 of 15 times.
Why is condition empty on some ads?▾
Because the site only offers a condition where it makes sense. Property, jobs and services have no condition field at all, so it came back on 180 of 300 sampled rows and we return null rather than inventing "used". You do not have to guess which categories have it: the categories action returns a shows_condition flag (and a shows_exchange flag) per category, so you can tell before you filter.
Are category-specific attributes included?▾
Where the site publishes them, and we are honest about how often that is: the attributes array was filled on 4 of the 10 details we sampled — vehicles and property — and empty on most goods ads, where the detail lives in the free-text description instead. We return the empty array as an empty array. Mileage, VIN and registration status for vehicles come back as their own named fields regardless.
Can I search for people who are BUYING, not selling?▾
Yes, and on this site that is a real market rather than a rounding error: in a 4,595-ad control, 2,487 were wanted ads and 2,108 were offers. Set listing_type to buy to get only the wanted ads, sell for only the offers, or leave it off for both. Wanted ads carry no price by definition, and the API labels them not_priced_wanted instead of showing a zero.
What happens if I ask for an ad that has been removed?▾
You get NOT_FOUND with a message saying the ad is removed or never existed, never a blank success you have to interpret. A search that genuinely matches nothing is a different thing and is treated as one: ok with zero rows and total_results 0, because an empty answer is still an answer. We measured both — a dead id and a nonsense keyword — on two separate runs.
How do I find the right category or town id?▾
The categories action returns all 89 category ids with their names and kinds, so category needs no guessing. Town and sub-group are different, and we say so rather than implying a catalogue exists: KupujemProdajem publishes no public list of either, so location_id and group_id come back on every search row next to their names, and you take the id from there. Both filters are measured working — Belgrade narrowed a 4,595-ad control to 2,842, and the Apple iPhone sub-group to 721.
What is the KupujemProdajem API?▾
KupujemProdajem API is a ReefAPI endpoint group for serbia's biggest classifieds site as json: cars, flats for sale and to rent, phones, furniture, clothing, services and jobs, with the seller's own currency, review history and verification badges. It returns live JSON through POST requests under /kupujemprodajem/v1.
99 Classifieds & Second-hand APIs on the same key
One key, one credit pool, one response envelope. If you are pulling KupujemProdajem, 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.
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-01.