# lalafo API — search and read classified ads on lalafo.kg (Kyrgyzstan), lalafo.az (Azerbaijan), lalafo.rs (Serbia) and lalafo.pl (Poland): cars, property, phones and electronics, jobs, services, home goods. Keyword, category, city, seller, price band and the category's own attribute filters (make, year, mileage, gearbox, fuel, rooms ...), four sorts, uncapped counts. Every ad returns its price in the currency the seller chose plus the source's own national-currency conversion, city with coordinates, posting / update / bump times, impression and contact counters, promoted flag, photos and the seller (private or business). Full ad detail adds the attribute table. Logged-out public data.

> Search one lalafo site. Needs `query`, `category_id` or `user_id` (any one); the rest narrow it. Promoted rows are flagged and come first on every page.
> ReefAPI engine `lalafo` · 8 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/lalafo/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/lalafo/v1/search — 3 credits
Search one lalafo site. Needs `query`, `category_id` or `user_id` (any one); the rest narrow it. Promoted rows are flagged and come first on every page.

**Parameters:**
- `country` (enum, optional, default "kg") — Which lalafo site: kg (lalafo.kg, default), az (lalafo.az), rs (lalafo.rs) or pl (lalafo.pl). Ids (listings, sellers, categories, cities) belong to one site. [one of: kg, az, rs, pl]
- `query` (string, optional) — Keywords, matched by the source's own search. Needs `query`, `category_id` or `user_id` (any one is enough).
- `category_id` (integer, optional) — Numeric category id from the `categories` action (e.g. kg 1502 = cars for sale, 1343 = laptops). Checked against the source — an unknown id is rejected (the source would silently return the whole site).
- `city_id` (integer, optional) — Numeric city id from the `cities` action (kg 103184 = Bishkek). Checked against the site's city list.
- `user_id` (integer, optional) — Only this seller's live ads (the `seller.seller_id` of a row).
- `price_min` (number, optional) — Lowest price, read in `currency` when given, otherwise in the site's national currency (KGS/AZN/RSD/PLN) — ads priced in USD/EUR are compared after the source's own conversion.
- `price_max` (number, optional) — Highest price, same currency rule as `price_min`.
- `currency` (enum, optional) — Return every price CONVERTED by the source into this currency (and read price_min/price_max in it). Leave empty to get each ad in the currency its seller chose. kg: KGS, USD · az: AZN, USD · rs: RSD, EUR · pl: PLN. [one of: KGS, USD, AZN, RSD, EUR, PLN]
- `filters` (array, optional) — Attribute filters of the category, from the `filters` action: '<param_id>:<value_id>' for a list attribute (repeat or use '|' for several values, e.g. '64:2780|2779'), '<param_id>:<from>-<to>' for a range attribute with plain VALUES (e.g. year '62:2018-2022', mileage '56:0-100000'). Needs `category_id`; every id is validated against the category's own definitions.
- `sort` (enum, optional, default "default") — Order. Promoted (paid) rows always come first on every page, outside this order. On rs and pl a `query` with the default order is ranked SEMANTICALLY by the source (every ad is a match, `match_mode: semantic`, total not exact); any explicit order gives real keyword matches with an exact total. [one of: default, newest, price_asc, price_desc]
- `page` (integer, optional, default 1) — Page number (1-based). The source serves at most 10 000 ads per query.
- `per_page` (integer, optional, default 20) — Ads per page, 1-50 (default 20). Promoted rows (4-17 per page measured) come on top of this number.
- `language` (enum, optional) — Language of category, city and attribute names (ads themselves stay as the seller wrote them). kg: ru (default), ky · az: az (default), ru · rs: sr (default), en · pl: pl (default), uk, en. [one of: ru, ky, az, sr, en, pl, uk]

