Njuškalo + Bolha API & Scraper
Njuškalo (njuskalo.hr) is Croatia's largest classifieds site and Bolha (bolha.com) is its Slovenian sister site on the same platform: cars, flats and houses, phones, bikes, furniture, spare parts and jobs, from private people and businesses.
🤖 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.
This API reads both, chosen with site=hr or site=si. `search` takes words with the site's filters (category, price range, condition, photos only, title only, buyer-protected payment only) and five sort orders. `browse` lists one category page, such as cars, cars of one make, or flats for sale in Zagreb, with price range, private or business seller, condition and any filter that category has on the site itself: year, mileage, fuel, body type, living area, rooms. Each row carries the listing id, title, link, photo, price in euros as a number and as printed, location, condition, the card's key facts (year and mileage, m², memory), date, a promoted flag and the seller's id, name and private-or-business type. `categories` walks the category tree with live listing counts. `listing` returns one listing in full: every detail field, equipment lists, the description, all photos, map coordinates, view count, expiry date and the seller's profile, region, website and rating.
What a Njuškalo / Bolha field actually contains
Fields that read differently from how they look. Every row was measured against live njuskalo.hr and bolha.com pages on 2026-10-14.
| Field | What it holds |
|---|---|
| listing_id | The number after -oglas- in the listing's web address. Pass it unchanged to listing (a listing URL works too). Search to listing returned the same id, price and seller on 22 of 22 rows across both sites. |
| price, price_text | price is the asking price in euros as a number; price_text is the site's own string ("14.400 €", "350.444,50 €": the dot groups thousands, the comma marks cents). On 16 of 16 listing pages price matched the price printed on the page. |
| price_on_request | true when the seller asks to be contacted for the price; price is then null rather than 0. A listing priced "0 €" also gets price null, with the string kept in price_text. |
| is_promoted | Paid promoted listings (up to 6) shown above the regular results on page 1. The site picks a different set of promoted listings on each request, so they are flagged and counted separately; the 25 regular rows are stable. |
| seller.seller_type | private or business on search rows, as the site labels the seller; listing adds store for registered shops, agencies and developers. |
| attributes | The key facts the site prints on the card for that category: year, mileage, fuel and power for cars, m² and year built for flats, memory and condition for phones. |
| total, last_reachable_page | total is the site's own count of matching listings. The site serves at most 400 pages of 25 (10,000 rows) per query even when it reports more pages; last_reachable_page says where the results stop. |
| available_filters | On browse: the category's own filters with their parameter names and choices, as the site defines them. Pass any of them in filters; a name the category does not have is refused rather than silently ignored. |
Prices and listings were identical when read from Croatia, Germany and the United States on 2026-10-14 (same listing, same regular rows). Category pages beyond their last page are reported as empty with page_clamped: true; the site itself would send you back to page 1.
Real request and response JSON
Captured from the indexed primary action, search, on .
{
"method": "POST",
"url": "https://api.reefapi.com/njuskalo/v1/search",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"query": "iphone",
"site": "hr"
}
}{
"ok": true,
"meta": {
"api": "njuskalo",
"endpoint": "search",
"mode": "live",
"latency_ms": 1430.9,
"record_count": 31,
"bytes": 191829,
"cache_hit": false,
"total": 15411,
"pages": 617,
"last_reachable_page": 400,
"promoted_rows": 6,
"pagination": {
"page": 1,
"has_more": true
},
"upstream_requests": 1,
"charged_credits": 2,
"version": "0.1.0",
"request_id": "e544027bddb141fa",
"queue_ms": 1.2,
"fetched_at": "2026-10-14T18:57:29.611Z"
},
"data": {
"query": {
"site": "hr",
"query": "iphone",
"sort": "relevance",
"page": 1
},
"total": 15411,
"pages": 617,
"last_reachable_page": 400,
"page": 1,
"has_more": true,
"promoted_count": 6,
"adapted_category_id": null,
"results": [
{
"listing_id": 49128015,
"title": "Iphone 17 Pro Max 256GB COSMIC ORANGE Novi Zapakirani sa Računom",
"url": "https://www.njuskalo.hr/iphone-17-pro-max/iphone-17-pro-max-256b-cosmic-orange-zapakirani-racunom-oglas-49128015",
"category_slug": "iphone-17-pro-max",
"image": "https://www.njuskalo.hr/image-360x360c/iphone-17-pro-max/iphone-17-pro-max-256b-cosmic-orange-zapakirani-racunom-slika-265795048.jpg",
"price": 1159,
"price_text": "1.159 €",
"price_min": null,
"price_max": null,
"price_on_request": false,
"price_hidden": false,
"currency": "EUR",
"location": "Špansko - Stenjevec",
"condition": null,
"attributes": [
{
"id": "[trimmed-depth]",
"label": "[trimmed-depth]",
"value": "[trimmed-depth]"
},
{
"id": "[trimmed-depth]",
"label": "[trimmed-depth]",
"value": "[trimmed-depth]"
}
],
"summary_lines": [
{
"caption": "[trimmed-depth]",
"text": "[trimmed-depth]",
"highlight": "[trimmed-depth]"
}
],
"created_at": "2026-10-14T13:46:34.000Z",
"is_promoted": true,
"payprotect": true,
"is_new_car": false,
"has_car_warranty": false,
"has_video": false,
"has_virtual_tour": false,
"has_ground_plan": false,
"is_luxury_real_estate": false,
"financing_text": null,
"seller": {
"seller_id": "2730310",
"name": "bord3",
"seller_type": "private",
"rating": 0,
"review_count": 0,
"logo": null
}
},
{
"listing_id": 51829841,
"title": "Iphone 17 Pro Max 256Gb",
"url": "https://www.njuskalo.hr/iphone-17-pro-max/iphone-17-pro-max-256gb-oglas-51829841",
"category_slug": "iphone-17-pro-max",
"image": "https://www.njuskalo.hr/image-360x360c/iphone-17-pro-max/iphone-17-pro-max-256gb-slika-288356812.jpg",
"price": 1240,
"price_text": "1.240 €",
"price_min": null,
"price_max": null,
"price_on_request": false,
"price_hidden": false,
"currency": "EUR",
"location": "Točak - Požega",
"condition": null,
"attributes": [
{
"id": "[trimmed-depth]",
"label": "[trimmed-depth]",
"value": "[trimmed-depth]"
},
{
"id": "[trimmed-depth]",
"label": "[trimmed-depth]",
"value": "[trimmed-depth]"
}
],
"summary_lines": [
{
"caption": "[trimmed-depth]",
"text": "[trimmed-depth]",
"highlight": "[trimmed-depth]"
}
],
"created_at": "2026-10-14T10:01:10.000Z",
"is_promoted": true,
"payprotect": false,
"is_new_car": false,
"has_car_warranty": false,
"has_video": false,
"has_virtual_tour": false,
"has_ground_plan": false,
"is_luxury_real_estate": false,
"financing_text": null,
"seller": {
"seller_id": "1480728",
"name": "Zalagaonica Požega",
"seller_type": "business",
"rating": 0,
"review_count": 0,
"logo": "https://www.njuskalo.hr/logo-140x140/ZalagaonicaPZ-logo-1480728.jpg?quality=100"
}
},
{
"listing_id": 51840583,
"title": "iPhone 17 Pro 256GB Orange/Silver/Blue + oprema [NOVO RAČUN JAM 2 god]",
"url": "https://www.njuskalo.hr/iphone-17-pro/iphone-17-pro-256gb-orange-silver-blue-oprema-racun-jam-2-god-oglas-51840583",
"category_slug": "iphone-17-pro",
"image": "https://www.njuskalo.hr/image-360x360c/iphone-17-pro/iphone-17-pro-256gb-orange-silver-blue-oprema-racun-jam-2-god-slika-288521490.jpg",
"price": 1129,
"price_text": "1.129 €",
"price_min": null,
"price_max": null,
"price_on_request": false,
"price_hidden": false,
"currency": "EUR",
"location": "Kajzerica - Novi Zagreb - Zapad",
"condition": null,
"attributes": [
{
"id": "[trimmed-depth]",
"label": "[trimmed-depth]",
"value": "[trimmed-depth]"
},
{
"id": "[trimmed-depth]",
"label": "[trimmed-depth]",
"value": "[trimmed-depth]"
}
],
"summary_lines": [
{
"caption": "[trimmed-depth]",
"text": "[trimmed-depth]",
"highlight": "[trimmed-depth]"
}
],
"created_at": "2026-10-14T12:42:49.000Z",
"is_promoted": true,
"payprotect": true,
"is_new_car": false,
"has_car_warranty": false,
"has_video": false,
"has_virtual_tour": false,
"has_ground_plan": false,
"is_luxury_real_estate": false,
"financing_text": null,
"seller": {
"seller_id": "2727337",
"name": "BoroviBorovi",
"seller_type": "private",
"rating": 0,
"review_count": 0,
"logo": null
}
}
]
}
}What the Njuškalo + Bolha API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| search | Keyword search across all of njuskalo.hr (site=hr) or bolha.com (site=si), with the source's own filters: category id, price range, condition, photos only, title-only matching, PayProtect (online payment) only, and 5 sort orders. Each row: listing id, title, URL, image, price (parsed + as printed), location, condition, the card's attributes (year, mileage, m², memory …), dates, promoted flag and the seller (id, name, private/business, rating). Plus the source's total, page count and the last page it actually serves. | Pricing teams call search to get keyword search across all of njuskalo.hr (site=hr) or bolha.com (site=si), with the source's…. | query, site, category_id, min_price, max_price, ... |
| browse | List one category page (e.g. `auti`, `auti/audi`, `prodaja-stanova/zagreb`, `mobiteli`) with the price range, seller type (private / business), condition, photos-only and sort — plus any of the category's OWN filters (car year, mileage, fuel, m², rooms …) through `filters`, using the parameter names the response lists in `available_filters`. Rows have the same shape as search. Also returns the category's sub-categories with counts. | Marketplace operators call browse to list one category page (e.g. | category, site, min_price, max_price, seller_type, ... |
| categories | The category tree, one level at a time: without `category` the site's top-level sections and their main categories; with a category path its child categories (brands, models, regions, sub-types) with the live listing count of each. Feed a `slug` to `browse`, a `category_id` to `search`. | Catalog enrichment teams call categories to get the category tree, one level at a time. | site, category |
| listing | Full listing by listing_id or URL: title, price (parsed + printed, range for new-build projects, on-request flag), state, created / expiry dates, view count, category path, location + map coordinates (approximate flag), every detail field the listing shows (car: make, model, year, mileage, power, VIN, owners …; real estate: m², rooms, floor, energy class …), equipment groups, full description, all photos, PayProtect fees, and the seller (id, username, display name, private / business / store, profile URL, region / town, website, phone-verified flag, rating). | Retail analysts call listing to get full listing by listing_id or URL. | listing_id, url, site |
Call search from your stack
curl -X POST https://api.reefapi.com/njuskalo/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"iphone","site":"hr"}'import requests
r = requests.post(
"https://api.reefapi.com/njuskalo/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"query": "iphone",
"site": "hr"
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/njuskalo/v1/search", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"query": "iphone",
"site": "hr"
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.njuskalo.search with {"query":"iphone","site":"hr"}.Who uses this API and why
- Track used-car asking prices in Croatia and Slovenia by make, year and mileage, separating private sellers from dealers.
- Monitor flats and houses for sale or rent by city with price, living area and year built.
- Collect new listings for a keyword every day, newest first, and read each one in full.
- Watch second-hand electronics prices across both markets with condition and seller type.
- Build a lead list of dealers, agencies and shops from the business sellers behind the listings.
Questions developers ask before integrating
Do I need a Njuškalo or Bolha account?
No. Everything is read logged out, and you call reefapi.com from anywhere.
Does it cover Slovenia as well as Croatia?
Yes. site=hr reads njuskalo.hr and site=si reads bolha.com; the two sites share one platform, so the fields are the same. Bolha's car category has no private-or-business filter, and the API says so instead of returning the unfiltered list.
Can I filter cars by year, mileage and fuel?
Yes, with browse on a car category and the site's own filter names. On 2026-10-14 the auti category had 53,787 listings: 2018 to 2020 left 11,087, up to 50,000 km 9,935, diesel 32,513, private sellers 17,744 and business sellers 36,043.
Can I separate private sellers from dealers and agencies?
On category pages, yes: seller_type private or business, and the two add up to the category total. Every row also carries the seller's type, so you can split a keyword search yourself.
How deep can I page?
Up to page 400 of a search or category, which is 10,000 rows; the site stops there even when it reports more. Narrow by category, price or filters to reach the rest.
Do you return the seller's phone number?
Only where the seller wrote it into the description. The site shows phone numbers to logged-in users, and this API reads the logged-out site.
What happens with a sold or expired listing?
listing returns NOT_FOUND. Expired listings stay online as a stub without price, and the API reports them as no longer active.
Which categories exist?
Call categories without a category for the top level, then with a path such as auti, prodaja-stanova or avto-moto for its children, each with its live listing count. Use the slug in browse and the category_id in search.
What is the Njuškalo + Bolha API?
Njuškalo + Bolha API is a ReefAPI endpoint group for croatia's and slovenia's biggest classifieds: cars, flats, phones and everything second-hand, with price, details and seller. It returns live JSON through POST requests under /njuskalo/v1.
Is the Njuškalo + Bolha API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. Njuškalo + Bolha calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Njuškalo + Bolha login or account?
No login to Njuškalo + Bolha is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Njuškalo + Bolha data?
The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Njuškalo + Bolha API use?
Njuškalo + Bolha actions currently cost 2-3 credits per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.
Can I call Njuškalo + Bolha from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call njuskalo actions with the same key, credit pool and JSON envelope used by normal REST requests.