03 Руководства
Синхронизация каталога
Как держать у себя копию рынка: один раз выгрузить каталог, а дальше забирать только то, что изменилось.
Первая выгрузка
Запрашивайте GET /v1/cars?market=kr&limit=100 и переходите по курсору, пока next_cursor не станет null. Каждая возвращённая машина — одна запись квоты, поэтому полная выгрузка большого рынка требует тарифа с подходящей квотой; на демо — до 20 машин за запрос.
Пагинация курсором
Пагинация только курсором: страница не «плывёт», когда каталог меняется. Параметр offset не поддерживается — запрос с ним получит 400. Поле count в ответе — сколько машин подходит под фильтры, если их не больше 10 000; больше — null.
Опрос ленты изменений
GET /v1/changes?market=kr&since=… отдаёт события с момента since: added — новая машина, disappeared — снята с продажи, price_drop и price_up — цена изменилась на min_pct процентов и больше. Копия рынка обновляется каждый час, поэтому опрашивать чаще смысла нет; насколько она свежа сейчас — в заголовке X-Data-Age-Seconds каждого ответа. Запоминайте момент прошлого опроса и передавайте его в since. Лента есть на тарифах Pro и Max и в демо; каждое событие — одна запись квоты.
Снятые с продажи
Проданная или снятая машина получает is_active=false и остаётся в API ещё 14 дней: её можно запросить по id или выбрать фильтром is_active=false. Ссылки на фото живут около суток — храните id машины, а не ссылку.
Пример на Python
import os
import time
from datetime import datetime, timezone
import httpx
api = httpx.Client(
base_url="https://api.apiauto.space/v1",
headers={"X-API-Key": os.environ["APIAUTO_KEY"]},
timeout=30,
)
def import_market(market: str) -> None:
"""The first import: every page of the catalog, by the cursor."""
params = {"market": market, "limit": 100}
while True:
page = api.get("/cars", params=params).raise_for_status().json()
for car in page["items"]:
save(car) # your database
if not page["next_cursor"]:
break
params["cursor"] = page["next_cursor"]
def follow_changes(market: str, since: str) -> str:
"""One poll of the feed; returns the moment to ask from next time."""
now = datetime.now(timezone.utc).isoformat()
params = {"market": market, "since": since, "limit": 100}
while True:
page = api.get("/changes", params=params).raise_for_status().json()
for event in page["items"]:
if event["type"] == "added":
save(api.get(f"/cars/{event['car_id']}").raise_for_status().json())
elif event["type"] == "disappeared":
mark_sold(event["car_id"])
else: # price_drop, price_up
update_price(event["car_id"], event["new_price"])
if not page["next_cursor"]:
return now
params["cursor"] = page["next_cursor"]
import_market("kr")
since = datetime.now(timezone.utc).isoformat()
while True:
time.sleep(3600) # the copy is refreshed hourly
since = follow_changes("kr", since)