# Changelog of Otomoto.pl Scraper (`redomic/otomoto-scraper`) Actor

- **URL**: https://apify.com/redomic/otomoto-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/redomic/otomoto-scraper.md

## Changelog

### Unreleased

- 0.1 (2026-11-16): add `query` keyword filter for search, detail and monitor runs (passed to Otomoto search and matched across title, version, short description and description) so buyers can narrow results by terms like "M pakiet" or "faktura VAT".

- 0.1 (2026-11-15): keep per-input status and run summary in the key-value store (`STATUS`, `SUMMARY`) instead of the dataset; emit English `driveType`, `color`, `condition`/`newUsed` values with the original labels in `*Label` fields and drop the duplicated `transmission` field; compute `marketMedianPrice`/`priceVsMarketPct` for cohorts with 3+ cars sharing make, model, year within one year and mileage band.

- 0.1 (2026-11-15): default `mode` to `detail` (input schema, README, `build_input`) so default task runs return enriched offer data; `mode: "search"` returns listing cards only.

- 0.1 (2026-11-15): trim Listings dataset view to high-fill core fields (move `priceEvaluation`, `cepikVerified`, `createdAt`, `daysListed` to Details) to reduce empty columns in Store previews.

- 0.1 (2026-11-14): add deal-signal fields `badges` and `isNegotiable` to search, detail, dealer and monitor rows (parsed from `__NEXT_DATA__`), preserved in monitor state/change rows, and surfaced in dataset views and README.

- 0.1 (2026-11-14): add derived `daysListed` (whole days between `createdAt` and run `scrapedAt`, clamped at 0) on all search/detail/monitor rows with created timestamps, including monitor change rows.

- 0.1 (2026-11-14): filter radius/centre and includeNoPrice while collecting and paging so maxItems is filled from passing rows (instead of cutting before filters), with MAX_PAGES cap.

- 0.1 (2026-11-13): fix blank Store-preview columns in overview by keeping only high-fill card fields in Listings and moving sparse/detail fields (`version`, `sellerName`, price-drop, detail and monitor columns) to Details/Price history views.

- 0.1 (2026-11-13): add structured `bodyType` input filter (sedan, kombi/estate, suv, compact, coupe, cabrio, minivan, city-car) mapped to Otomoto `search[filter_enum_body_type]`, with schema, URL builder, tests and README usage.

- 0.1 (2026-11-12): extend monitor `removed` rows to include last-known `priceHistory`, `firstPrice`, `lowestPrice`, `priceDropPct` and `daysOnMarket` (whole days between `firstSeenAt`/`lastSeenAt`), add `daysOnMarket` to `new`/`changed` rows, surface fields in dataset schema and README, and add fixture-backed tests for unchanged ($0), price-drop `changed`, and `removed` outcomes.

- 0.1 (2026-11-12): add monitor regression test verifying unchanged run bills $0 and a price change emits a change row with `previousPriceAmount`, `priceDropPct`, `firstSeenAt`/`lastSeenAt` and is charged once.

- 0.1 (2026-11-12): add fixture-backed assertions for detail/search parity fields (`driveType`, `condition`/`newUsed`, `generation`, `imageCount`, `bumpedAt`, `updatedAt`) across search, detail and dealer rows.

- 0.1 (2026-11-12): add detail/search parity fields — parse and emit `driveType`, `condition`/`newUsed`, `generation`, `imageCount`, and `bumpedAt` (and keep `updatedAt` when available) from `__NEXT_DATA__`/parameters for search, detail and dealer rows.

- 0.1 (2026-11-11): normalize data quality fields — map country origins to consistent ISO-like 2-letter codes (e.g. `i`→`it`, `d`→`de`), clean seller names (trim/fallback from seller site), and drop always-null/unavailable `bodyType`, `countryOrigin` and `isPremiumTopAd` fields instead of emitting nulls.

- 0.1 (2026-11-11): add structured `sort` (`newest`, `cheapest`, `price-asc`, `price-desc`) and `onlyPriceDrops` inputs for search filters, mapping to Otomoto `search[order]` and `search[filter_enum_special_params]=price_drop`.

- 0.1 (2026-11-10): add fixture-backed regression tests for failed battery inputs (VW Golf diesel <=40k and Toyota Corolla Krakow 2018-2022 30k-70k) to guard against 0-row outcomes.

- 0.1 (2026-11-10): list and offer pages are now fetched with impit's Chrome TLS fingerprint through the Apify datacenter proxy (plain httpx is kept only as a fallback), with 5 attempts and exponential backoff up to ~10 s on 403/429 and a fresh proxy session per attempt. Fixes the 10 Nov battery failure where three fresh-session httpx attempts all got HTTP 403 from otomoto.pl list pages. `tests/test_client.py` covers 403,403,200 -> 32 real rows, the all-403 case, the 429 retry, the 404 fast-fail and the httpx fallback.

- 0.1 (2026-11-10): stop escalating to a direct (no-proxy) fetch when the residential PL proxy configuration is unavailable; only escalate when a real residential proxy URL can be obtained, so a missing residential config keeps retrying through the datacenter proxy instead of issuing direct requests that otomoto blocks. Captured and tested the two battery inputs that were 403-blocked (VW Golf diesel, Toyota Corolla Krakow).

- 0.1: three-window canary behavior — per-request escalation after 2 datacenter 403s, detail enrichment off residential

- 0.1 (2026-11-12): complete README Monitor docs — setup/scheduling, status meanings, block/retry behavior, limitations and terms/compliance notes.

### 0.1 - 2026-11-13

- Add in-run market benchmark: `marketMedianPrice`/`priceVsMarketPct` on priced rows in make+model groups (3+ listings, fallback make) and a `market` block on summary rows (count/min/median/mean/max price, median mileage); monitor changed rows benchmarked against current scrape, removed rows keep price history unchanged.

- 0.1 (2026-11-14): remove dead `isNegotiable` field (no negotiation key published in Otomoto `__NEXT_DATA__`) from parser output, monitor state, dataset schema and README.

- 0.1 (2026-11-15): omit empty `badges` and keep a single `imageCount` field on rows so prefill/detail outputs have no always-empty or duplicate columns.
