okidoki API & Scraper
okidoki.ee is where Estonia sells phones, furniture, children's things, cars, flats, services and jobs, and this API reads it as JSON.
🤖 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.
`search` finds adverts by text and narrows them by category, price, condition (new or used), seller type (private or business), county / municipality / place, and offers, video, urgent and escrow flags; every row carries the advert id, title, EUR price, photo, whether the seller is a business and its name, the verification labels and the date the site shows. `listing` returns one advert in full: category path, price with its shape (fixed, from, up to, range, per month or per day, free), condition, every attribute the site prints (mileage, gearbox and engine for a car; area, rooms, floor and building for a flat; field and hours for a job), location, description, every photo, total and today's views, and the seller's id, name, verification, member-since date, feedback score and number of adverts. `categories` returns the whole tree of about 660 categories with the site's live advert count, and `locations` turns a place name into the location filter. Measured on 2026-10-15: 1 406 adverts for iphone, 2 093 passenger cars, 402 flats.
What an okidoki field actually contains
Seven fields that need one sentence of context. Every row was checked against live okidoki pages on 2026-10-15.
| Field | What it holds |
|---|---|
| price / price_type | price is set only when the advert prints one amount. A salary or rent printed as a range (1 000 - 3 200 € per month), as 'from' or as 'up to' comes back as price_min / price_max with price null, because the page's own machine-readable price for those is the lower bound or 0. price_type says which shape it is: fixed, from, up_to, range, free, on_request, none. |
| price_period | month or day when the price is per period (rents, salaries); the site's own word is kept in price_period_text. |
| seller_type / company_name | On search rows: company when the advert card carries a business name box, private otherwise. Checked: 50 of 50 rows were company with the site's business filter on, 0 of 50 with the private filter on. The advert page itself does not mark businesses; use search with seller_id and seller_type=company to check one seller. |
| shown_date | The date okidoki prints on the advert. It moves when the seller renews the advert, so it is not the first-publish date: an advert from 2025 showed today's date. |
| total / total_capped | The site's own result count. okidoki stops counting at 5 000 and at page 100; total_capped is true when that ceiling is reached. |
| category_id | The deepest category the advert sits in. For flats and houses the site's breadcrumb stops at Real estate; category_id still names Flats (1505) or Houses. |
| itemprop_price / price_mismatch | The page's machine-readable price next to the printed one. On 10 of 10 single-amount adverts they agreed; price_mismatch flags any advert where they do not. |
Measured limits: 50 rows a page by default (25, 100 or 200 on request); the count and the pages stop at 5 000 adverts / page 100; asking past the last page returns zero rows with page_clamped instead of repeating the last page. Phone numbers are not returned.
Real request and response JSON
Captured from the indexed primary action, search, on .
{
"method": "POST",
"url": "https://api.reefapi.com/okidoki/v1/search",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"query": "iphone",
"category": 1403
}
}{
"ok": true,
"meta": {
"api": "okidoki",
"endpoint": "search",
"mode": "live",
"latency_ms": 1968.8,
"record_count": 50,
"bytes": 446786,
"cache_hit": false,
"upstream_requests": 1,
"charged_credits": 3,
"version": "1.0.0",
"request_id": "bc0c95d448ab44bb",
"queue_ms": 1.5,
"fetched_at": "2026-10-15T17:02:57.158Z"
},
"data": {
"total": 874,
"total_capped": false,
"page": 1,
"per_page": 50,
"last_page": 18,
"has_more": true,
"page_clamped": false,
"applied": {
"query": "iphone",
"category": 1403,
"seller_id": null,
"page": 1,
"per_page": 50,
"sort": "newest",
"condition": null,
"seller_type": "all",
"min_price": null,
"max_price": null,
"location": null
},
"rows": [
{
"id": 14181158,
"url": "https://www.okidoki.ee/item/iphone-17-air-256gb/14181158/",
"title": "iPhone 17 Air 256GB",
"price": 600,
"price_min": 600,
"price_max": 600,
"price_type": "fixed",
"price_period": null,
"price_period_text": null,
"is_free": false,
"currency": "EUR",
"price_text": "600 €",
"price_per_m2": null,
"image": "https://images.okidoki.st/14181158/41606783_10.jpg",
"photo_count": 3,
"seller_type": "private",
"company_name": null,
"identity_verified": true,
"data_verified": false,
"labels": [
"Kasutaja tuvastatud"
],
"shown_date": "2026-10-15T17:01:00+03:00",
"shown_date_text": "Täna, 17:01"
},
{
"id": 13761854,
"url": "https://www.okidoki.ee/item/iphone-16-plus/13761854/",
"title": "iPhone 16 Plus",
"price": 200,
"price_min": 200,
"price_max": 200,
"price_type": "fixed",
"price_period": null,
"price_period_text": null,
"is_free": false,
"currency": "EUR",
"price_text": "200 €",
"price_per_m2": null,
"image": "https://images.okidoki.st/13761854/39616199_10.jpg",
"photo_count": 6,
"seller_type": "private",
"company_name": null,
"identity_verified": false,
"data_verified": false,
"labels": [],
"shown_date": "2026-10-15T16:50:00+03:00",
"shown_date_text": "Täna, 16:50"
},
{
"id": 14181047,
"url": "https://www.okidoki.ee/item/apple-iphone-15-pro-black-256gb-heas-korras-aku-92/14181047/",
"title": "Apple iPhone 15 Pro Black 256GB heas korras. Aku 92%",
"price": 570,
"price_min": 570,
"price_max": 570,
"price_type": "fixed",
"price_period": null,
"price_period_text": null,
"is_free": false,
"currency": "EUR",
"price_text": "570 €",
"price_per_m2": null,
"image": "https://images.okidoki.st/14181047/41606306_10.jpg",
"photo_count": 8,
"seller_type": "private",
"company_name": null,
"identity_verified": true,
"data_verified": false,
"labels": [
"Kasutaja tuvastatud"
],
"shown_date": "2026-10-15T16:21:00+03:00",
"shown_date_text": "Täna, 16:21"
}
]
}
}What the okidoki API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| search | Search okidoki.ee adverts by text, category, seller, price, condition, seller type and location. One page of advert cards with price, photo, seller type and the date the site shows, plus the site's own total. | Price-intelligence teams call search to search okidoki.ee adverts by text, category, seller, price, condition, seller type and location. | query, category, seller_id, page, per_page, ... |
| listing | One okidoki advert in full: title, category path, price (fixed / from / up to / range, period), condition, all attributes (car, flat and job parameters included), location, description, every photo, view counts, the date the site shows, and the seller block. | Classifieds aggregators call listing to get one okidoki advert in full. | id |
| categories | okidoki's full category tree (about 660 nodes) with the site's live advert count per category. Use category_id in search. | Resale and arbitrage tools call categories to get okidoki's full category tree (about 660 nodes) with the site's live advert count per category. | parent |
| locations | Resolve an Estonian place name to okidoki location tokens (county / municipality / place) for search's `location` filter. | Lead-generation teams call locations to resolve an Estonian place name to okidoki location tokens (county / municipality / place) for…. | query |
| suggest | okidoki's own search autocomplete: popular queries for what was typed, some scoped to a category. | Price-intelligence teams call suggest to get okidoki's own search autocomplete. | query |
Call search from your stack
curl -X POST https://api.reefapi.com/okidoki/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"iphone","category":1403}'import requests
r = requests.post(
"https://api.reefapi.com/okidoki/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"query": "iphone",
"category": 1403
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/okidoki/v1/search", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"query": "iphone",
"category": 1403
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.okidoki.search with {"query":"iphone","category":1403}.Who uses this API and why
- Track Estonian second-hand prices for a product: search a query in one category daily and keep id, EUR price, condition and shown date.
- Watch used-car supply in Estonia: page category 1601 with condition=used and read mileage, engine and gearbox from each advert.
- Map rent levels by town: search flats with a location token and read area, rooms, floor and the monthly price from each advert.
- Find the businesses selling in a category with seller_type=company, then list each one's adverts with seller_id.
- Follow the Estonian jobs board: salary ranges, field and hours from category 361267 adverts.
Questions developers ask before integrating
Do I need an okidoki account or an Estonian connection?
No. Search, adverts, the category tree and the location lookup are read without an account, and you call reefapi.com from anywhere.
Which categories does it cover?
All of them: electronics, real estate, home and garden, children, animals, hobbies, fashion, sport, services, transport, jobs and business. categories returns the full tree with each category's live advert count; pass a category_id to search.
How do I search one city or county?
Call locations with a place name, for example tartu. It returns tokens such as r12 (Tartu county), m17 (Tartu city) or p684 (Tartu). Pass one of them as location to search. Measured: iphone adverts went from 1 406 to 1 082 in Tallinn and to 30 in Pärnu county.
Can I get only business sellers or only private sellers?
Yes, seller_type = company or private. Measured on iphone: 100 business adverts and 1 305 private ones, and every returned row matched the filter.
How are salaries and rents returned?
With their shape: a range gives price_min and price_max, 'from' gives price_min, 'up to' gives price_max, and a per-month or per-day amount sets price_period. A single price is never invented for a range.
Is the date on an advert the day it was posted?
No. okidoki prints the latest renewal, so the API calls it shown_date and keeps the site's own text next to it.
How many results can one search return?
okidoki stops at 5 000 adverts and page 100. Narrow with category, price or location to reach the rest; total_capped tells you when the ceiling is hit.
Can I get the seller's phone number?
No. okidoki shows it only after a separate click, and the API does not request it. You get the seller's id, name, verification, member-since date, feedback score and advert count.
What is the okidoki API?
okidoki API is a ReefAPI endpoint group for estonia's general classifieds site: search adverts, read any advert in full, with eur prices and seller details. It returns live JSON through POST requests under /okidoki/v1.
Is the okidoki API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. okidoki calls use the same shared credit balance as every other ReefAPI engine.
Do I need an okidoki login or account?
No login to okidoki 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 okidoki 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 okidoki API use?
okidoki actions currently cost 1-3 credits per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.
Can I call okidoki from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call okidoki actions with the same key, credit pool and JSON envelope used by normal REST requests.