# DubiCars Dealer Scraper - UAE Car Dealers, Phones & Emails (`scrapersdelight/dubicars-dealer-scraper`) Actor

Export UAE car dealers from DubiCars: name, emirate, direct phone, map coordinates, live inventory count and the export-dealer flag, plus e-mail and street address. 684 dealers reachable - DubiCars stops serving its own directory past page 30, and this Actor says so rather than pretending otherwise.

- **URL**: https://apify.com/scrapersdelight/dubicars-dealer-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.80 / 1,000 per dealer returneds

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## DubiCars Dealer Scraper — UAE Car Dealers

Turns the dealer directory of **DubiCars**, the UAE's largest car marketplace, into a B2B lead list:
one row per dealer with a **direct phone number, e-mail, street address, map coordinates and live
inventory count**.

***

### Read this before you buy: coverage

**DubiCars advertises 1,522 dealers. Its directory serves 684 of them.**

That is not a limitation of this Actor — it is the site refusing its own pagination. Page 30 of the
directory returns normally; **page 31 returns a Cloudflare challenge**, deterministically, from
datacenter and residential exits alike, while the page footer carries on linking to pages 31 through
96 as though they worked. This Actor sweeps every facet the site does serve — the global list plus
each of the eight emirate views — and deduplicates, which lifts the reachable set from 480 to **684
(44.9%)**.

A scraper that trusted the footer's page links would fire ~65 refused requests per run and hand you
480 rows while the page it just read says 1,522. This one tells you the number and reports it in
`RUN_SUMMARY` as `reachableUnion` against `advertisedByDubicars`.

### What one row looks like

```json
{
  "dealerId": "2516",
  "dealerName": "777 Cars Trading",
  "emirate": "Dubai",
  "carsCount": 64,
  "phone": "+97142695977",
  "email": "motorsdxb777@gmail.com",
  "streetAddress": "Aweer, Showroom 74",
  "latitude": 25.086817,
  "longitude": 55.145386,
  "priceRange": "AED 70,000 - AED 1,950,000",
  "listingsSampled": 30,
  "exportListingsInSample": 0,
  "sellsForExport": false,
  "enriched": true
}
```

| field | what it is |
|---|---|
| `dealerName` · `emirate` · `carsCount` | Identity and how many vehicles they have live right now |
| `phone` | Direct dealer line — **comes free from the directory**, not from the enrichment step |
| `latitude` · `longitude` | Map coordinates, also free from the directory |
| `email` · `streetAddress` · `priceRange` | From the dealer's own page, when `enrichContacts` is on |
| `listingsSampled` · `exportListingsInSample` · `sellsForExport` | See **the export question** below |
| `enriched` · `enrichmentNote` | `false` means the dealer's page was **not read** — never that they have no e-mail |
| `detailUrlIsCanonical` | `false` where the directory published no link and the dealer id was used instead |

Measured across two live runs: **16 of 18 dealers enriched (89%)** — 12/12 on one sample, 4/6 on another. The two that failed publish no structured contact block on their own page; they are still delivered, flagged `enriched: false` with the reason, and **not** charged differently.

### The export question, answered honestly

DubiCars shows an "export dealers" filter and states a cohort of **186** on the button. **That filter
does not work as a URL.** `?filter=only-for-export` returns a byte-identical page to the unfiltered
view — same 16 dealers, same "1522 dealers found" — and so does every other parameter form. The
directory simply ignores unknown query parameters.

So this Actor does **not** sell you an export flag copied off a filter it cannot reproduce. What it
gives you instead is measured per dealer, from that dealer's own listings: `exportListingsInSample`
counts how many of their live vehicles are flagged for export rather than the local market, and
`sellsForExport` is true when that count is above zero. `listingsSampled` tells you how many listings
that judgement is based on, so you can see how strong it is. Where no listings were sampled, all
three are `null` rather than a guess.

### Input

