# Doctolib Scraper \[$1/1K💰] | Doctor Data | Phone | Billing (`ahmed_jasarevic/doctolib-fr-scraper`) Actor

Scrape doctor and practice profiles from Doctolib (FR/DE/IT) for healthcare lead generation, pharma territory mapping and clinic recruitment. Names, specialties, phones, fees, billing sectors, GPS and online-booking status as clean JSON at $1 per 1,000 profiles - no browser or proxy needed.

- **URL**: https://apify.com/ahmed\_jasarevic/doctolib-fr-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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/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

## Doctolib Scraper: Doctor & Practice Data for France, Germany & Italy

Extract **doctor and practitioner profiles from Doctolib** (doctolib.fr, doctolib.de, doctolib.it) in one run: name, specialty, practice address + GPS, phone, billing sector, consultation fees, languages, online-booking status, telehealth, photos and profile URL — clean structured JSON for **healthcare lead generation, pharma territory mapping, clinic recruitment and healthcare market research**. Built on Doctolib's own internal JSON API (no browser, no login), it is fast, cheap and stable: **$1 per 1,000 profiles**, proxy-free by default.

### Build Healthcare Lead Lists From Doctolib Data

- **Healthtech lead generation** — build prospect lists of doctors and practices by specialty + city across France, Germany and Italy.
- **Pharma & medical-device sales targeting** — map who practises where, what they charge (published fees), which languages they speak and whether they accept new patients.
- **Clinic recruitment** — find practitioners by specialty, billing sector and online-booking behaviour to target recruitment outreach.
- **Healthcare market mapping** — enumerate the Doctolib directory per specialty/city with GPS coordinates for geo-analysis and territory planning.
- **CRM enrichment** — enrich a contact database with practice phone numbers, practice locations and visit motives (optional profile-detail mode).
- **Patient-access & telehealth research** — measure online-booking and teleconsultation adoption per specialty, city and country.

### How the Scraper Works: Doctolib's Internal JSON API, No Browser Needed

The actor calls Doctolib's own patient-search JSON endpoint (`POST /patient-health-search/api/v1/hcp/search`) with a normal Chrome User-Agent + Referer header — no cookies, no browser, no DOM scraping. When profile details are enabled, each record is enriched from the slot-selection funnel endpoint (`GET /online_booking/api/slot_selection_funnel/v1/info.json`). HTML profile pages are aggressively rate-limited by DataDome, so the actor deliberately avoids them. A search-only run of 100 profiles makes only ~5 HTTP requests and finishes in seconds at 256 MB memory; enabling details adds one request per profile and still completes well under a minute.

### Scrape Practitioner Profiles Without the Official Doctolib API

Doctolib does not offer a public, self-serve API: its official developer API is restricted to approved partners (medical software vendors and hospital information systems). This actor gives you the same publicly visible practitioner directory data — names, specialties, addresses, published fees, billing sectors — as structured JSON through the Apify API, at $1 per 1,000 profiles.

### Input Fields: Country, Specialty & City Filters

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `country` | string (enum) | No | `fr` | Doctolib country site: `fr` (doctolib.fr), `de` (doctolib.de), `it` (doctolib.it) |
| `specialty` | string | Yes | — | Doctolib specialty slug or free-text keyword, e.g. `medecin-generaliste`, `dentiste`, `allgemeinmedizin`, `zahnarzt`, `medico-di-medicina-generale`, `odontoiatra` |
| `city` | string | Yes | — | City to search in (e.g. `Paris`, `Berlin`, `Milano`); geocoded into a bounding box via Nominatim |
| `viewport` | object | No | — | Explicit bounding-box override `{"northeast":{"lat","lng"},"southwest":{"lat","lng"}}` when geocoding is not wanted |
| `maxResults` | integer | No | `100` | Max profiles per run (max 10,000). Free Apify users are capped at 10 |
| `scrapeProfileDetails` | boolean | No | `false` (see note below) | Enrich each profile with phone, practice names/locations and visit motives via the funnel API (1 extra request + 1 `profile-detail` charge per profile) |
| `proxy` | object | No | — | Standard Apify proxy config; enable (e.g. `AUTO`/residential group) only if you hit rate limits |

> ⚠️ **Note for `scrapeProfileDetails`:** in the current build, profile-detail enrichment runs whenever the field is *not explicitly `false`* (i.e. omitting the field also enables it and triggers the per-profile `profile-detail` charge). Set `"scrapeProfileDetails": false` explicitly for a cheap search-only run. This will be aligned with the schema default in a future build.

