Otomoto.pl Scraper — Clean History & VAT Invoice avatar

Otomoto.pl Scraper — Clean History & VAT Invoice

Pricing

from $3.99 / 1,000 results

Go to Apify Store
Otomoto.pl Scraper — Clean History & VAT Invoice

Otomoto.pl Scraper — Clean History & VAT Invoice

Otomoto.pl Scraper extracts car listings, prices, mileage, fuel type, gearbox, specifications, seller details, locations, and other vehicle data from Otomoto.pl. Automate automotive market research, price tracking, competitor analysis, and lead generation.

Pricing

from $3.99 / 1,000 results

Rating

0.0

(0)

Developer

Scrapio

Scrapio

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

3 days ago

Last modified

Share

Otomoto.pl Scraper — Adverts, Sellers and Clean-History Flags

Otomoto.pl Scraper — Clean History & VAT Invoice extracts vehicle adverts from Otomoto.pl, Poland's largest used-vehicle marketplace, pre-screened on Otomoto's own provenance filters — accident-free, undamaged, documented service history, VAT invoice, first owner, registered in Poland, country of origin — and returns each one as structured JSON carrying the seller block, pricing, equipment and every provenance flag as a flat, typed column. Unlike a scraper that hands back raw HTML, every advert, seller detail and paperwork flag arrives ready for a spreadsheet, database or LLM context window with no parsing step. This guide documents every input, every output field, and how procurement, research and AI teams actually run it.


🧭 What Does Otomoto.pl Scraper — Clean History & VAT Invoice Do?

This actor is a specialised Otomoto.pl scraper that searches or reads individual vehicle adverts on otomoto.pl and narrows the result to cars whose declared history and paperwork pass a screen built from Otomoto's own search filters. It returns vehicle adverts (full listing data), the seller block attached to each advert (dealer or private-seller details as Otomoto publishes them), and a set of flat provenance and paperwork flags — accident-free, damage status, VAT invoice, VAT margin invoice, first owner, service history, registered-in-Poland, country of origin and VIN-published. No Otomoto.pl account or login is required — the actor reads the same __NEXT_DATA__ payload embedded in the public listing and advert pages that a logged-out visitor's browser receives.

  • 🚗 Nine vehicle categories: cars, vans, trucks, motorcycles & quads, trailers, campers, construction machinery, agricultural machinery, and parts
  • 🛡️ Nine provenance/paperwork filters applied by Otomoto itself, before a detail page is ever fetched
  • 🚫 A local, Polish-diacritic-insensitive word screen over the ad text for anything Otomoto has no checkbox for
  • 👤 The seller/dealer block and dealer packages on every advert
  • 🧾 VAT invoice and VAT margin invoice flags for business buyers who need to reclaim tax
  • 🔗 A Start URLs mode that reads specific listing or advert URLs directly, bypassing the search filters
  • ⚙️ Automatic proxy escalation (none → datacenter → residential) only if Otomoto actually blocks a request

⚡ Features & Capabilities

Everything below groups into what the actor scrapes, how it is structured, and how it protects you from a silently wrong result.

Core features

  • Full advert record per rowid, title, price, priceList, images, mainFeatures, description, equipment, details, parametersDict, category, seller, packages, createdAt, updatedAt and more, copied from Otomoto's own detail-page payload.
  • Search-side provenance screeningdamageStatus, accidentFreeOnly, serviceHistoryOnly, vatInvoiceOnly, vatMarginOnly, firstOwnerOnly, registeredInPolandOnly, hasVinOnly and countryOfOrigin are all turned into Otomoto's own search[filter_enum_*] query parameters, so a non-matching advert is filtered out by Otomoto before this actor spends a request fetching it.
  • Per-row screen verification — Otomoto's appliedFilters echo is not trusted on its own (a made-up filter name is echoed back too). Every returned advert is checked row by row against the filters you asked for; a violation is never charged and fails the run loudly instead of silently shipping a bad row.
  • Flat, null-honest provenance columnsisAccidentFree, isDamaged, hasVatInvoice, hasVatMarginInvoice, isFirstOwner, hasServiceHistory, isRegisteredInPoland, isImported, countryOfOrigin, countryOfOriginLabel, hasVin. A missing flag is null ("the seller did not answer"), never false ("the seller said no").
  • Local word screenexcludeKeywords drops adverts whose title, description or equipment list contains a banned substring, after diacritics are folded on both sides. Dropped adverts are never hidden: they are pushed as a free, uncharged type="excluded" row naming the exact keyword that matched.
  • Accounting rows for dead adverts — a sold or removed advert produces a free, uncharged type="unavailable" row with the HTTP status and reason instead of silently vanishing from the result.

