# BOVAG Scraper (`lokki/bovag-scraper`) Actor

Scrapes viaBOVAG vehicle listings from search URLs, friendly filter paths, or explicit search requests.

- **URL**: https://apify.com/lokki/bovag-scraper.md
- **Developed by:** [Ian Dikhtiar](https://apify.com/lokki) (community)
- **Categories:** Automation, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $12.70 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## BOVAG Scraper

Turn viaBOVAG.nl into a clean vehicle data feed. This scraper collects Dutch car listings, dealer details, BOVAG trust signals, pricing, mileage, images, and optional detail-page specs in flat columns that are ready for lead generation, market research, inventory monitoring, and automotive analytics.

In Dutch: haal occasions van viaBOVAG op met prijzen, kilometerstanden, dealerinformatie, garantie-indicatoren en specificaties. Klaar voor Excel, BI dashboards, CRM import, prijsvergelijking en voorraadonderzoek.

### Why This Scraper Is Useful

viaBOVAG is not just another car site. Listings often include the signals buyers actually care about: BOVAG Garantie, onderhoudsvrij rijden, NAP checks, return warranty, dealer contact data, APK and technical specs. This actor turns those signals into structured data instead of making you manually click through listing pages.

Use it to:

- Track used-car supply by make, model, city, dealer, year, price, fuel type, mileage, or warranty status.
- Build dealer lead lists with phone numbers, websites, cities, and live listing URLs.
- Monitor price changes and inventory depth in the Dutch automotive market.
- Compare BOVAG-backed vehicles against other marketplaces.
- Feed car data into Notion, Airtable, Sheets, CRMs, BI tools, or pricing models.
- Enrich automotive content, lead magnets, valuation workflows, or dealership intelligence systems.

### Cool Things It Offers

- Endpoint-based scraping: uses viaBOVAG JSON endpoints, not brittle browser card scraping.
- Flat dataset output: no annoying nested JSON blobs in Apify tables.
- Detail enrichment: optional listing-page fetches add license plate, energy label, APK, registration date, seats, doors, gearbox, and expanded specs.
- BOVAG confidence fields: warranty, return warranty, NAP, maintenance-free, serviced flags, and certainty keys.
- Dealer intelligence: dealer name, city, phone number, website, external ad URL, and listing URL.
- Search flexibility: run broad searches, friendly filtered URLs like /auto/merk-toyota, or raw search request objects.
- Proven live coverage: tested against 100 real viaBOVAG brand inputs with a 100 percent pass rate during validation.

### Wat Krijg Je?

- Auto titel, prijs, merk, model, bouwjaar, kilometerstand, brandstof, transmissie en carrosserie.
- Dealernaam, plaats, telefoonnummer, website en advertentielink.
- BOVAG zekerheden zoals garantie, omruilgarantie, onderhoudsvrij rijden en NAP.
- Optionele technische details zoals kenteken, energielabel, APK, deuren, zitplaatsen en specificaties.
- Platte kolommen die direct bruikbaar zijn in spreadsheets, dashboards en automatiseringen.

### Waarom viaBOVAG Data Waardevol Is

viaBOVAG combineert occasionaanbod met vertrouwen. Voor kopers draait het niet alleen om prijs en kilometerstand, maar ook om zekerheid: BOVAG Garantie, onderhoudshistorie, NAP, omruilgarantie, APK en de betrouwbaarheid van het autobedrijf. Deze scraper zet die signalen om naar gestructureerde data.

Daarmee kun je sneller zien welke occasions interessant zijn, welke dealers actief zijn, welke merken veel voorraad hebben, en waar prijsverschillen ontstaan in de Nederlandse automarkt.

### Nederlandse Use Cases

- Occasion voorraad monitoren per merk, model, bouwjaar, plaats of dealer.
- Dealer leads verzamelen met telefoonnummers, websites en actuele advertenties.
- Tweedehands auto prijzen vergelijken op basis van kilometerstand, bouwjaar en uitvoering.
- BOVAG Garantie en andere zekerheden analyseren per voertuig of dealer.
- Kenteken, APK, energielabel en voertuigspecificaties ophalen voor verrijking.
- Auto data exporteren naar Excel, Google Sheets, CRM, Airtable, Notion of BI dashboards.
- Marktinformatie verzamelen voor autobedrijven, leadgeneratie, SEO-content of prijsmodellen.

### Populaire Nederlandse Zoekopdrachten

Deze actor sluit aan op zoekopdrachten zoals:

- BOVAG scraper
- viaBOVAG scraper
- occasion scraper Nederland
- tweedehands auto data
- BOVAG occasion data
- auto voorraad scraper
- dealer leads Nederland
- kenteken data scraper
- BOVAG garantie occasions
- voertuigspecificaties ophalen
- Nederlandse automarkt data
- auto prijzen vergelijken Nederland

### Flat Output Policy

This actor deliberately pushes flat rows. Apify tables and CSV exports are much more useful when each useful field gets its own column.

- Arrays such as fuelTypes, warranties, and certaintyKeys become readable comma-separated text plus count fields.
- Detail-page specification groups become named spec columns such as spec_algemeen_kenteken.
- Raw nested blobs such as specificationGroups and structuredData are not pushed.

The result: more useful columns, less post-processing.

### Example Input

    {
      "startUrls": [
        { "url": "https://www.viabovag.nl/auto" },
        { "url": "https://www.viabovag.nl/auto/merk-toyota" }
      ],
      "maxItems": 100,
      "maxPages": 5,
      "includeDetails": false
    }

Advanced users can pass raw viaBOVAG search request objects:

    {
      "searchRequests": [
        {
          "brand": "toyota",
          "inStock": true,
          "mobilityType": "auto",
          "hideVatExcludedPrices": true,
          "showCommercialVehicles": true
        }
      ],
      "maxItems": 50
    }

### Input Fields

- startUrls: viaBOVAG search URLs, for example /auto or /auto/merk-toyota.
- searchRequests: raw viaBOVAG search request objects for advanced filtering.
- mobilityType: default category when no URL/request is supplied. Defaults to auto.
- maxItems: total unique listings to push.
- maxPages: maximum result pages per search. viaBOVAG currently returns 24 listings per page.
- includeDetails: fetch listing detail pages and add extra flat spec columns.
- proxyConfiguration: optional Apify proxy settings.

### Output Highlights

Core listing fields:

- id, title, price, formattedPrice, url, imageUrl
- make, model, year, month, mileage, mileageUnit
- fuelTypes, fuelTypeCount, transmissionType, bodyType, color, enginePower
- dealerName, dealerCity, dealerPhoneNumber, dealerWebsiteUrl
- sourceSearchPath, sourcePageNumber, sourcePagePosition, scrapedAt

BOVAG trust fields:

- bovagWarranty, warranties, warrantyCount
- certaintyKeys, certaintyCount
- fullyServiced, hasReturnWarranty, hasBovagMaintenanceFree
- hasNapWeblabel, hasBovagChecklist, servicedOnDelivery

Detail enrichment fields when includeDetails is true:

- licensePlate, energyLabel, primaryFuelType, secondaryFuelType
- doors, seats, apkUntil, productionYear, firstRegistrationDate
- detailMake, detailModel, detailTrim, detailBodyType
- spec columns expanded from viaBOVAG detail specification groups

### Validation

The actor includes a live quality gate:

    npm run test:live

The live test:

- pulls 100 real brand inputs from viaBOVAG facets,
- fetches search results for every input,
- samples detail-page enrichment,
- validates required columns,
- reviews every output column,
- fails if any column contains nested objects or arrays,
- fails if the success rate is below 95 percent.

Latest validation during build hardening:

- 100 inputs tested
- 100 successful
- 0 failed
- 138 columns reviewed
- 0 nested columns

### Local Run

    cd actors/bovag-scraper
    npm install
    node src/main.js

For a local custom input, write storage/key_value_stores/default/INPUT.json before running.

### Good Use Cases

- Dutch used-car market research
- BOVAG occasion inventory monitoring
- Dealer prospecting and lead generation
- Automotive price intelligence
- Vehicle data enrichment
- Car marketplace comparison
- CRM imports for dealership outreach
- Content or SEO research around popular Dutch car models

### Nederlandse Zoektermen

This scraper is useful for workflows around: BOVAG scraper, viaBOVAG scraper, occasion data, auto occasions Nederland, tweedehands auto data, dealer leads Nederland, BOVAG garantie data, kenteken en voertuigspecificaties, auto voorraad scraper.

# Actor input Schema

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

viaBOVAG search URLs, for example https://www.viabovag.nl/auto or https://www.viabovag.nl/auto/merk-toyota.
## `searchRequests` (type: `array`):

Raw viaBOVAG search request objects. These are merged over the default auto request.
## `mobilityType` (type: `string`):

Default mobility type when no start URL or search request is supplied.
## `maxItems` (type: `integer`):

Maximum number of unique listings to push.
## `maxPages` (type: `integer`):

Each viaBOVAG page currently returns 24 listings.
## `includeDetails` (type: `boolean`):

Fetch each vehicle detail page and merge richer specification data as flat columns when available.
## `proxyConfiguration` (type: `object`):

Optional Apify proxy configuration.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.viabovag.nl/auto"
    }
  ],
  "searchRequests": [],
  "mobilityType": "auto",
  "maxItems": 100,
  "maxPages": 5,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
