# Blocket Vehicle Listings Scraper (`automation-lab/blocket-sweden-vehicle-listings`) Actor

Export public Blocket car listings with make, model, year, asking price, mileage in kilometers, location, seller context, images and canonical URLs from saved Swedish vehicle searches.

- **URL**: https://apify.com/automation-lab/blocket-sweden-vehicle-listings.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.27 / 1,000 item extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Blocket Vehicle Listings Scraper

Export **blocket vehicle listings** from public Swedish car search pages into structured rows for inventory and asking-price comparisons. Paste the filtered search URL you already use on Blocket, or start with the default used-car search. Each row includes listing identity, make, model, model year, price, mileage, location, public seller context, images, and the canonical listing URL when those values are available.

### Who is it for?

Used-car analysts can compare asking prices for a model and region. Dealers can review competing inventory. Researchers can assemble Swedish automotive samples without manually transcribing search cards. Recurring Apify schedules can collect snapshots for your own downstream comparison pipeline.

### Why use it?

The output keeps stable listing IDs for joining snapshots and removes duplicates across searches in one run. It preserves source mileage and units alongside a kilometer conversion, so Swedish mil are not confused with kilometers. Seller context and image links come from the search response without additional detail-page charges.

This is an independent tool, not affiliated with or endorsed by Blocket. It covers the car search category, which can include transport vehicles. It does not support motorcycles, boats, caravans, property, jobs, or general marketplace searches.

### Getting started

1. Open Blocket's car search and apply your intended filters.
2. Copy the full HTTPS search URL, including its query string.
3. Add it under **Car search URLs**. Alternatively, omit URLs to search used cars with `sales_form=1`.
4. Set **Maximum unique listings** and run the Actor.
5. Inspect the dataset and download JSON, CSV, Excel, or another Apify export format.

### Input parameters

```json
{
  "startUrls": [{"url": "https://www.blocket.se/mobility/search/car?sales_form=1&q=volvo"}],
  "maxItems": 100
}
```

| Parameter | Behavior |
| --- | --- |
| `startUrls` | 1–10 HTTPS `/mobility/search/car` URLs. Optional; omitted URLs use the used-car default. |
| `maxItems` | Global unique-row limit, default 100, range 1–10000. Zero is invalid. |

Entries use **URL only**. Custom `method`, `payload`, `headers`, and `userData` exposed by some clients are ignored; the Actor makes its own GET requests.

A supplied URL replaces the default filters: do not assume every custom search excludes leasing or new cars. `page=1` through `page=50` starts at that source page. Searches run sequentially and share the result limit. Listing URLs and unsupported categories fail validation rather than silently switching scope.

### Filters and matching

Filters embedded in the URL are passed to Blocket. Create them in its search UI rather than guessing parameter values. For example, the source's `q=volvo` search was verified locally with Volvo records. Free-text matching follows Blocket's behavior; this Actor does not implement exact-phrase, whole-word, case-sensitive, or title-only matching.

Native filters may evolve. Inspect a sample before using it for a decision. No undocumented parameter is guaranteed to affect the upstream search. The Actor does not enrich detail URLs or apply a second set of unrelated local filters.

### Extracted data

| Fields | Meaning |
| --- | --- |
| `listingId`, `url`, `title`, `category` | Stable identity, canonical link, heading, and `car` category. |
| `make`, `model`, `modelSpecification`, `year` | Manufacturer, model, trim text, and model year. |
| `price`, `currency`, `priceUnit`, `salesForm` | Advertised amount and native sales-form code. Not a transaction price. |
| `mileage`, `mileageUnit`, `mileageKm` | Original odometer value/unit and conversion when recognized. |
| `fuel`, `transmission` | Source Swedish labels. |
| `location`, `latitude`, `longitude` | Public locality and approximate coordinates. |
| `sellerName`, `sellerId`, `sellerType` | Public organisation context; private sellers may have null names. |
| `images` | Image URLs, not downloaded files. |
| `sourceTimestamp`, `searchUrl`, `scrapedAt` | Source Unix milliseconds, discovery page, and collection time. |

Missing fields are null; missing image collections are empty arrays. Source mistakes are preserved rather than guessed away. A Scandinavian mile is 10 km; unknown units produce a null kilometer conversion. `salesForm=1` denotes used-car sale and `2` new-car sale; other source codes can describe leasing. Do not compare monthly lease amounts with full purchase prices.

### Output example

The normalized shape below follows observed search records; identity and seller values are illustrative.