Why do developers and data teams scrape Otomoto.pl?

🏢 Automotive dealers, remarketing and procurement teams

A dealer building a sourcing shortlist runs a search with accidentFreeOnly, serviceHistoryOnly and vatInvoiceOnly set, gets back price, hasVatInvoice, hasServiceHistory and seller on every matching car, and loads the result straight into a buying spreadsheet or a fleet-procurement tool — without opening a single advert by hand to check whether the seller actually ticked the accident-free box.

📊 AI training data and RAG indexing

description, equipment, mainFeatures and parametersDict are the high-information text and structured-attribute fields for this platform — description for free-text RAG chunks about a specific car, parametersDict for the same structured spec set (make, model, year, engine, mileage) across every row for training data. Two uses: (1) RAG enrichment — a car-buying assistant can answer "does this listing have a documented service history" straight from hasServiceHistory without another fetch; (2) training data — the provenance flags and parametersDict values are typed primitives with a consistent shape across every advert in a category.

📱 Competitive and market intelligence

Track price and priceDrop across repeated runs on the same query/category to see how a brand or model is priced and how fast prices move; track createdAt and updatedAt to see how quickly a dealer's stock turns over. provenanceFiltersApplied.advertsBeforeScreen vs advertsAfterScreen in every run's rows also shows how large the accident-free, documented-history share of a given market segment actually is.

🔬 Research and academic use

Otomoto's own filters give a direct, reproducible way to measure things like the accident-free or VAT-invoice share of the Polish used-car market by brand, price band or region — all from publicly accessible listings, with no login and no private data involved in the vehicle records themselves.

🎥 Product and SaaS development

The hasVin flag (without the VIN itself — see Limitations) is a natural trigger for a "run a vehicle history check" upsell inside a car-shopping app; the flat provenance columns are ready-made filters for a search UI or a price-alert tool built on top of scheduled runs of this actor.


🍚 Input Parameters

None of the 22 parameters are required — an empty input runs a default search for the first 10 cars category adverts that are accident-free and have documented service history.

