Otomoto.pl Scraper With Dealer Contact Leads avatar

Otomoto.pl Scraper With Dealer Contact Leads

Pricing

from $2.99 / 1,000 results

Go to Apify Store
Otomoto.pl Scraper With Dealer Contact Leads

Otomoto.pl Scraper With Dealer Contact Leads

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

Pricing

from $2.99 / 1,000 results

Rating

0.0

(0)

Developer

SimpleAPI

SimpleAPI

Maintained by Community

Actor stats

1

Bookmarked

1

Total users

1

Monthly active users

2 days ago

Last modified

Share

Otomoto.pl Scraper — Adverts, Prices and Dealer Contact Leads

Otomoto.pl Scraper With Dealer Contact Leads pulls vehicle adverts from Poland's Otomoto.pl marketplace and attaches the seller behind each one: plaintext phone numbers, dealership name, address, storefront URL, live stock count, working hours and badges. Every row carries id, title, price, mainFeatures, seller, sellerContacts, hasPhone and scrapedAt as structured JSON. Car dealerships building call lists, lead-gen agencies, and market analysts tracking price and stock movement use it to turn a category or brand search into a ready-to-dial dataset. Point it at a category, a brand, or a list of URLs, and it returns clean, typed rows with no manual copy-paste.

What is Otomoto.pl Scraper With Dealer Contact Leads?

It is an Apify Actor that scrapes Otomoto.pl vehicle listing pages and individual advert pages, then resolves each advert's published phone number(s) through Otomoto's own contact endpoint. No Otomoto account, login, or API key is required — the Actor reads only what the public advert page and Otomoto's own keyless phone endpoint publish.

Key features:

  • 🔎 Discovery by category, brand, location, price, and year — or paste specific Otomoto listing/advert URLs directly, bypassing search entirely
  • ☎️ Plaintext seller phone numbers — resolved live per advert, not looked up or guessed
  • 🏢 Server-side dealer / private splitsellerType shrinks the run before a single advert page is fetched, not after
  • 📇 Full seller outreach record — dealership name, address, storefront URL, live stock count, working hours, and platform badges, all already present on the advert page
  • 🧮 One row per advert or one row per seller — collapse every listing from the same business into a single lead
  • 📤 Structured JSON output — export to CSV, Excel, JSON, or push straight into a CRM via the Apify API

What data can I extract with Otomoto.pl Scraper With Dealer Contact Leads?

Every advert row carries the vehicle listing fields plus the seller's outreach record, using the exact key names the Actor writes to the dataset.

FieldExample valueUse case
id6149626356Unique advert identifier, dedupe key
type"advert"Row kind — "advert" (charged) or "unavailable" (free)
title"BMW X5 3.0d xDrive M Sport"Listing title
url"https://www.otomoto.pl/osobowe/oferta/bmw-x5-ID6IbcJS.html"Canonical advert URL
price189900Integer price coercion
priceList{ "value": "189900", "currency": "PLN" }Otomoto's own price object (string value preserved)
mainFeatures["2019", "89 000 km", "Diesel"]Headline specs shown on the listing
isUsedCartrueNew vs. used flag
verifiedCartrueOtomoto's verification badge
createdAt / updatedAt"2026-07-28T09:12:00Z"Publish and last-edit timestamps
seller{ "id": 15244680, "name": "Auto Studio Kraków", "type": "PROFESSIONAL", ... }Raw seller block from the advert page
sellerContactssee belowBuilt outreach record
hasPhonetruetrue/false only once the phone endpoint has answered; null if not attempted
equipment / details / detailsGroups / parametersDictarrays / objectsFull spec sheet as Otomoto structures it
category{ "code": "PersonalVehicles", "label": "Osobowe" }Section the advert sits in
scrapedAt"2026-08-04T10:03:11Z"Run timestamp

📇 Seller contact leads

sellerContacts is the field that turns a car list into a call list. It is built entirely from data already present on the advert page plus phone numbers walked from Otomoto's own contact endpoint — no third-party lookup, no email guessing. It carries sellerId, sellerType (PROFESSIONAL/PRIVATE), isBusiness, dealerName, phones (array, up to 5 resolved per advert), phoneCount, storefrontUrl, website, addressLine, city, postcode, region, regionSlug, latitude/longitude, listedVehicleCount (the seller's live stock count), workingHours, sellerBadges, and onOtomotoSinceLabel. A sales team can filter on hasPhone and sort dealers by listedVehicleCount to prioritize outreach to high-volume sellers first.