```json
{
  "listingId": "12345678",
  "url": "https://www.blocket.se/mobility/item/12345678",
  "title": "Volvo XC60",
  "category": "car",
  "make": "Volvo",
  "model": "XC60",
  "year": 2020,
  "price": 249000,
  "currency": "SEK",
  "mileage": 12000,
  "mileageUnit": "SCANDINAVIAN_MILE",
  "mileageKm": 120000,
  "location": "Stockholm",
  "sellerName": "Example dealer",
  "sellerType": "Företag",
  "images": [],
  "scrapedAt": "2026-10-03T00:00:00.000Z"
}
```

### How much does it cost to extract Blocket vehicle listings?

Pay-per-event pricing consists of one `start` event per valid run and one `item` event per delivered unique listing. Duplicate, rejected, and missing records have no item charge. Images and seller context included in a listing have no separate event charge. The start event costs $0.001. Listing prices are FREE $0.002438, BRONZE $0.00212, SILVER $0.0016536, and GOLD/PLATINUM/DIAMOND $0.001272 per listing. At BRONZE, 10 listings cost approximately $0.0222, 100 approximately $0.213, and 1,000 approximately $2.121. At FREE, 100 cost approximately $0.2448. These are Actor event estimates; consult Apify's current pricing panel and account billing for your applicable tier and invoice.

Spend tiers follow your qualifying aggregate monthly Apify Store spend, not a private volume discount in this Actor. Set a maximum charge budget to bound spending. A natural no-result search still incurs the start event. Invalid input is rejected before that event. Failed runs can contain partial rows and their corresponding charges.

### Pagination and limitations

Each search follows Blocket's reported pagination, capped at 50 source pages. The Actor does not partition searches to bypass that cap or promise complete national inventory. It stops at the global result limit, a billing limit, source exhaustion, or an error. Overlapping queries consume no duplicate item charges, but may still require page requests.

Listings can move between pages while the source changes. Deduplication prevents repeated IDs but cannot guarantee a snapshot transaction or perfect coverage. Sponsored placements outside the normal search response are excluded. There are no built-in historical comparisons, sold-status confirmations, valuations, phone lookups, or notifications.

### Integrations

Use Apify schedules for repeat collection, then join runs by `listingId` in your database. Store `scrapedAt` and compare price or mileage columns to identify changes. A record absent from a capped or filtered sample is not proof it was sold.

Send exports to spreadsheets, BI systems, Make, or Zapier for downstream processing; those services may have their own charges.

### API usage

Use your own Apify token securely. The synchronous endpoint is convenient for small runs; larger runs should use the asynchronous run API and retain the returned run ID.

```bash
curl -X POST 'https://api.apify.com/v2/acts/automation-lab~blocket-sweden-vehicle-listings/run-sync-get-dataset-items' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"maxItems":20}'
```

```javascript
const response = await fetch('https://api.apify.com/v2/acts/automation-lab~blocket-sweden-vehicle-listings/run-sync-get-dataset-items', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.APIFY_TOKEN}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ maxItems: 20 }),
});
if (!response.ok) throw new Error(`Apify returned ${response.status}`);
const rows = await response.json();
```

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/blocket-sweden-vehicle-listings').call(run_input={'maxItems': 20})
rows = list(client.dataset(run['defaultDatasetId']).iterate_items())
```

### MCP setup

Claude Code:

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/blocket-sweden-vehicle-listings"
```