ParameterRequiredTypeDescriptionExample Value
startUrlsNoarrayFull Otomoto.pl URLs — listing pages or individual advert pages. Non-empty, this OVERRIDES every search filter below, including the provenance screen (provenance columns are still filled in from the advert itself; the word screen still runs). A sold/removed advert produces a free, uncharged row instead of vanishing. Default [].["https://www.otomoto.pl/osobowe/volvo"]
categoryNostringOtomoto section to search. Enum: cars, vans, trucks, motorcycles, trailers, campers, construction, agricultural, parts. The provenance filters are car-market filters and return nothing on parts. Default "cars"."cars"
queryNostringBrand, or brand plus model separated by a space, using Otomoto's own Polish model name. An unrecognised brand or model fails the run rather than silently returning the whole catalogue. Default ""."bmw seria 3"
locationNostringA Polish town or voivodeship, Polish characters handled. An unresolvable name fails the run rather than silently returning national results. Default ""."Warszawa"
sortNostringEnum: relevance_web, created_at:desc, created_at:asc, price:asc, price:desc, year:desc, year:asc, filter_float_price:asc, filter_float_price:desc, filter_float_mileage:asc, created_at_first:desc. Several values are remapped or applied client-side over the rows this run collected — see Limitations. Default "relevance_web"."filter_float_price:asc"
minPriceNointegerMinimum advert price in PLN. Minimum 0. No default (omitted from the search when unset).20000
maxPriceNointegerMaximum advert price in PLN. Minimum 0. No default.80000
minProductionYearNointegerEarliest production year. Minimum 1900, maximum 2030. No default.2015
maxProductionYearNointegerLatest production year. Minimum 1900, maximum 2030. No default.2022
maxItemsNointegerHard cap on how many adverts are scraped and charged. Free rows (removed adverts, word-screen exclusions) never count against it. Minimum 1, maximum 100000. Default 10.200
damageStatusNostringOtomoto's own damage checkbox. Enum: exclude (default), any, only. Measured on /osobowe/bmw, 2026-08-03, baseline 19,594 adverts: exclude → 15,934, only → 1,008, any → 19,594."exclude"
accidentFreeOnlyNobooleanKeep only adverts the seller declared accident-free. Measured: 10,420 of 19,594. Default true.true
serviceHistoryOnlyNobooleanKeep only adverts with a documented service record. Measured: 8,405 of 19,594. Default true.true
vatInvoiceOnlyNobooleanKeep only cars sold with a VAT invoice. Measured: 4,451 of 19,594. Default false.true
vatMarginOnlyNobooleanKeep only cars sold on a margin-scheme invoice (VAT generally cannot be reclaimed on these). Measured: 1,607 of 19,594. Default false.false
firstOwnerOnlyNobooleanKeep only cars still owned by their first owner. Measured: 4,746 of 19,594. Otomoto publishes no owner-COUNT filter or field, so this checkbox is the closest available proxy. Default false.false
registeredInPolandOnlyNobooleanKeep only cars already registered in Poland, dropping fresh unregistered imports. Measured: 10,251 of 19,594. Default false.true
hasVinOnlyNobooleanKeep only adverts where the seller published a VIN. Measured: 17,737 of 19,594. Does not return the VIN itself — see Limitations. Default false.false
countryOfOriginNostringKeep only cars Otomoto records as originating from this country. 31 codes plus "" for any country, each verified live against a non-zero advert count (e.g. d → Germany, measured 3,440 of 19,594 on /osobowe/bmw). Default ""."d"
excludeKeywordsNoarrayCase- and Polish-diacritic-insensitive substring match over the advert title, description and equipment list. Matched adverts are pushed as a free, uncharged type="excluded" row. Default [].["powypadkowy", "sprowadzony"]
concurrencyNointegerHow many Otomoto pages are fetched in parallel. Minimum 1, maximum 20 (values above 20 are silently clamped). Default 10.10
requestDelayNointegerExtra pause before each request, in seconds, plus a small random jitter. Minimum 0, maximum 30. Default 0.0
proxyConfigurationNoobjectApify Proxy settings. Default {"useApifyProxy": false} — Otomoto answers Apify's datacenter exit directly, so no proxy is used unless you request one or the actor is genuinely blocked (see Limitations).{"useApifyProxy": false}

JSON input example

{
"startUrls": [],
"category": "cars",
"query": "bmw seria 3",
"location": "Warszawa",
"sort": "filter_float_price:asc",
"minPrice": 20000,
"maxPrice": 80000,
"minProductionYear": 2015,
"maxProductionYear": 2022,
"maxItems": 200,
"damageStatus": "exclude",
"accidentFreeOnly": true,
"serviceHistoryOnly": true,
"vatInvoiceOnly": true,
"vatMarginOnly": false,
"firstOwnerOnly": false,
"registeredInPolandOnly": true,
"hasVinOnly": false,
"countryOfOrigin": "",
"excludeKeywords": ["powypadkowy", "sprowadzony"],
"concurrency": 10,
"requestDelay": 0,
"proxyConfiguration": { "useApifyProxy": false }
}

Supported URL types and input formats

  • Listing pagehttps://www.otomoto.pl/osobowe/volvo. Accepted as a startUrls entry; the actor paginates it exactly as it would a search built from category/query.
  • Model-narrowed listing pagehttps://www.otomoto.pl/osobowe/bmw/seria-3, equivalent to category: "cars", query: "bmw seria 3".
  • Individual advert pagehttps://www.otomoto.pl/osobowe/oferta/volvo-xc-40-ID6IbdLC.html, matched by the pattern /oferta/<slug>-ID<id>.html. Used directly as a startUrls entry to re-check one specific car; the provenance columns are still filled in, but the provenance screen inputs (accidentFreeOnly etc.) do not apply because Start URLs bypass every search filter.