🎯 Targeting data

The fields you filter and segment on are category (section), price/priceList, the production year read from parametersDict, seller.type (dealer vs. private), and sellerContacts.city/region for geographic segmentation. Combined with the input-side sellerType, minPrice/maxPrice, and minProductionYear/maxProductionYear filters, these let you narrow a national category down to a specific brand, price band, region, and seller type before a single row is charged.

How does Otomoto.pl Scraper With Dealer Contact Leads differ from the official Otomoto API?

Otomoto does publish an API, but it is not a public search/read API: its own FAQ states integration is restricted to business clients ("Z integracji API mogą korzystać wyłącznie Klienci biznesowi Otomoto") and requires an API partner-account registration (checked on otomoto.pl/news/faq-api, 2026-08-04). It is built for a dealer to post, manage, and deactivate their own listings — not to search or read other sellers' adverts, and it does not expose a competitor's phone number or contact record. There is no self-serve endpoint for "give me every BMW listing in Kraków with seller contacts."

Why not build this yourself?

Building an equivalent scraper means solving problems this Actor already handles: Otomoto's category slugs move over time (five of the original section paths now 404 and redirect to different slugs), a single-word brand+model query silently returns the entire unfiltered catalogue instead of erroring, sort keys are silently ignored when unrecognized, and a removed advert answers with a valid-looking page that has to be told apart from a genuine block. Add proxy escalation logic, and a bespoke build turns into an ongoing maintenance job. This Actor absorbs that: it validates that Otomoto actually applied the filters requested and fails loudly instead of silently returning the wrong result set, and it starts with no proxy at all, escalating to datacenter and then residential only if it is genuinely blocked.

Use the official API when you manage your own dealer inventory on Otomoto. Use this Actor when you need to read and export other sellers' adverts and contact data at scale.

How to use data extracted from Otomoto.pl?

🏢 Car dealerships and sales teams

Search a brand and region with sellerType: "private" and withPhoneOnly: true to build a call list of individual sellers who might trade in toward a dealer purchase, or run sellerType: "dealer" against a competing region to see what rival lots are stocking and at what price. The sellerContacts.phones, dealerName, and city fields go straight into a dialer or CRM import; hasPhone filters out dead lines before the file ever reaches a rep.

📊 Agencies and lead-generation services

Run the same search on a recurring schedule (Apify Schedules) for multiple clients, using oneRowPerSeller: true to collapse each dealer's full inventory into one row with sellerAdCount and sellerAdIds, so a client-facing report shows "47 dealers with X active listings" rather than raw advert counts.

🔬 Market research and price intelligence

Sweep a category with minPrice/maxPrice and minProductionYear/maxProductionYear bands to build a price distribution by year and mileage (from parametersDict), or compare sellerType: "dealer" vs. "private" volume in a region — the actual search[private_business] split Otomoto applies (measured on /osobowe/bmw: 8,229 dealer vs. 11,372 private adverts out of 19,601 unfiltered, 2026-08-03) to model where private-party supply outweighs dealer stock.

🤖 AI agents and automated pipelines

Because the Actor returns typed JSON with a stable schema, it slots into an agent tool call or RAG pipeline as a "search Otomoto for X, return sellers with phones" function — the agent supplies category, query, and sellerType, and gets back a rectangular dataset it can filter on hasPhone without further parsing.

🔼 Input sample

ParameterRequiredTypeDescriptionExample value
extractSellerContactsNobooleanResolve phone numbers and build the seller outreach record. Default true. When false, sellerContacts, hasPhone, and sellerContactsFetched are all null.true
sellerTypeNostring (enum: dealer, private, any)Applied server-side before any advert page is fetched. Default "dealer". Ignored when startUrls is non-empty."dealer"
withPhoneOnlyNobooleanDrop advert rows where no phone number could be read. Default false. Requires extractSellerContacts: true.false
oneRowPerSellerNobooleanCollapse every advert from the same seller into one row plus sellerAdIds/sellerAdCount. Default false.false
startUrlsNoarrayFull Otomoto.pl listing or advert page URLs. Overrides every search filter below, including sellerType. Default [].[]
categoryNostring (enum, 9 values)Otomoto section: cars, vans, trucks, motorcycles, trailers, campers, construction, agricultural, parts. Default "cars"."cars"
queryNostringBrand, or brand plus model, space-separated. Default ""."bmw seria 3"
locationNostringPolish town or voivodeship. Default "" (whole country)."Kraków"
sortNostring (enum, 11 values)Result order. Default "relevance_web"."created_at:desc"
minPriceNointeger, minimum 0Minimum price in PLN.20000
maxPriceNointeger, minimum 0Maximum price in PLN.90000
minProductionYearNointeger, min 1900, max 2030Earliest production year.2018
maxProductionYearNointeger, min 1900, max 2030Latest production year.2023
maxItemsNointeger, min 1, max 100000Hard cap on advert detail pages fetched. Default 10.200
concurrencyNointeger, min 1, max 20Parallel requests (advert pages and phone lookups). Default 10.10
requestDelayNointeger, min 0, max 30Extra pause per request, in seconds, plus jitter. Default 0.0
proxyConfigurationNoobjectApify Proxy settings. Default {"useApifyProxy": false}.{"useApifyProxy": false}