**Returns:** country, total_results (the source's figure; stops at 10 000), total_capped, total_is_exact, match_mode (semantic | keyword_or_filter), total_available (the uncapped count, filled only when capped), page, page_count, per_page, returned, promoted_count, page_clamped, has_more, prices_converted_to, query, sort, filters_sent and listings[] with listing_id, country, url, title, description, price, currency (the seller's own: KGS/USD, AZN/USD, RSD/EUR, PLN), price_kind (fixed | negotiable | not_priced), is_negotiable, price_converted, old_price, national_price + national_currency (the source's own conversion, KG), national_old_price, category_id, city, city_id, city_alias, lat, lng, created_at, updated_at, bumped_at, impressions, favorite_count, callers_count, writers_count, promoted, is_premium, label, phone (as the public page publishes it; null when the seller hid it), phone_hidden, chat_disabled, image, image_count, seller{seller_id, name, company_name, is_pro, seller_type (business | private), avatar, response_rate_pct, response_time_s, response_info, is_banned}

**Example request body:**
```json
{
  "country": "kg",
  "category_id": 1502,
  "sort": "newest"
}
```

### POST https://api.reefapi.com/lalafo/v1/listing — 1 credit
Full detail of one ad by `listing_id` (+ `country`) or by its lalafo URL (the country is read off the domain). A removed ad, or an id asked under the wrong country, returns NOT_FOUND.

**Parameters:**
- `listing_id` (integer, optional) — Ad id (`listing_id` of a search row).
- `url` (string, optional) — A lalafo ad URL; its domain sets the country.
- `country` (enum, optional, default "kg") — Which lalafo site: kg (lalafo.kg, default), az (lalafo.az), rs (lalafo.rs) or pl (lalafo.pl). Ids (listings, sellers, categories, cities) belong to one site. [one of: kg, az, rs, pl]
- `language` (enum, optional) — Language of category, city and attribute names (ads themselves stay as the seller wrote them). kg: ru (default), ky · az: az (default), ru · rs: sr (default), en · pl: pl (default), uk, en. [one of: ru, ky, az, sr, en, pl, uk]

**Returns:** the search row shape plus description (full text), images[] (url, thumbnail_url, is_main), attributes[] (param_id, name, value, value_id), email (only when the ad publishes one) and status_id

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

### POST https://api.reefapi.com/lalafo/v1/seller — 1 credit
A seller's public profile by `user_id` (from a row's `seller.seller_id`). Use `search` with `user_id` for their ads.

**Parameters:**
- `user_id` (integer, required) — Seller id.
- `country` (enum, optional, default "kg") — Which lalafo site: kg (lalafo.kg, default), az (lalafo.az), rs (lalafo.rs) or pl (lalafo.pl). Ids (listings, sellers, categories, cities) belong to one site. [one of: kg, az, rs, pl]
- `language` (enum, optional) — Language of category, city and attribute names (ads themselves stay as the seller wrote them). kg: ru (default), ky · az: az (default), ru · rs: sr (default), en · pl: pl (default), uk, en. [one of: ru, ky, az, sr, en, pl, uk]

**Returns:** seller_id, name, about, avatar, member_since, is_pro, seller_type (business | private), has_business_profile, verified, response_rate_pct, response_time_s, response_info, is_banned, is_deleted

**Example request body:**
```json
{
  "user_id": 17287932
}
```

### POST https://api.reefapi.com/lalafo/v1/count — 1 credit
How many live ads match a filter set, without downloading them — the source's UNCAPPED number (cars on lalafo.kg: 54 537, where search stops at 10 000). Same filters as `search`.

**Parameters:**
- `country` (enum, optional, default "kg") — Which lalafo site: kg (lalafo.kg, default), az (lalafo.az), rs (lalafo.rs) or pl (lalafo.pl). Ids (listings, sellers, categories, cities) belong to one site. [one of: kg, az, rs, pl]
- `query` (string, optional) — Keywords, matched by the source's own search. Needs `query`, `category_id` or `user_id` (any one is enough).
- `category_id` (integer, optional) — Numeric category id from the `categories` action (e.g. kg 1502 = cars for sale, 1343 = laptops). Checked against the source — an unknown id is rejected (the source would silently return the whole site).
- `city_id` (integer, optional) — Numeric city id from the `cities` action (kg 103184 = Bishkek). Checked against the site's city list.
- `user_id` (integer, optional) — Only this seller's live ads (the `seller.seller_id` of a row).
- `price_min` (number, optional) — Lowest price, read in `currency` when given, otherwise in the site's national currency (KGS/AZN/RSD/PLN) — ads priced in USD/EUR are compared after the source's own conversion.
- `price_max` (number, optional) — Highest price, same currency rule as `price_min`.
- `currency` (enum, optional) — Return every price CONVERTED by the source into this currency (and read price_min/price_max in it). Leave empty to get each ad in the currency its seller chose. kg: KGS, USD · az: AZN, USD · rs: RSD, EUR · pl: PLN. [one of: KGS, USD, AZN, RSD, EUR, PLN]
- `filters` (array, optional) — Attribute filters of the category, from the `filters` action: '<param_id>:<value_id>' for a list attribute (repeat or use '|' for several values, e.g. '64:2780|2779'), '<param_id>:<from>-<to>' for a range attribute with plain VALUES (e.g. year '62:2018-2022', mileage '56:0-100000'). Needs `category_id`; every id is validated against the category's own definitions.
- `language` (enum, optional) — Language of category, city and attribute names (ads themselves stay as the seller wrote them). kg: ru (default), ky · az: az (default), ru · rs: sr (default), en · pl: pl (default), uk, en. [one of: ru, ky, az, sr, en, pl, uk]