📦 Output Format

Every run writes one row per advert to the Apify dataset as typed JSON. Three type values exist: "advert" (a fully scraped, screen-passing car — the only type charged via the row_result pay-per-event), "excluded" (dropped by the excludeKeywords word screen, free), and "unavailable" (removed or sold before it could be read, free). To pull only the billed rows from the dataset, filter on type == "advert"; the free rows stay in the dataset as an audit trail rather than disappearing.

Every run's dataset can also be exported as JSON, CSV, Excel, XML or RSS directly from the Apify Console or the Apify API — a feature of every Apify dataset, not something specific to this actor.

Output for a vehicle advert (type="advert", charged)

{
"id": 6109876543,
"type": "advert",
"status": "active",
"title": "Volvo XC40 T5 Momentum AWD",
"url": "https://www.otomoto.pl/osobowe/oferta/volvo-xc40-t5-momentum-awd-ID6IbdLC.html",
"sourceUrl": "https://www.otomoto.pl/osobowe/oferta/volvo-xc40-t5-momentum-awd-ID6IbdLC.html",
"price": 129900,
"priceList": {
"value": "129900",
"currency": "PLN",
"labels": ["Faktura VAT"],
"isUnderBudget": false
},
"primaryImageUrl": "https://ireland.apollo.olxcdn.com/v1/files/example-primary.jpg",
"images": [
"https://ireland.apollo.olxcdn.com/v1/files/example-primary.jpg",
"https://ireland.apollo.olxcdn.com/v1/files/example-2.jpg"
],
"createdAt": "2026-07-28T10:15:00Z",
"originalCreatedAt": "2026-07-20T09:00:00Z",
"updatedAt": "2026-08-02T14:30:00Z",
"mainFeatures": ["2020", "45 000 km", "Diesel", "Automatyczna"],
"badges": ["LOW_MILEAGE"],
"description": "Sprzedaje Volvo XC40 w idealnym stanie, serwisowane w ASO.",
"isParts": false,
"isUsedCar": true,
"verifiedCar": true,
"seller": { "...": "Otomoto's own seller object for this advert, unchanged except the internal `benefits` dealer-entitlement list, which is stripped" },
"packages": { "...": "dealer package/campaign data exactly as Otomoto publishes it, if any" },
"equipment": { "...": "the equipment groups exactly as Otomoto publishes them" },
"details": [
{ "key": "make", "value": "Volvo" },
{ "key": "model", "value": "XC40" },
{ "key": "year", "value": "2020" }
],
"detailsGroups": { "...": "Otomoto's own grouping of the details array" },
"parametersDict": {
"no_accident": { "label": "Bezwypadkowy", "values": [{ "value": "1", "label": "Tak" }] },
"vat": { "label": "VAT", "values": [{ "value": "1", "label": "Tak" }] }
},
"category": { "code": "PersonalVehicle", "id": "29", "label": "Osobowe", "uriPath": "osobowe" },
"adFeatures": { "...": "Otomoto's own ad-feature list, if any" },
"valueAddedServices": { "...": "Otomoto's own value-added-service list, if any" },
"priceDrop": null,
"scrapedAt": "2026-08-04T09:12:03Z",
"isAccidentFree": true,
"isDamaged": false,
"hasVatInvoice": true,
"hasVatMarginInvoice": null,
"isFirstOwner": null,
"hasServiceHistory": true,
"isRegisteredInPoland": true,
"isImported": null,
"countryOfOrigin": "d",
"countryOfOriginLabel": "Niemcy",
"hasVin": true,
"excludedByKeyword": null,
"provenanceFiltersApplied": {
"mode": "search",
"screenApplied": true,
"otomotoFilters": {
"search[filter_enum_damaged]": "0",
"search[filter_enum_no_accident]": "1",
"search[filter_enum_service_record]": "1"
},
"otomotoAppliedFilters": ["filter_enum_damaged", "filter_enum_no_accident", "filter_enum_service_record"],
"advertsBeforeScreen": 19594,
"advertsAfterScreen": 3105,
"excludeKeywords": []
}
}