No input is required — every parameter has a default, and an empty run scrapes the first 10 car adverts by relevance.

{
"extractSellerContacts": true,
"sellerType": "dealer",
"withPhoneOnly": false,
"oneRowPerSeller": false,
"startUrls": [],
"category": "cars",
"query": "bmw seria 3",
"location": "Kraków",
"sort": "created_at:desc",
"minPrice": 20000,
"maxPrice": 90000,
"minProductionYear": 2018,
"maxProductionYear": 2023,
"maxItems": 200,
"concurrency": 10,
"requestDelay": 0,
"proxyConfiguration": { "useApifyProxy": false }
}

⚠️ Common pitfall: query must be space-separated ("bmw seria 3"), not a single hyphenated word ("bmw-seria-3"). A multi-word query becomes two path segments on Otomoto (/osobowe/bmw/seria-3); a single hyphenated blob is read by Otomoto as one unrecognized token and would silently widen the search to the entire unfiltered catalogue. This Actor checks Otomoto's own applied-filters response and fails the run with the exact rejected word instead of returning an unfiltered result set labeled as your search.

🔽 Output sample

The dataset is typed, normalized JSON with a stable schema across every row — export to CSV, Excel, JSON, or XML directly from the Apify Console, or pull it via the API/apify_client.

{
"id": 6149626356,
"type": "advert",
"status": "active",
"title": "BMW X5 3.0d xDrive M Sport",
"url": "https://www.otomoto.pl/osobowe/oferta/bmw-x5-ID6IbcJS.html",
"sourceUrl": "https://www.otomoto.pl/osobowe/oferta/bmw-x5-ID6IbcJS.html",
"price": 189900,
"priceList": {
"value": "189900",
"currency": "PLN",
"labels": ["Faktura VAT"],
"isUnderBudget": false
},
"primaryImageUrl": "https://ireland.apollo.olxcdn.com/v1/files/example.webp",
"images": ["https://ireland.apollo.olxcdn.com/v1/files/example.webp"],
"createdAt": "2026-07-28T09:12:00Z",
"originalCreatedAt": "2026-07-20T14:03:00Z",
"updatedAt": "2026-08-01T11:45:00Z",
"mainFeatures": ["2019", "89 000 km", "Diesel", "Automatyczna"],
"badges": ["LOW_MILEAGE"],
"description": "BMW X5 3.0d xDrive M Sport, bezwypadkowy, serwisowany w ASO...",
"isParts": false,
"isUsedCar": true,
"verifiedCar": true,
"seller": {
"id": 15244680,
"name": "Auto Studio Kraków",
"type": "PROFESSIONAL",
"location": {
"address": "ul. Wielicka 12",
"city": "Kraków",
"postalCode": "30-552",
"region": "Małopolskie"
},
"sellerUrl": "https://www.otomoto.pl/osobowa/auto-studio-krakow",
"numberOfActiveAds": 47
},
"packages": ["EXTENDED", "TOP"],
"equipment": [{ "code": "air-conditioning", "values": ["automatic"] }],
"details": [{ "key": "year", "value": "2019" }],
"detailsGroups": [{ "code": "general", "items": ["year", "mileage"] }],
"parametersDict": { "year": { "value": "2019" }, "mileage": { "value": "89000" } },
"category": { "code": "PersonalVehicles", "id": "29", "label": "Osobowe", "uriPath": "osobowe" },
"adFeatures": ["highlighted"],
"valueAddedServices": [],
"priceDrop": null,
"scrapedAt": "2026-08-04T10:03:11Z",
"sellerContacts": {
"sellerId": "15244680",
"sellerType": "PROFESSIONAL",
"isBusiness": true,
"dealerName": "Auto Studio Kraków",
"phones": ["12 345 67 89", "600 123 456"],
"phoneCount": 2,
"storefrontUrl": "https://www.otomoto.pl/osobowa/auto-studio-krakow",
"website": "https://autostudiokrakow.pl",
"addressLine": "ul. Wielicka 12",
"city": "Kraków",
"postcode": "30-552",
"region": "Małopolskie",
"regionSlug": "malopolskie",
"latitude": 50.0247,
"longitude": 19.9645,
"listedVehicleCount": 47,
"workingHours": { "mon-fri": "9:00-17:00" },
"sellerBadges": ["registration-date"],
"onOtomotoSinceLabel": "Sprzedający na OTOMOTO od 2015"
},
"hasPhone": true,
"sellerContactsFetched": true
}

