# Changelog of Finn Torget Scraper — Norwegian Marketplace (`blackfalcondata/finn-torget-scraper`) Actor

- **URL**: https://apify.com/blackfalcondata/finn-torget-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/blackfalcondata/finn-torget-scraper.md

## Changelog

### 0.2.1 — 2026-09-06

#### Billing correctness across restarts and overlapping runs

- A run that the platform restarts mid-way no longer re-delivers what it had already delivered, and a run that resumes after another run has moved the shared incremental state on now keeps what that run delivered instead of billing the change again.
- A listing that was merely seen again, without being delivered, is no longer mistaken for a newer version of itself.
- An expiry that has already been reported is now recorded as reported rather than dropped, so it is not reported a second time — and a listing that comes back after one is reported as NEW, as documented.
- Where one search had been stored under two spellings (with and without an explicit sort), both records are read, merged once and retired, so paid history is not lost and settled expiries are not revived.

#### Known limitation during the upgrade

State written by earlier versions cannot say whether a listing is missing from it because a scan was incomplete or because its expiry had already been reported. Listings carried over from such state are therefore treated conservatively for one run: they are never billed as new again, and if they are gone their expiry is recorded without an EXPIRED row. An EXPIRED row can be missed once per listing in that window; no listing is billed twice. It resolves on the first run that sees the listing or completes a scan.

### 0.2.0 — 2026-05-12

#### Behavior change

- **`omitNulls` default is `true`.** Output rows now drop fields with null, empty string, empty array, or empty object values by default. Set `omitNulls: false` if you need a stable schema where every row has every documented key.

#### New typed output fields

Generic-suffix matching (validated on the DBA-equivalent Schibsted Aurora platform across 1320 listings × 320 sub-cats) promotes category-prefixed extras to typed columns:

- `brand` matches `*_brand` (`lego_brand`, `shoes_brand`, `mobile_brand`, …)
- `model` matches `*_model`
- `size` matches `*_size` (`shoe_size`, `women_clothing_size`, `mobile_memory_size`, …)
- `subType` matches `*_type` excluding `ad_type` (`shoe_type`, `hifiparts_type`, `women_clothing_dress_type`, …)
- `color` from `colour` / `color` extras
- `material` matches `*_material` (`bags_purses_material`, `jewellery_main_material`)
- `gender` matches `gender` or `*_gender`
- `theme` matches `*_theme` (e.g. `lego_theme`)
- `designer` for art/furniture listings
- `age` matches `*_age` (pet age)
- `season` for seasonal items (Påske, Jul, …)
- `platform` for gaming (`games_group`, `*_platform`)
- `depth`, `height`, `width`, `length` (cm — furniture)

#### Shared / location fields

- `coordinateAccuracy` is now populated for supported listings.
- `mapImageUrl` extracted from recommerce detail JSON (`itemData.location.position.mapImage`).

#### Fiks ferdig filter

- Added the `fiksFerdig` input flag to return only listings with Fiks ferdig (transactable shipping). About 86% of recommerce listings qualify (verified live).

#### Internal

- 15 new unit tests in `tests/transform.test.ts` covering extras matching, length parsing, and omitNulls semantics.

### 0.1.1 — 2026-05-11

- Fixed: `priceMin` / `priceMax` filters now actually narrow results to the requested price range. Previously they were accepted but ignored, and runs returned the full unfiltered list.
- Added: Live canary test suite — verifies each filter actually narrows results against an unfiltered baseline on every release.

### 0.1.x — 2026-04-14

- Added: `descriptionHtml`, `descriptionMarkdown` output fields (triple-format descriptions for RAG/LLM pipelines)
- Added: `contentHash` output field (stable hash over content-identifying fields, used for change detection)

### 0.1.x — 2026-04-14

- Added: cross-run repost detection (`isRepost`, `repostOfId`, `repostDetectedAt`)
- Added: `skipReposts` input to exclude detected reposts from output

All notable changes to FINN.no Torget Scraper are documented here.

### \[0.1.0] — 2026-03-22

#### Added

- Initial release: direct HTTP fetch + React Query hydration extraction from FINN.no Torget
- 35 structured output fields per listing (title, price, condition, brand, model, category path, GPS coordinates, images, seller info, shipping, buy-now, attributes)
- Multi-page search with a `maxResults` limit
- Detail enrichment (`includeDetails`): description, full category path, zip code, attributes
- Compact output mode for AI-agent/MCP workflows with `descriptionMaxLength` truncation
- Incremental mode: track new/changed listings across runs with scoped `stateKey`
- Filters: category (11 categories), condition, region (16 Norwegian counties), price range, seller type, sort order
- PAY_PER_EVENT pricing: `actor-start` ($0.01) + `result` ($0.002) events
- No proxy, no external services — direct fetch only
- 97 integration tests passing (vitest)
