# DACH Residential White Pages & Reverse Phone Lookup (`jungle_synthesizer/dach-residential-phone-directory-reverse-lookup-scraper`) Actor

Search residential and business phone directories across Germany, Switzerland and Austria by name and city, or run a reverse phone lookup by number. Returns full name, phone (E.164), mobile, street address, postal code and district in one normalised schema per country.

- **URL**: https://apify.com/jungle\_synthesizer/dach-residential-phone-directory-reverse-lookup-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 40.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 record scrapeds

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

## DACH Residential White Pages & Reverse Phone Lookup

Search Germany, Switzerland and Austria's national phone directories by name and city, or run a reverse phone lookup by number, across all three countries in a single actor. Returns full name, phone number (with E.164 formatting), mobile, street address, postal code, and district for residential and business listings, normalised into one schema regardless of which country a result came from.

***

### DACH Phone Directory Scraper Features

- Searches by name, optionally narrowed to a city, across Germany, Switzerland and Austria in one run
- Runs reverse phone lookups on a German, Swiss or Austrian number — auto-detects the country from a `+49`/`+41`/`+43` prefix, or searches every selected country when given a bare national number
- Returns normalised phone numbers in both display and E.164 format, with mobile numbers split out separately
- Parses street address, postal code, city and district (German Stadtteil / Swiss canton) per listing
- Covers residential and business entries in one search — no separate mode needed
- Pick any combination of the three countries per run, or leave the default (all three) in place

***

### Who Uses This Data?

- **Skip tracing and process serving** — locate a current address and phone number for a named individual before filing across DACH jurisdictions
- **Debt recovery** — cross-check a debtor's last known name against current directory listings in Germany, Switzerland or Austria
- **Insurance claims** — verify a claimant's address and phone against a public directory record
- **B2C lead generation** — build contact lists by name or region for German-speaking Europe outreach campaigns
- **Reverse phone research** — identify who's calling from an unknown German, Swiss or Austrian number
- **Data enrichment** — append name, address and phone fields to an existing DACH-region contact list

***

### How It Works

1. Choose a search mode — name search or reverse phone lookup.
2. For a name search, give it a name and (optionally) a city. For a phone lookup, give it a number — include the country code (`+49`/`+41`/`+43`) for a precise match when searching more than one country.
3. Pick which of the three countries to search via `countries` — all three by default.
4. The actor returns every matched listing with contact details and address, paginating automatically up to your `maxItems` limit.
5. A name search with no city returns matches from anywhere in the selected country/countries — narrow it if you're only after one region.

***

### Input

```json
{
  "searchMode": "name",
  "countries": ["DE", "CH", "AT"],
  "name": "Meier",
  "city": "Berlin",
  "maxItems": 50
}
```

| Field        | Type    | Default            | Description |
|--------------|---------|--------------------|--------------------------------------------------------------------------------------------------------|
| `searchMode` | String  | `name`             | `name` (search by name, optionally narrowed by city) or `phone` (reverse phone lookup). |
| `countries`  | Array   | `["DE","CH","AT"]` | Which of Germany, Switzerland and Austria to search. Omit a country to skip it. |
| `name`       | String  | —                  | Name to search for — a surname or full name. Required for name mode. |
| `city`       | String  | —                  | City to narrow a name search, e.g. `"Berlin"`. Optional — omit for nationwide results in each country. |
| `phone`      | String  | —                  | Phone number for a reverse lookup, e.g. `"030 3134894"` or `"+43 1 4032202"`. Required for phone mode. |
| `maxItems`   | Integer | `10`               | Maximum number of records to return. |

Reverse phone lookup example:

```json
{
  "searchMode": "phone",
  "phone": "+43 1 4032202",
  "maxItems": 5
}
```

#### Resuming a large crawl