An advert that was sold or removed before it could be read is pushed as a free, uncharged row instead: type: "unavailable", sourceUrl, httpStatus, unavailableReason: "advert_removed_or_expired", with every contact field null. In oneRowPerSeller mode, the surviving row additionally carries sellerAdIds (all advert IDs merged into it) and sellerAdCount.

How do you filter and target specific adverts?

Category vs. free-text query. category picks the Otomoto section (cars, vans, trucks, motorcycles, trailers, campers, construction, agricultural, parts); query narrows inside it to a brand or brand-plus-model. Use category alone to sweep a whole section, add query when you know the brand.

Scope precision. location (a Polish town or voivodeship — a town uses Otomoto's own catchment radius, a voivodeship is an exact administrative match), minPrice/maxPrice (PLN), and minProductionYear/maxProductionYear narrow the result set before any advert page is fetched.

Quality thresholds. sellerType (dealer/private/any) is applied server-side via Otomoto's own search[private_business] parameter, shrinking the run before a single detail page loads; every returned advert is then re-checked row by row. withPhoneOnly drops rows where no phone number could be resolved.

Volume controls. maxItems (1–100,000, default 10) caps how many advert detail pages are fetched — in oneRowPerSeller mode the dataset can hold fewer rows than this (adverts collapse into sellers) but never more. concurrency (1–20) and requestDelay (0–30s) tune request pacing.

{ "category": "cars", "query": "bmw x5", "location": "Kraków", "sellerType": "dealer", "minProductionYear": 2019, "sort": "created_at:desc", "maxItems": 200 }
{ "category": "cars", "query": "volvo", "sellerType": "private", "withPhoneOnly": true, "oneRowPerSeller": true, "maxItems": 500 }
{ "startUrls": ["https://www.otomoto.pl/dostawcze/kamper", "https://www.otomoto.pl/osobowe/oferta/bmw-x5-ID6IbcJS.html"], "extractSellerContacts": true }

▶️ Want to try other Otomoto scrapers?

This is currently the only Otomoto.pl Actor in the SimpleAPI catalog. If your workflow needs contact-lead extraction from a different platform, these SimpleAPI scrapers cover a similar ground:

ScraperWhat it extracts
Google Maps Extractor with Reservation/Order Online LinksGoogle Maps business listings plus the online booking platform (OpenTable, Resy, SevenRooms, and others) each venue runs on
Facebook Group Posts And Details & Contact Leads ScraperFacebook group posts, group profile data, and email/phone mentions typed by members themselves
Pinterest Profile Scraper With Email & Website ContactsPublic Pinterest profile bios plus emails, phone numbers, and social handles from the linked website
TikTok Shop Data Scraper: Reviews & Sentiment AnalysisTikTok Shop products, reviews, and reviewer trust signals by keyword, category, or seller store

How to extract Otomoto.pl data programmatically

Every run is a standard Apify Actor call: one API call with your Apify token, a JSON input body, and structured JSON back — no separate Otomoto credentials required.

Python example

from apify_client import ApifyClient
client = ApifyClient("<APIFY_API_TOKEN>")
run = client.actor("SimpleAPI/otomoto-pl-scraper-with-dealer-contact-leads").call(
run_input={
"category": "cars",
"query": "bmw seria 3",
"location": "Kraków",
"sellerType": "dealer",
"withPhoneOnly": True,
"maxItems": 100,
}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
contacts = item.get("sellerContacts") or {}
print(item["title"], item["price"], contacts.get("phones"))

Export to spreadsheets or CRM

From the Apify Console, use the dataset's Export button to download CSV or Excel directly, or select the ☎️ Adverts + seller contacts view for a flattened table. Map title, price, and the sellerContacts.dealerName/phones/city keys to your CRM's lead columns — hasPhone gives you a ready-made filter for a "call-ready" segment before import.

Scraping publicly accessible Otomoto.pl advert pages is generally lawful — these listings are published specifically to be found and contacted by buyers, and this Actor reads only what a visitor to the public page (and Otomoto's own public contact endpoint) can already see. No login, cookie, or bypass of access controls is used.

The legal framing depends on which rows you collect. With sellerType: "dealer" (the default), output is business/dealership data — dealership name, storefront, and stock count — governed by Otomoto's Terms of Service and database-rights considerations, not personal-data law. With sellerType: "private" or "any", dealerName and phones can identify an individual rather than a business; that output is personal data and falls under GDPR (and CCPA where applicable), which requires a lawful basis for storage and further use. Consult legal counsel for commercial applications involving bulk storage of personal data.

❓ FAQ

Do sold or removed adverts still show up in the results?

Yes, but as a free, uncharged row rather than being silently dropped: type: "unavailable", with httpStatus and unavailableReason: "advert_removed_or_expired". Every contact field on that row is null because nothing was ever fetched for it.

Can I get seller phone numbers along with the advert data?

Yes — it's the Actor's core feature. With extractSellerContacts: true (the default), each advert's published phone numbers are resolved live from Otomoto's own contact endpoint (up to 5 per advert) and attached in sellerContacts.phones, alongside dealership name, address, storefront URL, live stock count, working hours, and badges. hasPhone and sellerContactsFetched tell you whether a number was actually found versus whether the lookup was even attempted.

How accurate is the phone and price data?

The Actor returns data exactly as Otomoto publishes it at request time — the phone number is read live from Otomoto's own endpoint, not guessed or completed from another source, and price/priceList reflect the advert's current listed price. Accuracy depends on the seller keeping the ad updated; re-run periodically if you need current stock and pricing.

How many adverts can I get per run?

maxItems caps the number of advert detail pages fetched, from 1 up to 100,000 (default 10). In oneRowPerSeller mode, the pushed dataset can hold fewer rows than maxItems because multiple adverts collapse into one seller row — it never holds more.

How do I target only dealerships, or only sellers I can actually call?

Use sellerType: "dealer" (or "private") to apply Otomoto's own business/private split server-side, before any advert page is fetched, and add withPhoneOnly: true to drop rows where no phone number could be resolved. Combine both with oneRowPerSeller: true to get one qualified lead per business instead of one row per listing.

Does Otomoto.pl Scraper With Dealer Contact Leads work with Claude, ChatGPT, and AI agent frameworks?

There is no dedicated MCP server for this Actor. It is callable as a standard HTTP endpoint through the Apify API by any agent framework that can make a tool call and read JSON — LangChain, LlamaIndex, or a custom agent loop can all invoke it as a scraping tool.

How does this compare to other Otomoto scrapers?

The distinguishing capability, verifiable from this Actor's own source and input schema, is the combination of plaintext phone-number resolution, the server-side dealer/private split, and the one-row-per-seller collapse in a single run. Check any other Otomoto listing's own documentation for its specific field coverage before comparing on price or speed.

Can I use this without an Otomoto account or API key?

Yes. You need only an Apify account and API token to run it — no Otomoto login, cookie, or API key of any kind is required, since the Actor reads public pages and Otomoto's own keyless contact endpoint.

What happens if my search matches zero adverts?

The run fails with a clear error naming the problem — Otomoto reporting zero total results, or Otomoto not actually applying a filter you asked for (an unrecognized brand, model, or location) — rather than silently returning an empty or wrongly-scoped dataset labeled as a success.

Conclusion

Otomoto.pl Scraper With Dealer Contact Leads turns an Otomoto category or brand search into a structured, contactable dataset: vehicle listing details plus plaintext seller phone numbers, dealership name, address, and live stock count, filterable by dealer/private split and phone availability. It's built for sales teams, lead-gen agencies, and market analysts who need Otomoto data as clean JSON rather than a spreadsheet built by hand. Start a run from the Apify Console or the API with your search filters, or paste Otomoto URLs directly, and open the ☎️ Adverts + seller contacts view when it finishes.