Fields shown as { "...": "…" } above are opaque pass-through blocks: this actor forwards them exactly as Otomoto currently publishes them on the advert page and does not restructure their internal shape, because that shape is Otomoto's own and not something this actor's source enumerates.

Output for provenance & paperwork flags

These eleven columns are what this variant adds on top of every base advert row, lifted flat out of parametersDict so a shortlist can be sorted and audited without unpacking it per row.

FieldTypeMeaning
isAccidentFreeboolean or nulltrue/false from Otomoto's no_accident flag; null if the seller did not answer
isDamagedboolean or nullFrom Otomoto's damaged flag
hasVatInvoiceboolean or nullFrom parametersDict.vat, corroborated by a "Faktura VAT" label in priceList.labels
hasVatMarginInvoiceboolean or nullFrom Otomoto's vat_discount flag
isFirstOwnerboolean or nullFrom Otomoto's original_owner flag
hasServiceHistoryboolean or nullFrom Otomoto's service_record flag
isRegisteredInPolandboolean or nullFrom Otomoto's registered flag
isImportedboolean or nullFrom Otomoto's is_imported_car flag
countryOfOriginstring or nullOtomoto's own country code, e.g. "d" for Germany
countryOfOriginLabelstring or nullThe Polish label Otomoto shows for that code, e.g. "Niemcy"
hasVinboolean or nullWhether a VIN exists on the advert — not the VIN value itself (see Limitations)

A null on any of these means the seller did not answer that question on the advert form. It is never coerced to false — a procurement shortlist has to be able to tell "unknown" apart from "no."

Schema stability and export options

Field names are stable across runs of this actor and do not change when Otomoto's front end changes its rendering, because every field is read from the same __NEXT_DATA__ JSON payload Otomoto's own React app consumes, not from rendered HTML. If Otomoto ever removes a key this actor currently reads, that field is emitted as null rather than silently dropped from the row, keeping the dataset rectangular across a run. Delivery is the standard Apify dataset: browse it in the Console's table view, pull it with the API or apify_client, or export it as JSON, CSV, Excel, XML or RSS.


💡 Otomoto.pl Scraper — Clean History & VAT Invoice Strategy Guide

🎯 Strategy 1: Real-time enrichment pipeline