Claude Desktop, Cursor, and VS Code can use their supported HTTP MCP configuration with the same scoped URL:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/blocket-sweden-vehicle-listings"
    }
  }
}
```

Authenticate according to your client's Apify configuration. Discover actual tool names with `tools/list`; the scoped endpoint also exposes supporting run/data tools. Discovery is not permission to start a run. Example prompt: “Collect 20 used Volvo listings from my Blocket car search URL and compare asking prices, clearly identifying missing mileage.”

Start an authorized run once and retain its run ID, status and storage IDs; these are metadata, not result rows. `call-actor` supports `waitSecs` 0–45 seconds (default 30). Configure the client's request timeout above the selected wait plus transport margin, within a total 120-second deadline. If still running, inspect that same run with bounded backoff: 2, 4, 8 seconds capped at 10. On client timeout, recover the known run; if its ID is unknown, report uncertainty rather than blindly restart. At the deadline, stop polling and report pending with the run ID. Report terminal failures honestly, with available rows identified as partial.

After success, use `get-dataset-items` with the returned `defaultDatasetId`, `offset=0`, `limit=20`, and a `fields` projection such as `listingId,url,make,model,year,price,currency,mileageKm,location,sellerType,scrapedAt`, following the discovered tool schema. Prefer untransformed JSON (no filtering or unwinding), advance source offsets using pagination metadata, and stop at exhaustion or a total budget of 100 rows or 64 KiB of serialized UTF-8 content across all pages, whichever comes first. Process pages host-side before model injection and omit or summarize oversized rows/pages with disclosure. If the client cannot intercept oversized responses, do not claim a hard byte guarantee. Report returned rows, continuation offset and partial/truncated status. Keep full exports outside model context. These are consumer context limits, not Actor collection limits; discovery transport size is not model-visible context, and client caching or token savings are not guaranteed.

### Legality, data handling and responsible use

No AI model is used in extraction or output. The Actor fetches public Blocket search pages and writes selected public vehicle and seller context to your Apify dataset. It does not retrieve private accounts, messages, phone numbers, or passwords. Public seller context and approximate location can still be personal data: use only for lawful, proportionate purposes, respect source terms, and avoid unsolicited outreach.

Apify hosts processing, output and logs. Dataset retention follows your Apify storage settings; delete unwanted runs/datasets through Apify. This Actor adds no persistent cache, cross-run dataset, or session storage. Normal logs contain counts and page numbers, not listing records or seller identities. No additional paid API, proxy, or external AI account is required by this implementation.

Failed operations send sanitized diagnostic input, exceptions and actor/build/run IDs to our private GlitchTip service for repair; secret fields and URL queries are removed and reports are retained for 30 days. Run storage and diagnostics have separate deletion/retention paths. Contact support for diagnostic deletion requests.

### FAQ and troubleshooting

**Why are there fewer rows than requested?** A search may exhaust, hit the 50-page cap, overlap earlier searches, or reach your charge budget.

The `maxItems` setting is a ceiling, not a guaranteed count.

**Can I supply a listing URL?** No. Use a `/mobility/search/car` URL. Other category and detail routes are rejected.

**Why did the run fail?** Invalid inputs, permanent HTTP errors, a blocked response, or a changed search-state shape fail visibly. Transient network errors, 429 and 5xx responses receive at most three total attempts. No browser or residential proxy fallback is hidden in the price. Inspect the run log; do not treat partial data as complete.

**Does this show sold vehicles or historical prices?** No. It collects current public search records. Maintain your own snapshots and interpret absence cautiously.

### Related Actors and support

For Nordic comparisons, see [FINN.no Multi-Category Listings](https://apify.com/automation-lab/finn-no-multi-category-listings). For other markets, see [AutoTrader Canada Vehicle Listings](https://apify.com/automation-lab/autotrader-ca-listings-scraper) and [Carzone Used Cars](https://apify.com/automation-lab/carzone-ie-used-car-listings-scraper). Their source coverage and schemas differ.

Report problems through the Apify Store issue channel or automation_labs_support@agentmail.to. Include the run link and a non-sensitive search example. Never send account credentials.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/blocket-sweden-vehicle-listings/changelog.md

# Actor input Schema

## `startUrls` (type: `array`):

URL only: custom method, payload, headers and userData are ignored. Provide 1–10 HTTPS Blocket /mobility/search/car URLs, including native category filters such as sales_form, variant, location, year_from or price_to. Filters are passed to Blocket, whose own matching semantics apply; q is not an Actor-side exact phrase or whole-word filter. URLs run sequentially. An optional page=1–50 starts pagination there. Listing/detail URLs and other vehicle categories are rejected. If omitted, searches used cars with sales_form=1; a supplied URL replaces that default and may include new cars or leasing.

## `maxItems` (type: `integer`):

Global maximum number of unique listing IDs saved across all URLs, after deduplication. Default 100; range 1–10000, with no zero/unlimited mode. Stops at this limit, billing budget, search exhaustion or Blocket's maximum of 50 pages per search. This does not guarantee every matching vehicle is available through the source cap.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.blocket.se/mobility/search/car?sales_form=1"
    }
  ],
  "maxItems": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

All collected listing rows.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.blocket.se/mobility/search/car?sales_form=1"
        }
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/blocket-sweden-vehicle-listings").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://www.blocket.se/mobility/search/car?sales_form=1" }],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/blocket-sweden-vehicle-listings").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.blocket.se/mobility/search/car?sales_form=1"
    }
  ],
  "maxItems": 20
}' |
apify call automation-lab/blocket-sweden-vehicle-listings --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/blocket-sweden-vehicle-listings"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/vc4zH1aYKo20ltC80/builds/srLVBMXdPh61UlUtF/openapi.json
