Quick answer: Blocket.se publishes no public car API, so the only way to get structured listings data is to scrape the public site. The Blocket Car Scraper on Apify handles browser fingerprint rotation, residential proxy rotation, Swedish-mil-to-km conversion, and retries for you — delivering clean typed rows at $2.05 per 1,000 results ($0.05 actor-start + $0.002 per result).
Sweden's used-car market is one of the most active in the Nordics. Blocket.se is the dominant classifieds platform in Sweden — tens of thousands of car listings at any moment, spanning everything from a 1999 Volvo V70 at 12,000 SEK to a freshly imported Tesla Model Y at market rate. If you want to track SEK prices by make and model, watch Sweden's fast-moving used-EV segment, or monitor a competitor's dealer inventory, Blocket is the data source you need.
The complication: Blocket.se publishes no public API, and its car search is rendered by a Next.js frontend backed by internal endpoints that resist naive HTTP clients. The site also reports odometer readings in the Swedish mile — mil — where 1 mil equals 10 kilometres, a unit convention that catches most data pipelines off guard the first time.
This guide covers how to pull Blocket.se car data programmatically, using the Blocket Car Scraper — a managed Apify Actor that handles both the anti-blocking layer and the mil-to-km normalisation.
Does Blocket.se Have an API? 🔎
No. Blocket.se is a consumer marketplace — it exposes no documented developer API and no data export for car listings. The site's internal search endpoint feeds the React frontend, but it uses session-based authentication and rate-limits aggressively. Any client you build against it will break without warning when Blocket rotates its internal API version or adds a new challenge layer.
The durable approach is a managed scraper that stays current with site changes, so your pipeline continues working when Blocket updates its frontend.
What Data You Can Extract
The Actor returns one structured row per listing. Fields from the search result card are always present; fields marked "enrichment-only" require enrichDetails: true, which fetches each car's detail page.
| Field | Description |
|---|---|
listing_id |
Blocket ad ID |
listing_url |
Absolute URL to the listing |
title |
Make + model heading |
make |
Manufacturer, e.g. Volvo |
model |
Model, e.g. V70 |
year |
Model year (Modellår) |
price |
Integer price in SEK |
currency |
Always SEK
|
mileage_km |
Odometer in km (converted from Swedish mil) |
fuel_type |
Bensin / Diesel / El, etc. — enrichment-only |
transmission |
Manuell or Automat — enrichment-only |
engine_power_hp |
Metric horsepower (Effekt, Hk) — enrichment-only |
engine_size_cc |
Displacement in cc — enrichment-only |
body_type |
Kombi / Sedan / SUV, etc. — enrichment-only |
color |
Exterior colour (Färg) — enrichment-only |
first_registration |
Registration date YYYY-MM-DD — enrichment-only |
location |
Seller location (Bilens plats) — enrichment-only |
drivetrain |
Framhjulsdrift / Fyrhjulsdrift, etc. — enrichment-only |
num_owners |
Number of previous owners (Antal ägare) — enrichment-only |
seller_type |
dealer (Handlare) or private (Privatperson) |
seller_name |
Dealer trading name — enrichment-only |
photo_urls |
List of photo URLs |
description |
Short trim/equipment line |
posted_date |
Listing publication date |
scraped_at |
ISO-8601 UTC timestamp of scrape |
Note the num_owners field — Blocket surfaces previous-owner count on detail pages, which is genuinely useful for pricing models that discount high-ownership cars.
A Realistic Output Row
Here is a sample result using the exact field names from the Actor's Pydantic ResultRow model:
{
"listing_id": "23740311",
"listing_url": "https://www.blocket.se/mobility/item/23740311",
"title": "Volvo V70",
"make": "Volvo",
"model": "V70",
"year": 2000,
"price": 12000,
"currency": "SEK",
"mileage_km": 238000,
"fuel_type": "Bensin",
"transmission": "Manuell",
"engine_power_hp": 140,
"engine_size_cc": 2400,
"body_type": "Kombi",
"color": "Grå",
"first_registration": "1999-11-04",
"location": "Sverige",
"drivetrain": "Framhjulsdrift",
"num_owners": 4,
"seller_type": "private",
"seller_name": null,
"photo_urls": [
"https://images.blocketcdn.se/dynamic/default/item/23740311/0c453750-654c-488c-878e-7d50af9966be"
],
"description": "2.4 Manuell",
"posted_date": null,
"scraped_at": "2026-06-02T00:00:00+00:00"
}
The mileage_km value of 238,000 came from a listing that showed "23 800 mil" — the Actor converted it. Without that conversion, a pipeline that compares Swedish listings against German or Irish equivalents would see odometer values that are an order of magnitude off.
How We Handle the Blocks
Blocket.se's car search is served by a Next.js frontend that calls internal authenticated endpoints. A plain HTTP client hitting those endpoints gets refused. Here is what the Actor does instead:
-
Browser fingerprint rotation. We use
curl-cffito impersonate real Chrome, Firefox, and Safari TLS handshakes — the complete ClientHello, ALPN extension order, and HTTP/2 SETTINGS frame. The target sees browser traffic, not Python. - Residential proxy rotation via Apify Proxy. We rotate residential exit IPs on every block. Swedish residential exits are preferred for this target.
-
Exponential backoff with Retry-After. We retry on 408, 429, and 5xx — up to five attempts per page, doubling the wait each time and honouring
Retry-Afterheaders. - Rate-limit-aware pacing. When Blocket pushes back, we slow down instead of accelerating into a ban.
- Loud failure, never silent. A hard block produces a non-zero exit and a descriptive status message — never a green run with an empty dataset.
Running It with Python 🐍
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("DevilScrapes/blocket-sweden-cars").call(
run_input={
"query": "volvo v70",
"maxResults": 200,
"enrichDetails": True,
"proxyConfiguration": {
"useApifyProxy": True,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}
)
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(f"Scraped {len(items)} listings")
for item in items[:3]:
print(item["make"], item["model"], item["year"], item["price"], "SEK",
item["mileage_km"], "km")
Three ways to target your search:
-
query— free-text, maps to Blocket'sqparameter (e.g."volvo v70 kombi"). -
make— convenience filter for a single brand (e.g."Volvo"). -
searchUrl— paste a full Blocket search URL with filters already applied. The URL wins if all three are set.
Use Cases
SEK price analytics. Track how asking prices for a make/model/year combo move over time in the Swedish market. Sweden's used-car market is liquid enough that weekly runs produce meaningful price series.
EV market tracking. Filter by fuel_type = El to chart used-EV pricing in Sweden, which is one of Europe's most mature EV markets. The engine_power_hp and year fields let you segment by generation.
Dealer inventory monitoring. Filter by seller_type = dealer and watch stock turnover at specific dealers by seller_name. Diff successive runs to catch new arrivals and price cuts before competitors.
Ownership-based pricing models. The num_owners field is rare in European marketplace scrapers. Build models that discount price by ownership count for a given make/model/mileage bucket.
Cross-Nordic arbitrage. Compare Blocket (SEK) prices against Norwegian Finn.no (NOK) or Danish DBA (DKK) equivalents. The km-normalised mileage_km field makes cross-market comparison straightforward.
FAQ ❓
How much does it cost?
Pay-Per-Event pricing: $0.05 for actor-start (one-off per run) plus $0.002 per result row. 1,000 results costs $2.05 total. Every new Apify account gets $5 of free credit — no credit card required to try.
Why does Blocket show "mil" but the Actor returns "km"?
The Swedish mile (mil) is 10 kilometres — different from the international mile (1.6 km). The Actor converts for you: a listing showing "23 800 mil" becomes 238000 in mileage_km, consistent with every other market in the Devil Scrapes automotive fleet.
Is scraping Blocket.se legal?
Blocket's terms restrict automated data collection. You are responsible for ensuring your use complies with applicable law and the site's terms. The Actor scrapes only public listing data visible to any unauthenticated browser. We do not bypass authentication, access private messages, or scrape seller phone numbers.
How do I get mileage, gearbox, and engine power?
Those fields live on each car's detail page. Keep enrichDetails: true (the default) to fill them in; set it to false to halve the request count and get just make, model, year, price, and photos from the search payload.
Get Started
The Actor is live on the Apify Store. Every new Apify account starts with $5 of free credit — enough for roughly 2,400 enriched listings.
Blocket Car Scraper on Apify Store
Questions or edge cases? Use the Actor's Issues tab on Apify Console. We ship fixes weekly.
Built by Devil Scrapes — a fleet of opinionated public-data Actors. Honest pricing, real engineering, zero fine print.
Top comments (0)