### Output Fields: Structured Doctor & Practice Profiles

Each dataset item is one practitioner/practice profile with the following fields:

| Field | Type | Description |
|---|---|---|
| `profileId`, `practiceId` | int | Doctolib internal profile / practice identifiers |
| `name`, `title`, `gender` | string | Practitioner name with title (e.g. "Dr Olivier-Jacques Bocrie"), honorific, gender |
| `specialty`, `specialtySlug` | string | Specialty display name and Doctolib slug |
| `profileUrl` | string | Link to the doctor's Doctolib profile page |
| `address`, `city`, `zipcode`, `country` | string | Practice postal address and country code (`fr`/`de`/`it`) |
| `latitude`, `longitude` | float | GPS coordinates of the practice |
| `languages` | string\[] | Spoken languages (Doctolib country codes) |
| `hasOnlineBooking` | boolean | Whether online booking is offered |
| `telehealth` | boolean/null | Whether video consultation is available |
| `acceptsNewPatients` | boolean/null | Whether new patients are accepted |
| `billingSector` | string | Billing/regulation sector (FR: `contracted_1`, `contracted_2`, `non_contracted`, ...; DE: `akzeptiert_gesetzlich_versicherte_patient`, ...) |
| `paymentMethods` | string\[] | Accepted payment methods |
| `fee`, `feeType` | number/string | Published consultation fee in EUR and its type, when available |
| `insuranceSector`, `insuranceSectorSplit` | string/null | Public/private insurance sector when the practice splits it |
| `visitMotiveName`, `visitMotiveId`, `agendaIds` | string/int/array | Matched appointment type and booking agenda IDs |
| `phone` | string | Practice landline number (only with `scrapeProfileDetails` enabled) |
| `practices` | array | All practice locations: name, address, city, zipcode, GPS, phone |
| `visitMotives` | string\[] | Visit motives for the profile (only with details enabled) |
| `photoUrl` | string | Practitioner photo URL |
| `type` | string | Provider type from the search payload |
| `dataSource` | string\[] | Which stages contributed: `["search"]` or `["search","funnel"]` |
| `scrapedAt` | string | ISO 8601 timestamp |

### Example Input

```json
{
  "country": "fr",
  "specialty": "medecin-generaliste",
  "city": "Paris",
  "maxResults": 200,
  "scrapeProfileDetails": false
}
```

Run a specific region without geocoding by passing `viewport` instead of relying on `city`, and enable enrichment for phone numbers:

```json
{
  "country": "de",
  "specialty": "zahnarzt",
  "city": "Berlin",
  "viewport": {
    "northeast": { "lat": 52.54, "lng": 13.5 },
    "southwest": { "lat": 52.45, "lng": 13.25 }
  },
  "maxResults": 100,
  "scrapeProfileDetails": true
}
```

### Example Output

```json
{
  "profileId": 315957,
  "practiceId": 396531,
  "name": "Dr Olivier-Jacques Bocrie",
  "title": "Dr",
  "gender": "male",
  "specialty": "Médecin généraliste",
  "specialtySlug": "medecin-generaliste",
  "profileUrl": "https://www.doctolib.fr/medecin-generaliste/puteaux/olivier-jacques-bocrie-paris?pid=practice-396531",
  "address": "7 Rue Bergère",
  "city": "Paris",
  "zipcode": "75009",
  "country": "fr",
  "latitude": 48.8719085,
  "longitude": 2.3468045,
  "languages": ["fr", "gb"],
  "hasOnlineBooking": true,
  "telehealth": true,
  "acceptsNewPatients": true,
  "billingSector": "contracted_1",
  "paymentMethods": ["cash", "check", "credit_card"],
  "fee": 68.5,
  "feeType": "fixed",
  "insuranceSector": null,
  "insuranceSectorSplit": null,
  "visitMotiveName": "Consultation",
  "visitMotiveId": 7785341,
  "agendaIds": [1149767, 11115],
  "photoUrl": "https://media.doctolib.com/image/upload/q_auto:eco,f_auto/mjptiifiik0dnula8mnr.jpg",
  "type": "hcp",
  "phone": "01 86 47 85 58",
  "practices": [
    {
      "name": "One Clinic - Défense",
      "address": "7 Esplanade du Général de Gaulle",
      "city": "Puteaux",
      "zipcode": "92800",
      "latitude": 48.88806,
      "longitude": 2.249253,
      "phone": "01 86 47 85 53",
      "slug": "one-clinic-defense"
    }
  ],
  "visitMotives": ["Consultation", "Suivi"],
  "dataSource": ["search", "funnel"],
  "scrapedAt": "2026-09-16T07:40:00.000Z"
}
```

