API віддає ті самі дані, що й сайт: лоти Prozorro.Продажі, їхні зміни й ваші збережені фільтри. Підходить, щоб підтягнути лоти у свою CRM, таблицю чи сайт. Лише читання, відповіді — JSON.
Ключ і перший запит
Ключ створюється в кабінеті, на вкладці API. Він показується один раз — скопіюйте його одразу. Ключ передається в заголовку:
curl -H "Authorization: Bearer prs_ваш_ключ" \
"https://parser.randomstar.org/api/v1/lots?kind=land_lease®ion=Полтавська&per_page=5"
Замість Authorization можна надіслати X-Api-Key: prs_…. У рядку адреси ключ не приймаємо: звідти він потрапляє в журнали й історію браузера. Ключ — як пароль: не публікуйте його у фронтенді сайту чи в репозиторії. Загубили — відкличте в кабінеті й створіть новий. Ключів може бути до п’яти — наприклад, окремо для CRM і для скрипта.
Ліміти
Ліміт — кількість запитів на добу для акаунта (спільний для всіх його ключів); обнуляється опівночі за Києвом. Довідники (/kinds, /regions, /statuses) не рахуються і працюють без ключа.
| Тариф | Запитів на добу |
|---|---|
| Профі | 1 000 |
| Бізнес | 20 000 |
У кожній відповіді — заголовки X-RateLimit-Limit (ліміт), X-RateLimit-Remaining (скільки залишилося) і X-RateLimit-Reset (коли обнулиться, Unix-час). Ліміт вичерпано — відповідь 429 із заголовком Retry-After (секунди до обнулення).
Методи
| Запит | Що повертає |
|---|---|
GET /api/v1/lots | Пошук лотів за умовами, сторінками |
GET /api/v1/lots/UA-… | Один лот: усі поля, історія змін, інші аукціони того ж об’єкта |
GET /api/v1/changes | Стрічка змін (нові лоти, ціна, дати, статус, документи, результат) — для синхронізації |
GET /api/v1/filters | Ваші збережені фільтри |
GET /api/v1/filters/id/lots | Лоти за вашим фільтром — ті самі, про які пише бот |
GET /api/v1/me | Чий ключ, тариф, ліміт і скільки використано сьогодні |
| Вебхук | Ми самі надсилаємо нові лоти й зміни на вашу адресу |
GET /api/v1/kinds, /regions, /statuses | Довідники кодів (без ключа) |
Адреса — https://parser.randomstar.org/api/v1/…. Підписи (тип, статус, тариф) — українською; ?lang=en — англійською.
Пошук лотів: /lots
Умови ті самі, що в каталозі й фільтрах кабінету, тож API бачить рівно те, що ви бачите на сайті.
| Параметр | Значення |
|---|---|
q | Слова з назви чи населеного пункту; номер UA-… або кадастровий номер — точний пошук |
kind | Тип аукціону — код із /kinds, наприклад land_lease |
region | Область — як у /regions, наприклад Полтавська, м. Київ |
min, max | Стартова ціна, ₴ |
deal | discount — лише зі знижкою повторного аукціону, dutch — лише голландські (ціна знижується на торгах) |
status | open (типово — приймають або скоро прийматимуть заяви), all або коди з /statuses через кому |
published_since, modified_since | Дата чи дата й час ISO 8601: 2026-10-01, 2026-10-01T09:00:00+03:00 |
sort | new (типово), modified, deadline (кінець прийому заяв), price_asc, price_desc |
page, per_page | Сторінка й розмір (до 100, типово 20) |
Відповідь:
{
"data": [
{
"id": "LRE001-UA-20261002-88807",
"url": "https://parser.randomstar.org/auctions/lre001-ua-20261002-88807/",
"source_url": "https://prozorro.sale/auction/LRE001-UA-20261002-88807/",
"kind": "land_lease", "kind_name": "Оренда землі",
"status": "active_tendering", "status_name": "Прийом заяв",
"title": "Аукціон з укладення договору оренди земельної ділянки…",
"region": "Полтавська", "locality": "Лохвицький район",
"price": {"amount": 16000.0, "currency": "UAH", "period": null, "vat_included": false},
"discount_percent": null, "area_ha": 2.7999, "area_m2": null,
"cadastral": "5322685300:00:002:0190",
"dates": {"published": "2026-10-02T16:12:00+03:00", "modified": "…",
"tender_end": "2026-10-15T20:00:00+03:00", "auction_start": "2026-10-16T11:25:00+03:00"},
"cancelled": false
}
],
"meta": {"page": 1, "per_page": 20, "total": 125, "pages": 7}
}
Картка лота: /lots/UA-…
Номер аукціону — у будь-якому регістрі. До полів зі списку додаються: title_uk, title_en, auction_type, item_type, cav, location (координати), guarantee (гарантійний внесок), min_step, normative_value (нормативна грошова оцінка землі), land_purpose, lease_duration (ISO 8601, P7Y), seller (назва й ЄДРПОУ — лише юрособи й органи влади), platform, dates.tender_start, attempt, previous_auction_id, documents_count, bids_count, result_amount, а також:
changes— останні 50 змін лота (найновіші першими);same_object_auctions— інші аукціони того ж об’єкта (повторні, з нижчою ціною).
Стрічка змін: /changes
Для синхронізації своєї бази: забирайте зміни по порядку й запам’ятовуйте курсор.
| Параметр | Значення |
|---|---|
since_id | Курсор: зміни з id більшим за нього. Без нього — зміни за останню добу |
limit | До 500, типово 100 |
events | Через кому: new, status, price, dates, docs, cancelled, result |
q, kind, region, min, max, deal | Лише зміни лотів, що підходять під умови |
{
"data": [
{"id": 812345, "event": "price", "old": "920000", "new": "736000", "at": "2026-10-04T09:12:00+03:00",
"lot": {"id": "…", "kind": "dgf", "price": {"amount": 736000.0, …}, …}}
],
"meta": {"next_since_id": 812345, "has_more": false}
}
Наступний запит — з since_id = next_since_id. Якщо has_more = true, запитуйте одразу ще раз; інакше — через кілька хвилин (ми оновлюємо дані кожні 5 хвилин).
Ваші фільтри: /filters
/filters — список фільтрів із кабінету: id, назва, умови, чи ввімкнений, куди надсилає. /filters/id/lots — лоти за фільтром; параметри status, sort, page тощо — як у /lots. Змінили фільтр у кабінеті — API одразу бачить нові умови.
Вебхуки
Замість того щоб опитувати /changes, можна дати нам адресу — і ми самі надсилатимемо події: нові лоти за вашими фільтрами й зміни «Моїх лотів» (ті самі, що приходять у Telegram). Адреса задається в кабінеті, на вкладці API; там же — секрет підпису, кнопка тестового запиту й стан останньої доставки. Вебхук один на акаунт, адреса — лише https:// і лише публічна.
Події збираються кожні 5 хвилин і приходять пачкою — POST із JSON:
POST /radar-webhook HTTP/1.1
Content-Type: application/json; charset=utf-8
X-Radar-Event: lots
X-Radar-Delivery: dlv_3f9a1c2b4d5e6f70
X-Radar-Timestamp: 1791100000
X-Radar-Signature: sha256=5c1e…
{
"id": "dlv_3f9a1c2b4d5e6f70",
"type": "lots",
"created_at": "2026-10-04T10:05:00+03:00",
"events": [
{
"type": "lot.new",
"reason": "filter",
"filter": {"id": 12, "name": "Оренда землі · Полтавська"},
"change": {"id": 812345, "event": "new", "old": null, "new": null, "at": "2026-10-04T10:01:12+03:00"},
"lot": {"id": "LRE001-UA-20261004-12345", "url": "…", "price": {"amount": 16000.0, …}, …}
},
{
"type": "lot.changed",
"reason": "watch",
"filter": null,
"change": {"id": 812350, "event": "price", "old": "920000", "new": "736000", "at": "…"},
"lot": {…}
}
]
}
typeподії:lot.new— новий лот за фільтром;lot.changed— зміна лота, за яким ви стежите (полеchange.event:status,price,dates,docs,cancelled,result);lot.relisted— той самий об’єкт виставлено повторно, а ви стежили за попереднім аукціоном (reason:relist; новий лот сам додається у відстеження).lot— у тому ж вигляді, що в/lots. Повну картку можна взяти через/lots/UA-….- Тестовий запит із кабінету —
X-Radar-Event: pingі порожнійevents. - Одна подія може прийти двічі (наприклад, ваш сервер прийняв дані, але відповів із помилкою), тож зберігайте за
change.id.
Відповідь і повтори
Відповідайте кодом 2xx упродовж 10 секунд — пачка вважається доставленою. Інакше повторимо через 1, 5, 30 хвилин, 2 і 6 годин, після чого пачку буде відкинуто. Події приходять по порядку: поки пачка не доставлена, наступні чекають. Після 20 невдач поспіль вебхук вимикається — причина в кабінеті, увімкнути знову — кнопкою «Зберегти й перевірити». Перенаправлень (301, 302) не виконуємо: вказуйте кінцеву адресу.
Перевірка підпису
Підпис — HMAC-SHA256 від рядка {X-Radar-Timestamp}.{тіло запиту} із секретом із кабінету. Перевіряйте його і не приймайте запити, старші за кілька хвилин.
// PHP
$body = file_get_contents('php://input');
$ts = (int)($_SERVER['HTTP_X_RADAR_TIMESTAMP'] ?? 0);
$sig = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, getenv('RADAR_WEBHOOK_SECRET'));
if (!hash_equals($sig, $_SERVER['HTTP_X_RADAR_SIGNATURE'] ?? '') || abs(time() - $ts) > 300) {
http_response_code(401); exit;
}
$data = json_decode($body, true);
foreach ($data['events'] as $e) { /* $e['type'], $e['lot']['id'] … */ }
http_response_code(200);
# Python (Flask)
import hmac, hashlib, os, time
from flask import request, abort
@app.post("/radar-webhook")
def radar_webhook():
body = request.get_data()
ts = request.headers.get("X-Radar-Timestamp", "0")
sig = "sha256=" + hmac.new(os.environ["RADAR_WEBHOOK_SECRET"].encode(),
ts.encode() + b"." + body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(sig, request.headers.get("X-Radar-Signature", "")) \
or abs(time.time() - int(ts)) > 300:
abort(401)
for e in request.get_json()["events"]:
... # e["type"], e["lot"]["id"]
return "", 200
Помилки
Помилка — відповідь із кодом HTTP і тілом {"error": {"code": "…", "message": "…"}}.
| HTTP | code | Що сталося |
|---|---|---|
| 400 | bad_sort, bad_status, bad_date | Неправильний параметр |
| 401 | no_key, bad_key | Немає ключа, ключ невідомий або відкликаний |
| 403 | plan_no_api | На тарифі немає API |
| 404 | lot_not_found, filter_not_found, unknown_method | Немає такого лота, фільтра чи методу |
| 405 | method_not_allowed | API лише для читання — тільки GET |
| 429 | daily_limit | Вичерпано добовий ліміт |
Приклади
PHP
$ch = curl_init('https://parser.randomstar.org/api/v1/lots?kind=privatization&sort=deadline');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('RADAR_API_KEY')],
]);
$res = json_decode(curl_exec($ch), true);
foreach ($res['data'] as $lot) {
echo $lot['id'], ' — ', $lot['price']['amount'], ' ₴ — ', $lot['url'], PHP_EOL;
}
Python
import os, requests
r = requests.get(
"https://parser.randomstar.org/api/v1/lots",
params={"kind": "land_lease", "region": "Полтавська", "max": 200000},
headers={"Authorization": "Bearer " + os.environ["RADAR_API_KEY"]},
timeout=30,
)
r.raise_for_status()
for lot in r.json()["data"]:
print(lot["id"], lot["price"]["amount"], lot["dates"]["tender_end"])
Синхронізація змін (Python)
since = load_cursor() # 0 при першому запуску
while True:
r = requests.get("https://parser.randomstar.org/api/v1/changes",
params={"since_id": since, "limit": 500, "kind": "dgf"},
headers={"Authorization": "Bearer " + KEY}, timeout=30).json()
for ch in r["data"]:
save(ch) # ваша обробка
since = r["meta"]["next_since_id"]
save_cursor(since)
if not r["meta"]["has_more"]:
break
Умови використання
- Дані — відкриті дані Prozorro.Продажі. Показуючи лоти своїм користувачам, давайте посилання на джерело — поле
source_url. - Персональних даних фізичних осіб в API немає: ми прибираємо їх ще під час збору.
- Правила використання й ліміти — у публічній оферті. Є питання чи потрібен інший ліміт — напишіть нам.
Не знайшли відповіді?
Подивіться питання та відповіді або напишіть нам — відповімо й допишемо документацію.