````

# Actor output Schema

## `vehicles` (type: `string`):

Export-ready viaBOVAG listings with vehicle, BOVAG warranty, dealer, source, and optional detail spec columns.

## `vehicleOverview` (type: `string`):

Apify Console dataset view for scanning core listing fields.

## `trustSignals` (type: `string`):

Dataset view focused on BOVAG warranty, certainty, and dealer contact fields.

## `summary` (type: `string`):

JSON summary with search count, item count, warnings, and search requests.

# 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.viabovag.nl/auto"
        }
    ],
    "searchRequests": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("lokki/bovag-scraper").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.viabovag.nl/auto" }],
    "searchRequests": [],
}

# Run the Actor and wait for it to finish
run = client.actor("lokki/bovag-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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.viabovag.nl/auto"
    }
  ],
  "searchRequests": []
}' |
apify call lokki/bovag-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=lokki/bovag-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "BOVAG Scraper",
        "description": "Scrapes viaBOVAG vehicle listings from search URLs, friendly filter paths, or explicit search requests.",
        "version": "1.0",
        "x-build-id": "YzNt9QI3CtqQOLbSk"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/lokki~bovag-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-lokki-bovag-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/lokki~bovag-scraper/runs": {
            "post": {
                "operationId": "runs-sync-lokki-bovag-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/lokki~bovag-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-lokki-bovag-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "viaBOVAG search URLs, for example https://www.viabovag.nl/auto or https://www.viabovag.nl/auto/merk-toyota.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "searchRequests": {
                        "title": "Search requests",
                        "type": "array",
                        "description": "Raw viaBOVAG search request objects. These are merged over the default auto request."
                    },
                    "mobilityType": {
                        "title": "Mobility type",
                        "enum": [
                            "auto",
                            "fiets",
                            "motor",
                            "caravan",
                            "camper",
                            "vouwwagen",
                            "kampeer"
                        ],
                        "type": "string",
                        "description": "Default mobility type when no start URL or search request is supplied.",
                        "default": "auto"
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum number of unique listings to push.",
                        "default": 100
                    },
                    "maxPages": {
                        "title": "Max pages per search",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Each viaBOVAG page currently returns 24 listings.",
                        "default": 5
                    },
                    "includeDetails": {
                        "title": "Include detail page data",
                        "type": "boolean",
                        "description": "Fetch each vehicle detail page and merge richer specification data as flat columns when available.",
                        "default": false
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Optional Apify proxy configuration.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
