To get OLX listing data, use Scavio's OLX API. POST /api/v1/olx/search takes a keyword or a category and returns 40 ads a page with price, condition, every parameter, city and district, posted and refreshed times, and the promoted ads OLX inserts, flagged with their slot; sort: "newest" lists the most recently posted or refreshed ads first. /offer returns one ad in full, /seller and /seller-ads a seller and its ads, and /filters, /locations and /categories give the ids that search takes. Every call costs 1 credit, $1.00 per 1,000 requests on the Growth plan, on all seven OLX Europe sites.
OLX's own Partner API only manages the ads of the account that authorizes it; its FAQ says reading other people's ads "is not possible". The calls below return the public listings instead. This guide covers OLX Europe, the platform behind olx.pl, olx.ro, olx.pt, olx.bg, olx.ua, olx.kz and olx.uz; OLX Brasil, OLX India, olx.ba and the Dubizzle-run OLX sites are different platforms. The responses are trimmed captures from November 12, 2026. Titles and parameter names come back in the site's language, as OLX writes them; field names are English, prices are numbers and dates are ISO 8601 in UTC.
Step 1: Search, newest first
curl -s https://api.scavio.dev/api/v1/olx/search \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "iphone", "sort": "newest"}'The envelope, then one organic item:
{
"query": "iphone",
"category_id": null,
"sort": "newest",
"applied_filters": {},
"total": 158856,
"total_capped": true,
"page": 1,
"page_size": 40,
"total_pages": 25,
"has_next_page": true,
"count": 52,
"promoted_count": 12,
"country": "pl",
"language": "pl",
"currency": "PLN",
"items": [
{
"id": 1111745594,
"url": "https://www.olx.pl/d/oferta/iphone-13-128gb-rozowy-CID99-ID1deLOy.html",
"title": "IPhone 13, 128Gb, różowy",
"description_snippet": "Witam, mam do sprzedania telefon iPhone 13, 128gb, różowy, stan tel bardzo dobry, stan bateri 90%, ł...",
"price": {
"value": 950,
"currency": "PLN",
"negotiable": true,
"type": "price",
"label": "950 zł",
"previous_value": null,
"original_value": null,
"original_currency": null
},
"salary": null,
"condition": "used",
"params": [
{"key": "state", "name": "Stan", "value": "Używane", "normalized_value": "used"},
{"key": "phonemodel", "name": "Model telefonu", "value": "iPhone 13", "normalized_value": "iphone-13"},
{"key": "builtinmemory_phones", "name": "Wbudowana pamięć", "value": "128GB", "normalized_value": "128gb"},
{"key": "coloriphone", "name": "Kolor", "value": "Różowy", "normalized_value": "pink"}
],
"category_id": 2298,
"category_type": "electronics",
"location": {
"city": "Borkowice",
"city_id": 60761,
"district": null,
"district_id": null,
"region": "Opolskie",
"region_id": 12
},
"created_at": "2026-11-12T17:56:21.000Z",
"refreshed_at": "2026-11-12T17:59:56.000Z",
"valid_to": "2026-12-12T17:56:22.000Z",
"status": "active",
"is_promoted": false,
"promoted_position": null,
"is_highlighted": false,
"is_business": false,
"olx_delivery": false,
"photos": ["https://ireland.apollo.olxcdn.com/v1/files/99qopxyf1xkg1-PL/image;s=750x1000"],
"seller": {"id": 291020289, "business_name": null}
}
]
}sort takes relevance (the default), newest, price_low_to_high or price_high_to_low. newest follows OLX's own order by last refresh, so an ad posted weeks ago that its seller refreshes today comes back near the top; created_at tells you when it was first posted. price.type is price, free, exchange or budget, and previous_value is filled when a seller lowered the price. params carries every attribute the seller filled in, with normalized_value for matching across languages. Search filters: min_price and max_price in the site's currency, condition (new, used, refurbished or damaged), seller_type (private or business), olx_delivery: true, with_photos: true and category_id.
A query is matched loosely, and one with no exact match returns the closest ads, never an empty list. Page 1 of "iphone" on olx.pl mixed phones with screen protectors, chargers and a smartwatch, so filter by category_id (2298 is iPhones on olx.pl) or on params when you need one product.
Step 2: Find location ids
curl -s https://api.scavio.dev/api/v1/olx/locations \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "Warszawa"}'{
"query": "Warszawa",
"count": 20,
"locations": [
{
"type": "city",
"city": "Warszawa",
"city_id": 17871,
"district": null,
"district_id": null,
"municipality": "Warszawa",
"county": "Warszawa",
"region": "Mazowieckie",
"region_id": 2
},
{
"type": "district",
"city": "Warszawa",
"city_id": 17871,
"district": "Białołęka",
"district_id": 365,
"municipality": "Warszawa",
"county": "Warszawa",
"region": "Mazowieckie",
"region_id": 2
}
],
"country": "pl",
"language": "pl",
"currency": "PLN"
}Pass region_id, city_id or district_id to search. With city_id you can add distance_km (0, 2, 5, 10, 15, 30, 50, 75 or 100) to include ads around the city. The same query found a second Warszawa, a village in Wielkopolskie with city_id 76109, so check the region before you store an id. query needs at least 2 letters.
Step 3: Read a category's own filters
Cars, flats and jobs have filters of their own: rooms, area, year, mileage and so on. The filters endpoint lists them with the exact keys search takes:
curl -s https://api.scavio.dev/api/v1/olx/filters \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"category_id": 14}'Category 14 is flats for sale on olx.pl. Two of its nine filters, trimmed:
{
"category_id": 14,
"query": null,
"region_id": null,
"total": 41437,
"filters": [
{
"key": "filter_float_m",
"label": "Powierzchnia",
"type": "input",
"kind": "range",
"unit": "m²",
"send_as": ["filter_float_m:from", "filter_float_m:to"],
"steps": [25, 40, 50, 60, 70, 80, 100, 120, 150],
"values": []
},
{
"key": "filter_enum_rooms",
"label": "Liczba pokoi",
"type": "select",
"kind": "choice",
"unit": null,
"send_as": ["filter_enum_rooms"],
"steps": [],
"values": [
{"value": "one", "label": "1 pokój", "count": 4004},
{"value": "two", "label": "2 pokoje", "count": 16622},
{"value": "three", "label": "3 pokoje", "count": 15102},
{"value": "four", "label": "4 i więcej", "count": 5709}
]
}
],
"locations": {
"type": "region",
"items": [{"id": 2, "name": "Mazowieckie", "count": 6874}, {"id": 6, "name": "Śląskie", "count": 5806}]
},
"categories": [
{"id": 3, "name": "Nieruchomości", "count": 41437},
{"id": 14, "name": "Sprzedaż", "count": 41437},
{"id": 1307, "name": "Mieszkania", "count": 41437}
],
"country": "pl",
"language": "pl",
"currency": "PLN"
}A range filter is sent as <key>:from and <key>:to with a number; a choice filter as the key with one value or a list. values carries the ad count for each choice, and locations counts the category's ads per region (or per city when you pass region_id). The filters endpoint works on olx.pl, olx.ro, olx.pt, olx.bg and olx.ua; olx.kz and olx.uz do not publish filter definitions.
Step 4: Search with category filters and a city
curl -s https://api.scavio.dev/api/v1/olx/search \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"category_id": 14, "city_id": 17871, "sort": "newest", "filters": {"filter_float_m:from": 40, "filter_enum_rooms": ["two"]}}'{
"query": null,
"category_id": 14,
"sort": "newest",
"applied_filters": {"city_id": 17871, "filters": {"filter_float_m:from": 40, "filter_enum_rooms": ["two"]}},
"total": 1054,
"total_capped": true,
"page": 1,
"page_size": 40,
"total_pages": 25,
"has_next_page": true,
"count": 50,
"promoted_count": 12,
"country": "pl",
"language": "pl",
"currency": "PLN",
"items": [
{
"id": 1100595254,
"url": "https://www.olx.pl/d/oferta/dwa-pokoje-po-remoncie-powisle-ul-tamka-CID3-ID1ctZ6m.html",
"title": "Dwa pokoje po remoncie Powiśle ul. Tamka",
"description_snippet": "Na sprzedaż dwupokojowe mieszkanie o powierzchni 42,3 m², położone na pierwszym piętrze bu...",
"price": {
"value": 899000,
"currency": "PLN",
"negotiable": false,
"type": "price",
"label": "899 000 zł",
"previous_value": null,
"original_value": null,
"original_currency": null
},
"salary": null,
"condition": null,
"params": [
{"key": "price_per_m", "name": "Cena za m²", "value": "21252.96 zł/m²", "normalized_value": "21252.96"},
{"key": "floor_select", "name": "Poziom", "value": "1", "normalized_value": "floor_1"},
{"key": "furniture", "name": "Umeblowane", "value": "Nie", "normalized_value": "no"},
{"key": "market", "name": "Rynek", "value": "Wtórny", "normalized_value": "secondary"},
{"key": "builttype", "name": "Rodzaj zabudowy", "value": "Blok", "normalized_value": "blok"},
{"key": "m", "name": "Powierzchnia", "value": "42,30 m²", "normalized_value": "42.3"},
{"key": "rooms", "name": "Liczba pokoi", "value": "2 pokoje", "normalized_value": "two"}
],
"category_id": 14,
"category_type": "real_estate",
"location": {
"city": "Warszawa",
"city_id": 17871,
"district": "Śródmieście",
"district_id": 351,
"region": "Mazowieckie",
"region_id": 2
},
"created_at": "2026-09-25T07:35:32.000Z",
"refreshed_at": "2026-11-12T18:13:16.000Z",
"valid_to": "2026-12-12T18:13:10.000Z",
"status": "active",
"is_promoted": false,
"promoted_position": null,
"is_highlighted": false,
"is_business": true,
"olx_delivery": false,
"photos": ["https://ireland.apollo.olxcdn.com/v1/files/xcuozqxduved1-PL/image;s=1200x900"],
"seller": {"id": 21117567, "business_name": null}
}
]
}All 50 items on the page, promoted ones included, were two-room flats of at least 40 m² in Warsaw. The 38 organic ads had a median asking price of 16,442.55 zł per m², read from the price_per_m parameter. This ad was first posted on September 25 and refreshed minutes before the call, which is why it sits at the top of a newest-first search. Up to 20 filter keys are accepted per call; other keys are refused with a 400.
Paging and the 1,000-result cap
page_size is 40 by default and up to 50. OLX lets anyone page through the first 1,000 results of a search only, so page x page_size cannot pass 1,000: at 40 a page that is 25 pages. total_capped: true means more ads match than you can page through. The "iphone" search matched 158,856 ads on olx.pl, so slice large searches by category_id, region or city, or price band until each slice is under 1,000. Page 2 of the same relevance search shared none of its 40 organic ads with page 1. Some pages carry slightly fewer than 40 organic ads (38 on the Warsaw flats page) because OLX fills the page around its promoted slots.
Promoted ads
OLX inserts paid promoted ads into result pages. Every first page we fetched on November 12, on all seven sites, carried 12 of them, in slots 1-3, 14-16, 27-29 and 40-42. Each comes with is_promoted: true and promoted_position, and promoted_count counts them. They are not sorted: on a newest-first search the first slot on olx.pl was a shop's 10,499 zł iPhone 18 Pro listing, not a new ad. Send "include_promoted": false to drop them, or keep them to measure who pays for visibility in a category. is_highlighted marks ads with a paid highlight.
Step 5: Read one ad
curl -s https://api.scavio.dev/api/v1/olx/offer \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"offer_id": "1107557408"}'Pass offer_id (an items[].id from search) or url, the ad link on any of the seven sites. Trimmed:
{
"id": 1107557408,
"url": "https://www.olx.pl/d/oferta/iphone-13-pro-128gb-graphite-pudelko-etui-szybki-ochronne-100-sprawny-CID99-ID1cXcha.html",
"title": "iPhone 13 Pro 128GB Graphite | Pudełko + Etui + Szybki ochronne | 100% Sprawny",
"description": "TYLKO ODBIÓR OSOBISTY\n\nCześć!\n\nMam na sprzedaż flagowy smartphone iPhone 13 Pro w wersji 128 GB i klasycznym, eleganckim kolorze Graphite (G...",
"price": {
"value": 950,
"currency": "PLN",
"negotiable": false,
"type": "price",
"label": "950 zł",
"previous_value": null,
"original_value": null,
"original_currency": null
},
"salary": null,
"condition": "used",
"params": [
{"key": "state", "name": "Stan", "value": "Używane", "normalized_value": "used"},
{"key": "phonemodel", "name": "Model telefonu", "value": "iPhone 13 Pro", "normalized_value": "iphone-13-pro"},
{"key": "builtinmemory_phones", "name": "Wbudowana pamięć", "value": "128GB", "normalized_value": "128gb"}
],
"category": {
"id": 2298,
"type": "electronics",
"breadcrumb": [
{"id": 99, "name": "Elektronika", "url": "https://www.olx.pl/elektronika/"},
{"id": 1838, "name": "Telefony", "url": "https://www.olx.pl/elektronika/telefony/"},
{
"id": 1839,
"name": "Smartfony i telefony komórkowe",
"url": "https://www.olx.pl/elektronika/telefony/smartfony-telefony-komorkowe/"
},
{
"id": 2298,
"name": "iPhone",
"url": "https://www.olx.pl/elektronika/telefony/smartfony-telefony-komorkowe/iphone/"
}
]
},
"location": {
"city": "Warszawa",
"city_id": 17871,
"district": "Żoliborz",
"district_id": 363,
"region": "Mazowieckie",
"region_id": 2
},
"photos": ["https://ireland.apollo.olxcdn.com/v1/files/tomgr0m5ytyr-PL/image;s=1000x750"],
"created_at": "2026-10-25T13:39:23.000Z",
"refreshed_at": "2026-10-25T13:41:50.000Z",
"valid_to": "2026-11-24T13:39:24.000Z",
"status": "active",
"is_active": true,
"is_business": false,
"is_promoted": true,
"is_highlighted": true,
"olx_delivery": false,
"is_job": false,
"seller": {"id": 8598981, "is_business": false, "business_name": null, "member_since": "2012-08-04T16:03:23.000Z"},
"country": "pl",
"language": "pl",
"currency": "PLN"
}description is the full text as plain text, and valid_to is when the ad expires unless the seller renews it. Job ads come with is_job: true and a salary block (from, to, period, currency, gross) instead of photos. An ad that has ended and an id that never existed both answer 404 "not found or no longer active", and that call is charged; OLX does not show a sold flag or a sale price, so the price you store is an asking price. An ad page can take from a few seconds to about a minute, slowest on olx.pt.
Step 6: Sellers
curl -s https://api.scavio.dev/api/v1/olx/seller \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user_id": "2547532895"}'{
"id": 2547532895,
"is_business": true,
"business_name": "Smartfony.net - Ogrodowa 9, Poznań",
"member_since": "2025-06-03T11:53:41.000Z",
"ads_url": "https://www.olx.pl/oferty/user/2MpbGf/",
"active_ads": 65,
"country": "pl",
"language": "pl",
"currency": "PLN"
}/seller-ads with the same user_id returns that seller's live ads in the search item shape, with the search sorts and filters and an optional query: this shop's 65 ads came back as 2 pages of 40. Most OLX sellers are private individuals, so a private seller is an id, is_business: false and a member-since date, nothing more. business_name is filled for business sellers only, and only when OLX holds a name for the business: the Warsaw flat above came from a business account with no name on file. OLX shows no seller ratings or reviews, so there are none to return.
Step 7: Categories, suggestions and similar ads
/categories without parent_id returns the top-level tree with direct children and live ad counts (19 top-level categories on olx.pl, 3,357 in all); with parent_id it returns that category's whole subtree:
{
"parent_id": null,
"parent": null,
"count": 19,
"total_categories": 3357,
"categories": [
{
"id": 5,
"name": "Motoryzacja",
"parent_id": null,
"level": 1,
"path": "motoryzacja",
"url": "https://www.olx.pl/motoryzacja/",
"type": "automotive",
"count": 4585439,
"children_count": 12,
"children": [
{
"id": 81,
"name": "Motocykle i Skutery",
"parent_id": 5,
"level": 2,
"path": "motoryzacja/motocykle-skutery",
"url": "https://www.olx.pl/motoryzacja/motocykle-skutery/",
"type": "automotive",
"count": 47198,
"children_count": 9
}
]
}
],
"country": "pl",
"language": "pl",
"currency": "PLN"
}/suggestions returns what the OLX search box suggests for a typed phrase, each with the category it is searched in, which is a quick way to map a keyword to a category_id. "rower" on olx.pl returned 10, starting with "rower" in Rowery górskie (category_id 1651) and "rower elektryczny" in Rowery elektryczne (1649). /similar takes an offer_id or url and returns the ads OLX shows next to it, in the search item shape: 29 next to the Warsaw iPhone 13 Pro above, from 550 zł to 999 zł among the first four. Similar works on pl, ro, pt, bg and ua.
Monitor new listings by polling newest and diffing ids
OLX has saved-search alerts for people, but no feed for software, so a monitor is a newest-first search on a schedule plus your own record of the ids you have seen:
import requests
API_KEY = "your_scavio_api_key"
seen: set[int] = set()
def poll(query: str, country: str = "pl", last_poll: str = "") -> list[dict]:
r = requests.post(
"https://api.scavio.dev/api/v1/olx/search",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"query": query, "country": country, "sort": "newest", "include_promoted": False},
timeout=180,
)
r.raise_for_status()
fresh = [ad for ad in r.json()["data"]["items"] if ad["id"] not in seen]
seen.update(ad["id"] for ad in fresh)
# refreshed ads also look unseen: keep only ads first posted since the last poll
return [ad for ad in fresh if ad["created_at"] > last_poll] if last_poll else freshTwo things we measured on November 12 shape the design. We polled "iphone" on olx.pl at 18:11 and again at 18:22 UTC. The second page 1 had 36 ids the first one did not, but only 5 of those 36 had been posted in the previous 24 hours; 31 were ads first posted more than a day earlier that their sellers had just refreshed. So an id you have not seen is not always a new ad: check created_at, and keep every id you have stored rather than only the last page. Second, on both polls the newest ad on page 1 was about 6 to 7 minutes old, so a check every few minutes does not get you closer than that. For busy searches, fetch page 2 as well, or narrow by category and city so one page covers the gap between polls.
Other markets
Every endpoint takes country: pl (the default), ro, pt, bg, ua, kz or uz. The same "iphone" search, newest first, returned 76,521 matches in UAH on olx.ua, 30,811 in RON on olx.ro, 15,625 in EUR on olx.pt and 11,670 in EUR on olx.bg. Where a site converts a price, value is the converted figure the site shows and original_value / original_currency keep what the seller typed: an olx.ro ad listed at 2,700 EUR came back as 14,439.90 RON, and on olx.uz 31 of 52 items were priced in y.e. units and came back in UZS, for example 840 y.e. as 10,058,412 UZS.
olx.kz and olx.uz answer in Russian by default; send "language": "kk" on olx.kz or "language": "uz" on olx.uz for Kazakh or Uzbek titles and labels on search, seller-ads and offer. Both sites hide the real count once a search passes 1,000 ads, so total is null there and total_capped is true. They also have no filters or similar endpoints and no OLX delivery flag. Both were sold in 2026, to Beeline Kazakhstan and TBC Bank Group, and still run on the shared OLX platform today.
Every OLX endpoint and what it costs
| Endpoint | What it returns | Credits |
|---|---|---|
/api/v1/olx/search | 40 ads a page (up to 50) plus promoted ads flagged with their slot; sorts, filters, location and radius | 1 |
/api/v1/olx/offer | One ad: full description, price, every parameter, breadcrumb, photos, dates, seller | 1 |
/api/v1/olx/seller | Business flag, business name (businesses only), member since, live ad count, seller page | 1 |
/api/v1/olx/seller-ads | One seller's live ads with the search sorts and filters | 1 |
/api/v1/olx/filters | A category's filters with send-as keys, value counts and per-region counts (pl, ro, pt, bg, ua) | 1 |
/api/v1/olx/categories | The category tree with ids, paths and live ad counts | 1 |
/api/v1/olx/locations | City and district autocomplete with city_id, district_id and region_id | 1 |
/api/v1/olx/suggestions | What the OLX search box suggests, with each suggestion's category | 1 |
/api/v1/olx/similar | About 30 ads OLX shows next to one ad (pl, ro, pt, bg, ua) | 1 |
Every call is 1 credit on every site, $1.00 per 1,000 requests on the Growth plan ($1 per 1,000 credits). A not-found, such as an ended ad or an unknown seller, is charged; a request the API rejects as invalid, such as filters on olx.kz, and a failed upstream call are not. Phone numbers, emails, private sellers' names, last-seen times and map positions are never returned.
Getting started
- Create a Scavio account and copy your API key; 50 free credits, no card, no OLX partner account.
- Map your keywords to categories with
/suggestionsor/categories, and your places to ids with/locations. - For a category with its own attributes, call
/filtersonce and store the keys you need. - Run a newest-first
/searchper saved search on a schedule, keep every id you have seen, and checkcreated_atto separate new ads from refreshed ones. - Call
/offerfor the new ads you want in full, and storeprice.value,refreshed_atand a timestamp each time: that table is your asking-price history. - Try the calls first in the playground, or give an agent the MCP server.
Try the OLX API free. Reference: OLX API · best OLX listings APIs · used vs new prices on OLX.pl · how to get Vinted listing data · Vinted new-listing alerts by API · how to get Allegro price data · how to get Redfin listing data
Frequently asked questions
Does OLX have a public API for searching listings?
No. OLX's developer FAQ at developer.olx.pl answers "Can I use API to read other people ads?" with: "It is not possible - you can manage only your own ads added on your authorized OLX account." OLX Group's Developer Hub FAQ answers "Can I use the API to get information from adverts statistics or other Market data?" with "Big NO! You can only manage content and its information from a user that authorized you to manage his content on his behind." Scavio's OLX API returns public listings from olx.pl, olx.ro, olx.pt, olx.bg, olx.ua, olx.kz and olx.uz with one key.
What is the OLX Partner API for?
Posting and managing ads for OLX users who authorize your app. Its specification says "OLX Europe shares public API for its partners. It allows to easily integrate with local sites by posting, managing adverts and communicating with OLX users via internal messaging system." Access needs an OLX account and an application that OLX verifies, and the client keys work for one country each. OLX Group's Developer Hub lists the OLX Europe API as stable with "No new developments or maintenance is being provided", while developer.olx.pl announces new order and status endpoints; both pages are live.
Which OLX sites does this cover?
The seven sites on the OLX Europe platform: olx.pl (the default), olx.ro, olx.pt, olx.bg, olx.ua, olx.kz and olx.uz, each in its own language and currency. OLX Brasil, OLX India, olx.ba (OLX Bosnia, a separate company with its own listing API) and the Dubizzle-run OLX sites are different platforms and are not covered.
What seller data does the OLX API return?
Most OLX sellers are private individuals, so Scavio returns a seller id, whether the seller is a business, the member-since date and, for business sellers only, the business name. Phone numbers, email addresses, private sellers' names, last-seen times, profile photos and map positions are never returned, and phone numbers or emails written into titles and descriptions are replaced with [phone removed] or [email removed]. A car's VIN is never returned.
What do OLX's terms say about using listing data?
OLX.pl changed its terms of service (Regulamin) on August 17, 2026, and we could not read the current text when writing this, so we do not quote it. Check OLX's current terms for each site you use and your local law for your use case; this is not legal advice. Scavio is built for monitoring and analysis: it does not post ads, message sellers, reveal phone numbers or buy anything.