Every run emits a `resumeCursor` in its Output. If a large crawl stops before it finishes — because it hit `maxItems`, your spend cap (`maxTotalChargeUsd`), or was aborted — start a new run with **the same input** plus that `resumeCursor` to continue from where it left off. The crawl resumes from the queued work the previous run didn't reach.

- You are **not re-charged** for records the earlier run already delivered.
- Resume within your account's run-retention window — on the free tier, roughly your 10 most recent runs. Once the source run is pruned, its `resumeCursor` is no longer valid.
- `resumeCursor` is opaque — supply it unmodified.

***

### Output Fields

```json
{
  "source_country": "DE",
  "source_site": "dastelefonbuch.de",
  "listing_id": "0001115703880",
  "listing_type": "private",
  "full_name": "Becker Sabine Meier Ingo",
  "first_name": null,
  "last_name": null,
  "phone": "030 3 13 48 94",
  "phone_e164": "+49303134894",
  "mobile": null,
  "street_address": "Pestalozzistr. 29",
  "postal_code": "10627",
  "city": "Berlin",
  "district": "Charlottenburg",
  "website": null,
  "listing_url": "https://kontakt-1.dastelefonbuch.de/Berlin/Sabine-Becker-Ingo-Meier-Berlin-Pestalozzistr.html",
  "query_term": "Meier",
  "query_location": "Berlin",
  "query_phone": null,
  "result_rank": 1,
  "scraped_at": "2026-09-20T15:23:20.077Z"
}
```

| Field            | Type    | Description                                                                                        |
|------------------|---------|----------------------------------------------------------------------------------------------------|
| `source_country` | String  | `DE`, `CH`, or `AT` — which country this listing is from.                                          |
| `source_site`    | String  | The national directory the listing came from.                                                      |
| `listing_id`     | String  | The source's internal listing identifier.                                                          |
| `listing_type`   | String  | `private` or `business`.                                                                           |
| `full_name`      | String  | Name as listed.                                                                                    |
| `first_name`     | String  | Given name, when the source separates it. `null` for German listings, which do not split names.    |
| `last_name`      | String  | Family name, when the source separates it. `null` for German listings, which do not split names.   |
| `phone`          | String  | Landline number as displayed, when the number is a landline.                                       |
| `mobile`         | String  | Mobile number as displayed, when the number is a mobile. Mutually exclusive with `phone`.          |
| `phone_e164`     | String  | Phone number normalised to E.164, e.g. `+49303134894`.                                             |
| `street_address` | String  | Street address, when listed.                                                                       |
| `postal_code`    | String  | Postal code, when listed.                                                                          |
| `city`           | String  | City.                                                                                              |
| `district`       | String  | German Stadtteil (e.g. `Charlottenburg`) or Swiss canton (e.g. `ZH`), when the source exposes one. |
| `website`        | String  | Homepage link, when the listing includes one. Sparse — most listings don't carry one.              |
| `listing_url`    | String  | Direct URL to the listing on its source site.                                                      |
| `query_term`     | String  | The `name` your search requested (name mode only).                                                 |
| `query_location` | String  | The `city` your search requested (name mode only).                                                 |
| `query_phone`    | String  | The `phone` your search requested (phone mode only).                                               |
| `result_rank`    | Integer | Position of this listing within its search's result set.                                           |
| `scraped_at`     | String  | ISO 8601 timestamp of when the record was collected.                                               |

**Data quality note:** none of the three source directories expose fax number, email address, or geolocation on their search-results pages, so those fields are not part of the output. `listing_type` is source-verified for the Swiss and Austrian legs and inferred from a page-level marker for the German leg — all three are more reliable than a name-keyword guess, but treat them as best-effort rather than a guarantee on every row.

***

### FAQ

#### How do I scrape German, Swiss and Austrian phone directories in one actor?

Give it a name (and optionally a city), or a phone number for a reverse lookup, and pick which of Germany, Switzerland and Austria to search via `countries`. It returns every matched listing with contact details and address — no account or API key needed.