**Returns:** country, count, filters_sent

**Example request body:**
```json
{
  "country": "kg"
}
```

### POST https://api.reefapi.com/lalafo/v1/categories — 3 credits
The site's category tree with live ad counts — the ids `search` takes. Default: the top two levels; `parent_id` returns one branch, `max_depth` goes deeper.

**Parameters:**
- `country` (enum, optional, default "kg") — Which lalafo site: kg (lalafo.kg, default), az (lalafo.az), rs (lalafo.rs) or pl (lalafo.pl). Ids (listings, sellers, categories, cities) belong to one site. [one of: kg, az, rs, pl]
- `parent_id` (integer, optional) — Only this category's subtree.
- `max_depth` (integer, optional, default 2) — Levels below the start (1-6).
- `language` (enum, optional) — Language of category, city and attribute names (ads themselves stay as the seller wrote them). kg: ru (default), ky · az: az (default), ru · rs: sr (default), en · pl: pl (default), uk, en. [one of: ru, ky, az, sr, en, pl, uk]

**Returns:** country, category_count, categories[] with category_id, name, parent_id, depth, path, url_path, ads_count, child_count

**Example request body:**
```json
{
  "country": "kg"
}
```

### POST https://api.reefapi.com/lalafo/v1/cities — 2 credits
Every city/town of one lalafo site with its region — the ids `city_id` takes.

**Parameters:**
- `country` (enum, optional, default "kg") — Which lalafo site: kg (lalafo.kg, default), az (lalafo.az), rs (lalafo.rs) or pl (lalafo.pl). Ids (listings, sellers, categories, cities) belong to one site. [one of: kg, az, rs, pl]
- `language` (enum, optional) — Language of category, city and attribute names (ads themselves stay as the seller wrote them). kg: ru (default), ky · az: az (default), ru · rs: sr (default), en · pl: pl (default), uk, en. [one of: ru, ky, az, sr, en, pl, uk]

**Returns:** country, city_count, cities[] with city_id, name, alias, region_id, region_name, featured

**Example request body:**
```json
{
  "country": "rs"
}
```

### POST https://api.reefapi.com/lalafo/v1/filters — 2 credits
The attribute filters one category offers (make, model, year, mileage, gearbox, rooms, condition ...) with their ids and value ids — what `search` `filters` takes.

**Parameters:**
- `category_id` (integer, required) — Category id.
- `country` (enum, optional, default "kg") — Which lalafo site: kg (lalafo.kg, default), az (lalafo.az), rs (lalafo.rs) or pl (lalafo.pl). Ids (listings, sellers, categories, cities) belong to one site. [one of: kg, az, rs, pl]
- `language` (enum, optional) — Language of category, city and attribute names (ads themselves stay as the seller wrote them). kg: ru (default), ky · az: az (default), ru · rs: sr (default), en · pl: pl (default), uk, en. [one of: ru, ky, az, sr, en, pl, uk]

**Returns:** country, category_id, params[] (param_id, name, alias, kind, is_range, is_multi_select, filter_syntax, values[] {value_id, value, alias}), currencies, source_sorts

**Example request body:**
```json
{
  "category_id": 1502
}
```

### POST https://api.reefapi.com/lalafo/v1/suggest — 1 credit
The site's own search suggestions for a partial query, each pointing at the category it belongs to.

**Parameters:**
- `query` (string, required) — Partial text.
- `country` (enum, optional, default "kg") — Which lalafo site: kg (lalafo.kg, default), az (lalafo.az), rs (lalafo.rs) or pl (lalafo.pl). Ids (listings, sellers, categories, cities) belong to one site. [one of: kg, az, rs, pl]
- `language` (enum, optional) — Language of category, city and attribute names (ads themselves stay as the seller wrote them). kg: ru (default), ky · az: az (default), ru · rs: sr (default), en · pl: pl (default), uk, en. [one of: ru, ky, az, sr, en, pl, uk]

**Returns:** country, query, suggestions[] with text, category_id, category_path, usage_count

**Example request body:**
```json
{
  "query": "iphone"
}
```

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