Feed a list of specific advert URLs you already track (e.g. from an internal shortlist or a dealer's own stock list) into startUrls. Each run re-fetches the current price, status, isAccidentFree, hasVatInvoice and hasServiceHistory for those exact cars and writes them back to your CRM or spreadsheet, so a listing that sold, changed price, or had a provenance flag change is caught the moment you run it — without re-running a full category search.

🎯 Strategy 2: Scheduled monitoring and alerting

Save a search (category, query, location, plus the provenance toggles you care about) and run it on an Apify Schedule. Diff each run's rows against the previous run on id, price and updatedAt: a new id appearing is a new matching car, a lower price on a known id is a price drop, and a car dropping out of the result entirely is worth checking against the unavailable rows from that run. Otomoto publishes no push feed, so a scheduled poll is the actual mechanism here.

🎯 Strategy 3: Bulk dataset build

Run the actor once per brand or model you need (each within concurrency ≤ 20 and maxItems ≤ 100,000, the actor's own documented ceilings), then aggregate every run's dataset export to a single CSV or database table for market research or model training. Because every row shares the same field set regardless of category, appending multiple runs' exports produces one consistent table without post-processing.

Strategy comparison at a glance

StrategyBest forRun patternOutput format
Real-time enrichmentRefreshing a known shortlist of advertsOn-demand run over startUrlsJSON row per advert, written back to your system
Scheduled monitoringCatching new listings or price/status changesApify Schedule, diffed run-over-runJSON dataset per run, compared on id/price/updatedAt
Bulk dataset buildMarket research or training-data collectionOne run per query/category, aggregated afterwardCSV/JSON export per run, concatenated

How to integrate Otomoto.pl Scraper — Clean History & VAT Invoice with your stack

Otomoto.pl Scraper — Clean History & VAT Invoice works with any language or tool that can make an HTTP request, through the Apify API and the apify_client SDKs.

Python

from apify_client import ApifyClient
import csv
client = ApifyClient("<YOUR_APIFY_API_TOKEN>")
# Replace with this actor's full ID from the Apify Console's Actor Information tab.
actor_id = "otomoto-pl-scraper-clean-history-and-vat-invoice"
run_input = {
"category": "cars",
"query": "volvo xc40",
"accidentFreeOnly": True,
"serviceHistoryOnly": True,
"maxItems": 100,
}
run = client.actor(actor_id).call(run_input=run_input)
rows = []
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item.get("type") == "advert": # skip free excluded/unavailable rows
rows.append(item)
with open("otomoto_adverts.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["id", "title", "price", "isAccidentFree", "hasVatInvoice", "url"])
writer.writeheader()
for row in rows:
writer.writerow({k: row.get(k) for k in writer.fieldnames})
print(f"Wrote {len(rows)} charged adverts to otomoto_adverts.csv")

Node.js

import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "<YOUR_APIFY_API_TOKEN>" });
const actorId = "otomoto-pl-scraper-clean-history-and-vat-invoice";
const run = await client.actor(actorId).call({
category: "cars",
query: "volvo xc40",
accidentFreeOnly: true,
serviceHistoryOnly: true,
maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const paidAdverts = items.filter((row) => row.type === "advert");
console.log(`Fetched ${paidAdverts.length} charged adverts`);
console.log(paidAdverts.slice(0, 3));

Async and scheduled pipelines

For large sweeps, start the run via the API and poll client.run(runId).get() for status: "SUCCEEDED" rather than blocking on .call(), or use an Apify Schedule to trigger the actor on a cron interval and an Apify webhook on ACTOR.RUN.SUCCEEDED to notify your own system when a run's dataset is ready to pull.


🎯 Who Needs Otomoto.pl Scraper — Clean History & VAT Invoice? (Use Cases & Industries)

🏢 Automotive dealers, remarketing and procurement teams

A used-car dealer or fleet buyer sets damageStatus: "exclude", accidentFreeOnly: true and vatInvoiceOnly: true, gets back price, hasVatInvoice, seller and mainFeatures on every matching advert, and imports the result straight into a sourcing spreadsheet — narrowing a market of tens of thousands of listings to a shortlist that already passes the paperwork checks a buyer would otherwise verify by hand.

📊 AI training data and RAG indexing teams

Teams building a car-shopping assistant index description, parametersDict and the flat provenance columns per advert so the assistant can answer "is this car accident-free" or "does it have service history" directly from typed fields instead of asking the model to re-read raw text on every query.

📱 Market intelligence analysts

Analysts running the same search weekly track price, priceDrop and provenanceFiltersApplied.advertsAfterScreen to see how a segment's pricing and the accident-free/VAT-invoice share of the market move over time, without manually re-checking each seller's disclosure.

🔬 Researchers

Academic and market researchers use the provenance screen to measure disclosure rates (accident-free, service history, VAT status) across brands, price bands or regions from publicly accessible listings, with no login and no scope beyond the advert data itself.

🎥 Product and SaaS developers

Developers building a car-search app or a price-alert tool use the flat provenance columns as ready-made filter facets, and the hasVin flag as a trigger to offer a paid vehicle-history-check integration for cars that publish a VIN.


Scraping publicly accessible vehicle adverts from Otomoto.pl is generally lawful; the practical risks are contractual and, narrowly, data-protection related — not criminal.

  • Scraping public data. Otomoto's listing and advert pages are served to any logged-out visitor without authentication, and this actor reads exactly that public payload. It does not bypass a login, paywall or access control.
  • Terms of Service. Like most online marketplaces, Otomoto's own Terms of Service may restrict automated access. Breaching a site's Terms of Service is a contractual matter between the scraper and the site — a civil risk, not a criminal one — and is separate from whether the underlying data is public.
  • Data protection. The vehicle listing data itself (price, specification, provenance flags) describes a car, not a person, and carries no personal-data obligation on its own. The seller object on each advert can be different: for a private-seller advert it may carry that individual's own name, contact details or location, which is personal data under EU/Polish data-protection law (GDPR). Anyone storing or reusing the seller field for a private seller should treat it accordingly.

Otomoto.pl Scraper — Clean History & VAT Invoice returns only publicly accessible data. What you do with that data is your responsibility — consult legal counsel for commercial applications involving personal data.


❓ Frequently asked questions

Does Otomoto.pl Scraper — Clean History & VAT Invoice work without an Otomoto.pl account?

Yes. The actor reads the same public __NEXT_DATA__ payload a logged-out browser receives on Otomoto's listing and advert pages; no Otomoto account, login or cookie is used or required.

How does it handle Otomoto's anti-scraping measures?

It classifies every response by whether the page's own expected data container actually parses out of it, rather than by loose keyword matching, and starts every run with no proxy at all — Otomoto answers Apify's datacenter exit directly. If a request is genuinely blocked, it retries up to three times per URL, then escalates the proxy tier from none to datacenter to residential; a removed advert (HTTP 410/404) is recognised as "gone," not a block, so it never burns a retry or triggers an escalation.

Can I run it at scale without getting blocked?

The actor supports up to 20 parallel requests (concurrency) and up to 100,000 items per run (maxItems), both hard-clamped in code. No uptime or success-rate figure is published for scraping at that scale — the proxy escalation described above is the actor's real defence, not a guaranteed outcome.

How fresh is the data Otomoto.pl Scraper returns?

Every run fetches Otomoto's listing and advert pages live at run time; nothing is cached or served from a previous run. Each row carries its own scrapedAt timestamp.

Which Otomoto.pl fields work best for AI training and RAG indexing?

For RAG, description is the free-text field with the most information per advert. For training data, parametersDict and the eleven flat provenance columns (isAccidentFree, hasVatInvoice, hasServiceHistory, etc.) have the most consistent structure across every advert in a category. All of them return as typed primitives — strings, booleans or null — requiring no normalization before use.

Does hasVinOnly return the actual VIN?

No. Otomoto serves the VIN itself as an encrypted token behind a reCAPTCHA, so this actor only reports whether a VIN exists (hasVin: true/false/null), not its value. Use it to identify which adverts make an external vehicle-history check possible.

What happens if Otomoto doesn't recognise my brand, model or location?

The run fails loudly and names the exact word it rejected, rather than silently returning Otomoto's entire unfiltered catalogue. Otomoto answers an unknown brand, model or town with HTTP 200 and the whole category's ads, so this actor checks the response against what you actually asked for and stops rather than shipping a mislabelled result.

Why is a provenance flag sometimes null instead of false?

Because a missing answer and a "no" answer are different facts. Otomoto's own advert form leaves several of these questions optional — measured on 40 live BMW adverts, vat was absent on 25 of 40 — so this actor returns null for "the seller did not answer" and reserves false for an explicit "no" from Otomoto.

Does Otomoto.pl Scraper — Clean History & VAT Invoice work with Claude, ChatGPT and other AI agent tools?

It is callable as an HTTP endpoint through the Apify API by any agent framework that can make a request and read JSON — every response is typed JSON with no HTML to parse before it enters an LLM's context window. No dedicated MCP server integration is documented for this actor.

Can I combine the provenance screen with Start URLs?

No — Start URLs override every search filter, including the provenance screen, exactly as the actor documents. The provenance columns are still filled in on each returned row from the advert's own data, and excludeKeywords still runs, but damageStatus, accidentFreeOnly and the other search-side toggles have no effect on a Start URL run.


ℹ️ Disclaimer

Otomoto.pl Scraper — Clean History & VAT Invoice extracts only publicly available vehicle-advert data from Otomoto.pl. This tool is intended for lawful use cases only. Users are responsible for complying with Otomoto.pl's terms of service and applicable data protection laws in their jurisdiction, particularly when storing or reusing the seller field from adverts posted by private individuals.