| input | default | what it does |
|---|---|---|
| `emirate` | all | Dubai 428 · Sharjah 156 · Ajman 45 · Abu Dhabi 44 · Umm al-Quwain 5 · Al Ain 4 · Ras al-Khaimah 2 |
| `minCarsCount` | `0` | Keep only dealers with at least this many vehicles live — a proxy for dealer size |
| `enrichContacts` | `true` | Reads each dealer's page for e-mail, address and price range. Off = fast directory-only pull, but phone and coordinates are still included |
| `maxDealers` | `200` | Cap on delivered and charged rows, applied after sorting by inventory size |
| `proxyConfiguration` | Apify Proxy (datacenter) | Datacenter is enough — the page-30 boundary behaves identically on residential, so residential buys nothing here |

Results come back **largest dealer first**, so a capped run returns the dealers with real inventory
rather than an arbitrary slice.

### Pricing

Pay per event: **$0.0018 per `dealer-lead`** — charged only for a dealer row actually delivered.
Filters are applied before delivery, so rows they drop are never charged, and a run that returns
nothing costs nothing. A full enriched pull of all 684 reachable dealers is **$1.23**.

A row where the dealer's page could not be read is still delivered — flagged `enriched: false` with
the reason — so you can see what was missed instead of being quietly short-changed.

Every run writes a `RUN_SUMMARY` with the advertised total, the reachable union, the coverage
fraction, the page ceiling that caused it, and delivered vs charged.

### Source and legal

Data comes from the public dealer directory at `dubicars.com/dealers` and from each dealer's own
public page. Both are pages DubiCars serves to any visitor with no login.

`robots.txt` disallows `/api`, `/ajax`, `/search`, `/search-count` and `/webapp`. **This Actor uses
none of them** — it reads the HTML directory and the dealer pages, which are not disallowed. Dealer
contact details are published by the dealers themselves to attract buyers; you are responsible for
how you use them, which for outreach into the UAE means the Consumer Protection Law's e-marketing
rules, and the equivalent wherever you are sending from.

# Actor input Schema

## `emirate` (type: `array`):

Leave empty for all. Measured dealer counts in the reachable set: Dubai 428 - Sharjah 156 - Ajman 45 - Abu Dhabi 44 - Umm al-Quwain 5 - Al Ain 4 - Ras al-Khaimah 2.

## `minCarsCount` (type: `integer`):

Keep only dealers with at least this many vehicles listed right now. A rough proxy for dealer size; the count comes straight off the directory card.

## `enrichContacts` (type: `boolean`):

Phone and coordinates come free from the directory. E-mail, street address and website need the dealer's own page, which is a heavier fetch - turn this off for a fast directory-only pull.

## `maxDealers` (type: `integer`):

Hard cap on delivered - and therefore charged - rows, applied after sorting by inventory size. 0 means every match; the whole reachable directory is about 684.

## `proxyConfiguration` (type: `object`):

Apify Proxy. Datacenter is sufficient: the page-30 boundary behaves identically on datacenter and residential exits, so residential buys nothing here.

## Actor input object example

```json
{
  "emirate": [],
  "minCarsCount": 0,
  "enrichContacts": true,
  "maxDealers": 200,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

One row per dealer - name, emirate, direct phone, map coordinates, live inventory count and export flag from the directory, plus e-mail, street address and website from the dealer's own page. The `enriched` flag says whether that page was read.

## `runSummary` (type: `string`):

RUN\_SUMMARY: how many dealers DubiCars advertises, how many its directory actually serves, the resulting coverage fraction, the page ceiling that caused it, the export cohort, and delivered vs charged.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/dubicars-dealer-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/dubicars-dealer-scraper").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 '{}' |
apify call scrapersdelight/dubicars-dealer-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapersdelight/dubicars-dealer-scraper"
        }
    }
}
```

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/vYZ39AN9pJ0zssoJc/builds/54vc4uypJkeoxIqkO/openapi.json