#### How much does this actor cost to run?

Pricing follows Apify's pay-per-event model — see the Pricing tab on the actor page for the current rate per record. Results are paginated, so a broad name search across all three countries costs more than a narrow one scoped to a city.

#### Can I search for a name across a whole country?

Yes — omit `city` and a name search returns matches from anywhere in each selected country. Add a city to narrow it.

#### Does this actor cover business listings, or just residential?

Both. A single name search can return private and business entries together; `listing_type` on each record tells you which is which.

#### What happens if a reverse phone lookup finds no match?

The run finishes with zero records for that query — none of the selected countries has a listing for the number you searched.

#### How do I search only one country?

Set `countries` to a single value, e.g. `["CH"]`, and the actor queries only that country's directory.

***

### Need More Features?

Need custom fields, filters, or a different target site? [File an issue](https://console.apify.com/actors/issues) or get in touch.

### Why Use This Scraper?

- **Three countries, one schema** — Germany, Switzerland and Austria normalised into the same field names, instead of running three separate actors and reconciling the output yourself.
- **Reverse phone lookup as a first-class mode** — not just name search, with automatic country detection from the number itself.
- **Clean, structured output** — consistent field names across every record, so you spend less time cleaning data and more time using it.

***

**Further reading:** [People Search Data in Bulk: 14 Sources, What Each One Returns](https://orbtop.com/articles/people-search-data-in-bulk/)

# Actor input Schema

## `sp_intended_usage` (type: `string`):

What will this data feed? E.g. lead lists, KYB checks, price tracking.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

We'll personally help with your use case. No spam.

## `resumeCursor` (type: `string`):

Leave empty for a fresh crawl. To CONTINUE a previous run where it stopped — without paying again for records you already received — paste the `resumeCursor` value from that run's Output (the run's OUTPUT key). Resume promptly: the previous run's data expires with your account's retention window (free tier: your ~10 most recent runs).

## `searchMode` (type: `string`):

Search mode: "name" (search by name, optionally narrowed by city) or "phone" (reverse phone lookup by number).

## `countries` (type: `array`):

Which national directories to search. Omit a country to skip it. Defaults to all three (Germany, Switzerland, Austria) — searching more countries costs the same per matched record as searching one.

## `name` (type: `string`):

Surname or full name to search (e.g. "Meier"). Required for name mode.

## `city` (type: `string`):

City or locality to narrow a name search (e.g. "Berlin"). Optional — omit to search nationwide within each selected country. Used only in name mode.

## `phone` (type: `string`):

Phone number for a reverse lookup, national or international format (e.g. "030 3134894", "+41 44 334 44 55", "+43 1 4032202"). Required for phone mode. Include the country code (+49/+41/+43) for a precise match when searching more than one country.

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

Maximum number of records to return. Results are paginated per source, and each page fetch is a billed request.

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "searchMode": "name",
  "countries": [
    "DE",
    "CH",
    "AT"
  ],
  "name": "Meier",
  "city": "Berlin",
  "maxItems": 10
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "searchMode": "name",
    "countries": [
        "DE",
        "CH",
        "AT"
    ],
    "name": "Meier",
    "city": "Berlin",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/dach-residential-phone-directory-reverse-lookup-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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "searchMode": "name",
    "countries": [
        "DE",
        "CH",
        "AT",
    ],
    "name": "Meier",
    "city": "Berlin",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/dach-residential-phone-directory-reverse-lookup-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 '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "searchMode": "name",
  "countries": [
    "DE",
    "CH",
    "AT"
  ],
  "name": "Meier",
  "city": "Berlin",
  "maxItems": 10
}' |
apify call jungle_synthesizer/dach-residential-phone-directory-reverse-lookup-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jungle_synthesizer/dach-residential-phone-directory-reverse-lookup-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/TjlgJuRL2DiJKLnBW/builds/Zbf9vSXISIrj49g7S/openapi.json
