# OLX API scraper — search OLX classifieds across 7 countries (Poland, Ukraine, Romania, Portugal, Bulgaria, Kazakhstan, Uzbekistan): listings, offer detail, prices, photos, categories, filters, seller profiles & inventory, related offers, result counts and a GEO location resolver. Bare datacenter, no account, seller PII redacted.

> Search OLX classifieds by keyword and/or category with sort, condition, price, delivery and location filters. Offset pagination (limit=40). Promoted ads filtered out.
> ReefAPI engine `olx` · 10 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/olx/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 or blocked calls are free.
- **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, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /olx/v1/search — 1 credit
Search OLX classifieds by keyword and/or category with sort, condition, price, delivery and location filters. Offset pagination (limit=40). Promoted ads filtered out.

**Parameters:**
- `query` (string, optional) — Free-text keyword search. (search needs query OR category_id.)
- `category_id` (integer, optional) — OLX numeric category id (discover via the categories / breadcrumbs actions). (search needs query OR category_id.)
- `country` (enum, optional, default "pl") — OLX country edition — each TLD is a fully separate marketplace. br/in/tr run on different stacks and are not supported. [one of: pl, ua, bg, ro, pt, kz, uz]
- `sort_by` (enum, optional) — Result ordering. Common keys shown; other OLX sort keys are also accepted. [one of: relevance, created_at:desc, filter_float_price:asc, filter_float_price:desc]
- `condition` (enum, optional) — Item condition filter. [one of: new, used]
- `with_photos` (boolean, optional) — Only return listings that have at least one photo.
- `courier` (boolean, optional) — Only return listings that offer OLX delivery (courier shipping).
- `region_id` (integer, optional) — Location filter: OLX numeric region id (discover via the filters action).
- `city_id` (integer, optional) — Location filter: OLX numeric city id (discover via the filters action).
- `district_id` (integer, optional) — Location filter: OLX numeric district id (discover via the filters action).
- `price_from` (number, optional) — Minimum price filter (in the marketplace's local currency).
- `price_to` (number, optional) — Maximum price filter (in the marketplace's local currency).
- `filters` (object, optional) — Advanced escape hatch: extra raw OLX filter params as a key->value map (e.g. {"filter_enum_state[0]": "used"}); keys come from the filters action. Most users won't need this — use condition / with_photos / courier instead.
- `offset` (integer, optional, default 0) — Pagination offset (skip N results). Page forward with meta.next_offset.
- `limit` (integer, optional, default 40) — Results per page (1-50, default 40). Larger values are clamped to 50.

**Returns:** offers[] (normalized, promoted slots filtered), search_id, total, has_more, next_offset

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

### POST /olx/v1/count — 1 credit
Lightweight result count for a query/category/filter combination — total matching listings without fetching the offers. Useful for market sizing.

**Parameters:**
- `query` (string, optional) — Free-text keyword search. (search needs query OR category_id.)
- `category_id` (integer, optional) — OLX numeric category id (discover via the categories / breadcrumbs actions). (search needs query OR category_id.)
- `country` (enum, optional, default "pl") — OLX country edition — each TLD is a fully separate marketplace. br/in/tr run on different stacks and are not supported. [one of: pl, ua, bg, ro, pt, kz, uz]
- `condition` (enum, optional) — Item condition filter. [one of: new, used]
- `region_id` (integer, optional) — Location filter: OLX numeric region id (discover via the filters action).
- `city_id` (integer, optional) — Location filter: OLX numeric city id (discover via the filters action).
- `district_id` (integer, optional) — Location filter: OLX numeric district id (discover via the filters action).
- `price_from` (number, optional) — Minimum price filter (in the marketplace's local currency).
- `price_to` (number, optional) — Maximum price filter (in the marketplace's local currency).
- `filters` (object, optional) — Advanced escape hatch: extra raw OLX filter params as a key->value map (e.g. {"filter_enum_state[0]": "used"}); keys come from the filters action. Most users won't need this — use condition / with_photos / courier instead.

**Returns:** total_count, visible_total_count (OLX caps deep results at 1000)

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

### POST /olx/v1/locations — 1 credit
GEO resolver: turn a place name into OLX region/city/district ids for the location filters. No params -> all regions; region_id -> its cities; city_id -> city detail + districts; query -> match a city by name across regions.

**Parameters:**
- `country` (enum, optional, default "pl") — OLX country edition — each TLD is a fully separate marketplace. br/in/tr run on different stacks and are not supported. [one of: pl, ua, bg, ro, pt, kz, uz]
- `query` (string, optional) — Place name to look up (city/region). Optional — omit to list all regions for the country.
- `region_id` (integer, optional) — List the cities inside this region id (region ids come from the same locations action with no params).
- `city_id` (integer, optional) — Look up this city's detail + districts (city ids come from a region's city list).

**Returns:** level (regions|cities|city|matches), regions[]/cities[]/districts[]/matches[] with id, name, lat/lon, has_districts

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

### POST /olx/v1/offer — 1 credit
Offer detail by numeric id (no trailing slash on upstream path).

**Parameters:**
- `id` (integer, required) — OLX offer numeric id (the digits in an offer URL / a search result's id).
- `country` (enum, optional, default "pl") — OLX country edition — each TLD is a fully separate marketplace. br/in/tr run on different stacks and are not supported. [one of: pl, ua, bg, ro, pt, kz, uz]

**Returns:** offer{} — full normalized offer (price, condition, photos, location, seller, params)

**Example request body:**
```json
{
  "id": 1027143072,
  "country": "pl"
}
```

### POST /olx/v1/categories — 1 credit
Category facets + filter suggestions from search metadata, plus global filter definitions.

**Parameters:**
- `query` (string, optional) — Free-text keyword search. (search needs query OR category_id.)
- `category_id` (integer, optional) — OLX numeric category id (discover via the categories / breadcrumbs actions). (search needs query OR category_id.)
- `country` (enum, optional, default "pl") — OLX country edition — each TLD is a fully separate marketplace. br/in/tr run on different stacks and are not supported. [one of: pl, ua, bg, ro, pt, kz, uz]

**Returns:** facets, filter_suggestions, filter_definitions, total_count, visible_total_count

**Example request body:**
```json
{
  "country": "pl",
  "category_id": 99
}
```

### POST /olx/v1/user_offers — 1 credit
Active offers for a seller user_id with offset pagination.

**Parameters:**
- `user_id` (integer, required) — OLX seller numeric id (an offer's seller_id / search result user.id).
- `country` (enum, optional, default "pl") — OLX country edition — each TLD is a fully separate marketplace. br/in/tr run on different stacks and are not supported. [one of: pl, ua, bg, ro, pt, kz, uz]
- `offset` (integer, optional, default 0) — Pagination offset (skip N results). Page forward with meta.next_offset.
- `limit` (integer, optional, default 40) — Results per page (1-50, default 40). Larger values are clamped to 50.

**Returns:** offers[] (this seller's active listings), total, has_more, next_offset

### POST /olx/v1/suggested — 1 credit
Related/suggested offers for a given offer id.

**Parameters:**
- `id` (integer, required) — OLX offer numeric id (the digits in an offer URL / a search result's id).
- `country` (enum, optional, default "pl") — OLX country edition — each TLD is a fully separate marketplace. br/in/tr run on different stacks and are not supported. [one of: pl, ua, bg, ro, pt, kz, uz]

**Returns:** offers[] related to the source offer, source_id

**Example request body:**
```json
{
  "id": 1027143072
}
```

### POST /olx/v1/breadcrumbs — 1 credit
Category or offer breadcrumb trail.

**Parameters:**
- `category_id` (integer, optional) — OLX numeric category id (discover via the categories / breadcrumbs actions). (search needs query OR category_id.)
- `id` (integer, optional) — OLX offer numeric id (alternative to category_id for breadcrumbs).
- `country` (enum, optional, default "pl") — OLX country edition — each TLD is a fully separate marketplace. br/in/tr run on different stacks and are not supported. [one of: pl, ua, bg, ro, pt, kz, uz]

**Returns:** breadcrumbs[] — the category/offer hierarchy trail

### POST /olx/v1/user — 1 credit
Public seller profile by user id.

**Parameters:**
- `user_id` (integer, required) — OLX seller numeric id (an offer's seller_id / search result user.id).
- `country` (enum, optional, default "pl") — OLX country edition — each TLD is a fully separate marketplace. br/in/tr run on different stacks and are not supported. [one of: pl, ua, bg, ro, pt, kz, uz]

**Returns:** user{} — public seller profile (PII redacted unless include_pii)

### POST /olx/v1/filters — 1 credit
Global filter attribute definitions keyed by filter_enum/filter_float names.

**Parameters:**
- `country` (enum, optional, default "pl") — OLX country edition — each TLD is a fully separate marketplace. br/in/tr run on different stacks and are not supported. [one of: pl, ua, bg, ro, pt, kz, uz]

**Returns:** filters{} — global filter attribute definitions (enum/float keys)

## More
- Try it live, no code: https://reefapi.com/playground?engine=olx
- Human docs page: https://reefapi.com/docs/olx
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