`phone`, `practices` and `visitMotives` appear when `scrapeProfileDetails` is enabled. Without details, `dataSource` is `["search"]` and those fields are absent.

### Integrate With Your CRM, ChatGPT or Scheduling Automation

- **Apify API (REST)** — call the actor from any application; results stream to an Apify Dataset you can export as JSON, CSV, XLSX or HTML.
- **MCP / AI agents** — the actor is callable through the Apify MCP server, so Claude, GPT and other agent clients can run it directly.
- **Webhooks** — get notified when a run finishes (SUCCEEDED/FAILED) or when items are pushed.
- **Zapier & Make (Integromat)** — Apify's official integrations let you pipe Doctolib profiles into HubSpot, Pipedrive, Google Sheets, Salesforce, etc.
- **Scheduling** — set a recurrence in Apify Console: weekly refresh for recruitment/lead-gen lists, monthly for market-mapping datasets. Periodically re-scraping profiles also keeps the data accurate (practices move, fees and online-booking status change).

### Related Actors: Healthcare Data & Lead Generation Tools

- [samstorm/dentist-lead-scraper](https://apify.com/samstorm/dentist-lead-scraper) — healthcare lead generation from Google Maps with verified emails and phones.
- [giovannibiancia/Doctoralia](https://apify.com/giovannibiancia/Doctoralia) — Doctoralia HCP data extractor (market research / lead generation sibling dataset).
- [gio21/doctoralia-scraper](https://apify.com/gio21/doctoralia-scraper) — Doctoralia doctors by city + specialty (Brazil, Spain, Italy, Poland, Mexico, Colombia, Chile).
- [memo23/vitals-scraper](https://apify.com/memo23/vitals-scraper) — US doctor & dentist profiles by specialty/location (adds US coverage to the cluster).

### FAQ: Doctolib API, Alternatives, Legality & More

#### Does Doctolib have an official API?

Doctolib's official developer API exists but is **partner-only**: access is granted to approved medical software vendors and hospital information systems via an authentication-gated developer portal. There is no public, self-serve tier, no public OpenAPI specification, and no free API key. For everyone else, the practical ways to get Doctolib directory data are scraping (like this actor) or licensed data from third-party vendors (e.g. Veeva OpenData subscribes).

#### Why use this actor instead of the official Doctolib API?

The official API requires a partner approval process and is not open to individual developers, consultants, agencies or most B2B companies. This actor reads the same publicly visible directory data (names, specialties, addresses, published fees, billing sectors, languages) via Doctolib's public-facing JSON endpoints and delivers it as structured JSON via the Apify API — with no browser, no login and no partnership process. Cost is **$1 per 1,000 profiles** (plus an optional $0.0025 per enriched profile).

#### Is scraping Doctolib legal?

This actor only reads **publicly visible directory information** — the same data any anonymous visitor sees on Doctolib's public search pages (names, specialties, addresses, published fees). It does not collect patient data, private messages, appointment histories or anything behind a login, and it does not book appointments. French regulator guidance (CNIL) and GDPR principles treat collection of manifestly public professional directory data as admissible for internal analysis and market research, subject to data-minimisation and purpose limits. You are responsible for complying with Doctolib's Terms of Service and applicable law (see the disclaimer at the bottom of this page) before using the data commercially.

#### How much does it cost to scrape Doctolib?

**$0.001 per profile** (base search result) + a small per-run start event (~$0.00005, based on memory) + optional **$0.0025 per profile** when profile-detail enrichment (phones, practices) is enabled. So a search-only run of 1,000 profiles costs about **$1.00**, and a fully enriched run of 1,000 profiles about **$3.50** — no proxy costs in the default configuration.

#### What are alternatives to scraping Doctolib?

- **Official partner API** — only for approved medical-software/hospital partners.
- **Licensed HCP data** — Veeva OpenData (5M+ HCPs in Europe), Axioma, and similar pharma-grade databases; subscription-based and much more expensive.
- **Other scrapers / no-code tools** — Scrapingbee's Doctolib API, Piloterr, Octoparse, or other Apify Store Doctolib actors (compare price per record: $0.00299–$0.04 depending on the actor).
- **Doctoralia data** — complementary HCP directory across additional countries (see Related Actors).

#### Which countries does Doctolib cover and how do I scrape each one?

Doctolib operates in France, Germany, Italy and the Netherlands. This actor covers **France** (`country: "fr"`, doctolib.fr), **Germany** (`"de"`, doctolib.de) and **Italy** (`"it"`, doctolib.it). Use the country's own specialty vocabulary for best results: FR `medecin-generaliste`, `dentiste`, `dermatologue`, `ophtalmologue`; DE `allgemeinmedizin`, `zahnarzt`, `hautarzt`, `augenarzt`; IT `medico-di-medicina-generale`, `odontoiatra`, `dermatologo-venereologo`, `oculista`.

#### How do I find doctors accepting new patients or offering online booking?

The output includes `acceptsNewPatients`, `hasOnlineBooking` and `telehealth` flags per profile. Run a search for your specialty + city, then filter the dataset on these boolean fields — e.g. build a list of practices with online booking and new-patient availability for a digital-health outreach campaign.

#### What data is NOT included?

Live appointment slots and opening hours are **not** returned: opening hours live on profile HTML pages that Doctolib aggressively rate-limits, and slot availability changes by the minute and isn't meaningful in a static dataset. Some practitioners have no online booking (search-only records); phone numbers and practice locations are only present when profile-detail enrichment is enabled.

### Competitive Positioning: Doctolib Scrapers Compared

| Capability | Other Doctolib actors (typical) | This actor |
|---|---|---|
| Base price per profile | $0.00299 – $0.04 (as published on store pricing pages) | **$0.001** (search result) + optional $0.0025 enrichment |
| Residential proxy | Required/forced on several (e.g. $0.04/result actor notes Cloudflare blocks datacenter) | Not required by default — plain HTTP on Doctolib's JSON API |
| Phone numbers in output | Several suppress contact PII entirely (e.g. GDPR-first actors return no phone) | **Yes** — practice landline numbers when enrichment is enabled |
| Billing sector, fees, payment methods | Some (15+ fields); others listing-only | **Yes** — `billingSector`, `fee`, `paymentMethods`, `insuranceSector` |
| Countries | FR/DE/IT on most; FR-only on some | fr, de, it in one run |

### For AI Agents & LLM Apps

**Purpose:** returns structured Doctolib practitioner/practice directory records (search results, optionally enriched with phone + practice locations + visit motives) for one specialty + city (or viewport) on doctolib.fr/.de/.it.

**Minimal working input (cheapest valid run):**

```json
{
  "specialty": "medecin-generaliste",
  "city": "Paris",
  "scrapeProfileDetails": false
}
```

**Variant inputs:**

- Multi-country: add `"country": "de"` (or `"it"`) and use the local specialty slug, e.g. `"specialty": "zahnarzt"`, `"city": "Berlin"`.
- Enriched mode (phone, `practices`, `visitMotives`): set `"scrapeProfileDetails": true` — adds one request + one `profile-detail` charge per profile.
- Region override: pass `"viewport": {"northeast": {"lat": 49.0, "lng": 2.6}, "southwest": {"lat": 48.6, "lng": 2.1}}` to bypass city geocoding.

**Output field list:** `profileId, practiceId, name, title, gender, specialty, specialtySlug, profileUrl, address, city, zipcode, country, latitude, longitude, languages, hasOnlineBooking, telehealth, acceptsNewPatients, billingSector, paymentMethods, fee, feeType, insuranceSector, insuranceSectorSplit, visitMotiveName, visitMotiveId, agendaIds, photoUrl, type, phone, practices[], visitMotives[], dataSource, scrapedAt`.

**Behaviors an agent should know:**

- `specialty` and `city` are **required** — the run fails immediately if either is missing.
- **`scrapeProfileDetails` is truthy unless explicitly `false`.** In the current build, omitting the field enables per-profile enrichment and the $0.0025 `profile-detail` charge. Pass `false` explicitly to keep runs cheap.
- `maxResults` is capped at **10 for free (non-paying) users**; paying users get up to 10,000 and the default is 100.
- `viewport`, if fully specified, **takes priority over `city` geocoding** (city may be empty of coordinates in that case). If geocoding fails, the run errors and asks for `viewport`.
- Do not filter by insurance/language/availability on the input — there are no such input filters; `languages`, `billingSector`, `hasOnlineBooking`, `acceptsNewPatients` are output flags to filter on after the run.
- Only publicly visible directory data is returned; no patient data. `dataSource` records which stages contributed (`search` / `funnel`).
- If HTTP 403s occur at scale, set `proxy.useApifyProxy: true` (residential group recommended).

**Billing model (pay-per-event):** Actor Start ~$0.00005 per GB-memory (min 1 event) + `result` $0.001 per dataset row + optionally `profile-detail` $0.0025 per enriched profile when details are enabled.

### Legal & Compliance Disclaimer

This actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by Doctolib** (Doctolib SAS and its country entities). "Doctolib" and the doctolib.fr / doctolib.de / doctolib.it services are trademarks of their respective owners.

The actor accesses **only publicly visible directory pages and public-facing JSON endpoints** used by the Doctolib website — it performs no login bypass, no CAPTCHA solving, no patient-data collection and no appointment booking. Phone numbers, when present, are practice landline numbers that practices themselves publish on their public profiles.

Users are responsible for complying with Doctolib's Terms of Service and all applicable data-protection law (including the EU GDPR and, for France, CNIL guidance on scraping and data reuse). Because output may include published practice phone numbers, do not use this data for unsolicited commercial outreach in violation of applicable law (e.g., GDPR / French ePrivacy rules on direct marketing). This information is not legal advice; for commercial use, consult a qualified lawyer.

### SEO Keywords

doctolib scraper, scrape doctolib, doctolib api, doctolib alternative, doctolib data extraction, doctor database france, base de donnees medecins, french doctors data, medecin generaliste, dentiste, dermatologue, cardiologue, ophtalmologue, german doctor directory, arztverzeichnis, zahnarzt, allgemeinmedizin, italian doctors database, elenco medici, doctors accepting new patients, healthcare lead generation, pharma sales territory mapping, clinic recruitment data, healthcare market research, doctor gps data

# Actor input Schema

## `country` (type: `string`):

Doctolib country site to search: France (doctolib.fr), Germany (doctolib.de) or Italy (doctolib.it).

## `specialty` (type: `string`):

Doctolib specialty slug or free-text keyword to search for. Examples: FR 'medecin-generaliste', 'dentiste', 'dermatologue'; DE 'allgemeinmedizin', 'zahnarzt', 'hautarzt'; IT 'medico-di-medicina-generale', 'odontoiatra', 'dermatologo-venereologo'. You can also use a free-text keyword such as 'cardiologue'.

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

City to search in, e.g. 'Paris', 'Berlin', 'Milano'. The city is geocoded (Nominatim) into a bounding box that Doctolib uses to filter results. You can override the geocoding with the 'viewport' field below.

## `viewport` (type: `object`):

Optional explicit bounding box used as the location filter instead of geocoding the city. Format: {"northeast": {"lat": 49.0, "lng": 2.6}, "southwest": {"lat": 48.6, "lng": 2.1}}. Useful when Nominatim geocoding is unavailable or you want a custom area.

## `maxResults` (type: `integer`):

Maximum number of practitioner/practice profiles to return. Free users are capped at 10.

## `scrapeProfileDetails` (type: `boolean`):

Fetch each practitioner's funnel JSON API to enrich records with phone number, practice names/locations and visit motives. Adds 1 request per profile. Disable for faster runs.

## `proxy` (type: `object`):

Select proxies to be used by your crawler.

## Actor input object example

```json
{
  "country": "fr",
  "specialty": "medecin-generaliste",
  "city": "Paris",
  "viewport": {
    "northeast": {
      "lat": 49,
      "lng": 2.6
    },
    "southwest": {
      "lat": 48.6,
      "lng": 2.1
    }
  },
  "maxResults": 100,
  "scrapeProfileDetails": false,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# 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 = {
    "country": "fr",
    "specialty": "medecin-generaliste",
    "city": "Paris",
    "viewport": {
        "northeast": {
            "lat": 49,
            "lng": 2.6
        },
        "southwest": {
            "lat": 48.6,
            "lng": 2.1
        }
    },
    "maxResults": 100,
    "scrapeProfileDetails": false,
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/doctolib-fr-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 = {
    "country": "fr",
    "specialty": "medecin-generaliste",
    "city": "Paris",
    "viewport": {
        "northeast": {
            "lat": 49,
            "lng": 2.6,
        },
        "southwest": {
            "lat": 48.6,
            "lng": 2.1,
        },
    },
    "maxResults": 100,
    "scrapeProfileDetails": False,
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/doctolib-fr-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 '{
  "country": "fr",
  "specialty": "medecin-generaliste",
  "city": "Paris",
  "viewport": {
    "northeast": {
      "lat": 49,
      "lng": 2.6
    },
    "southwest": {
      "lat": 48.6,
      "lng": 2.1
    }
  },
  "maxResults": 100,
  "scrapeProfileDetails": false,
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/doctolib-fr-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/doctolib-fr-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/aCUAQ7v8BgOzelHPk/builds/KqfABcJAzQOAkdBWT/openapi.json
