# Doctoralia Doctor Schedule Monitor (`scrapers_lat/doctoralia-doctor-schedule-monitor`) Actor

Monitor one Doctoralia doctor's appointment calendar. Every run returns booked vs free 30-minute slots with datetime, location and booking status, plus change detection (new bookings and cancellations) since the previous run for calendar sync.

- **URL**: https://apify.com/scrapers\_lat/doctoralia-doctor-schedule-monitor.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (community)
- **Categories:** Automation, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $25.00 / 1,000 slot records

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?

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

[![Doctoralia Doctor Schedule Monitor](https://scrapers.lat/banners/doctoralia-doctor-schedule-monitor.png)](https://console.apify.com/actors/wTcWNYbOYs9ygFMQd/input)

## Doctoralia Doctor Schedule Monitor

Keep a scheduling agent, CRM or calendar in sync with **one doctor's Doctoralia appointment calendar**. Point the actor at a single Doctoralia profile URL and every run reads that doctor's 30-minute slots across all of their active calendars, tells you which are **booked** and which are **free**, and detects what **changed since the last run** (new bookings and cancellations). Built to run on a short cron (for example every 30 minutes) so an automation agent always has the current state of the calendar.

HTTP-only and fast. No browser, no login to the doctor's Doctoralia account required.

Here is one real record the actor returns (a currently booked slot):

```json
{
  "doctorName": "Dr. Diego Armando Huertas Castelli",
  "doctorId": "75266",
  "doctorUrl": "https://www.doctoralia.co/perfil/diego-armando-huertas-castelli",
  "addressId": "85713",
  "locationName": "Psi, Diego Armando Huertas Castelli. Psicología y Coaching.",
  "city": "Bogotá",
  "address": "Psi, Diego Armando Huertas Castelli. Psicología y Coaching.",
  "onlineOnly": false,
  "specialty": "Psicólogo",
  "slotStart": "2026-08-19T19:00:00-05:00",
  "slotDate": "2026-08-19",
  "slotTime": "19:00",
  "status": "booked",
  "changeType": "new_booking",
  "bookingUrl": null,
  "observedAt": "2026-08-19T23:21:48.327Z"
}
```

### What you get

For every appointment slot in your date window, one record with the slot datetime (with timezone), whether it is booked or free, the location it belongs to, and how it changed since the previous run. Free slots include the public booking URL.

### Input

| Field | Type | Description |
|-------|------|-------------|
| `doctorUrl` | string | Full Doctoralia profile URL of the doctor to monitor, for example `https://www.doctoralia.co/perfil/diego-armando-huertas-castelli`. Recommended. |
| `doctorSlug` | string | Alternative to `doctorUrl`: the profile slug (for example `diego-armando-huertas-castelli`), combined with `country` to build the URL. |
| `country` | enum | Country domain used only when building the URL from `doctorSlug`: `co`, `mx`, `es`, `ar`, `cl`, `pe`, `br`. Default `co`. |
| `daysAhead` | integer | How many days of calendar to read from today (1 to 60). Default `7`. |
| `output` | enum | `changes` (only slots whose status changed since the last run, for a cron), `booked` (all currently booked slots), or `all` (full grid of booked and free). Default `changes`. |
| `maxSlots` | integer | Safety cap on records emitted per run. Default `500`. |

### Output

| Field | Description |
|-------|-------------|
| `doctorName` | Doctor display name (public). |
| `doctorId` | Doctoralia doctor id. |
| `doctorUrl` | Profile URL monitored. |
| `addressId` | Calendar / location id the slot belongs to. |
| `locationName` | Clinic / location name. |
| `city` | City. |
| `address` | Address text. |
| `onlineOnly` | `true` for an online-only calendar. |
| `specialty` | Doctor specialty when available. |
| `slotStart` | Slot start as returned, ISO 8601 with timezone (for example `2026-08-19T19:00:00-05:00`). |
| `slotDate` | Slot date `YYYY-MM-DD`. |
| `slotTime` | Slot time `HH:MM`. |
| `status` | `booked` or `free`. |
| `changeType` | `new_booking`, `cancellation`, `existing` (first run only), or `unchanged`. |
| `bookingUrl` | Public booking URL (present for free slots only). |
| `observedAt` | When this run observed the calendar (ISO). |

### How change detection works

The actor remembers the set of booked slots from the previous run for each doctor (stored in a persistent key-value store keyed by doctor id). On the next run it compares:

- a slot booked now but not before becomes `new_booking`,
- a slot that was booked before and is now free becomes `cancellation`,
- on the very first run there is no history, so every currently booked slot is emitted once as `existing` to let you seed your calendar.

In `output: "changes"` mode an idle poll with no calendar movement returns zero records, so your cron only produces data (and cost) when something actually changed.

### Use cases

- **Schedule sync**: keep a scheduling-automation agent, Google Calendar or CRM continuously in sync with a doctor's real Doctoralia bookings on a 30-minute cron.
- **Double-booking prevention**: know the moment a slot fills up so your own booking flow never offers a time that is already taken.
- **Appointment monitoring**: track new bookings and cancellations over the day for reminders, waitlist fills or staffing.

### Recommended setup for a 30-minute sync

1. Set `doctorUrl` to your doctor's Doctoralia profile URL.
2. Set `output` to `changes` and `daysAhead` to `7`.
3. Schedule the actor to run every 30 minutes.

Each tick returns only new bookings and cancellations since the previous tick, which your agent applies to its calendar.

### Billing

This actor uses pay per event:

| Event | Price | When |
|-------|-------|------|
| `apify-actor-start` | $0.02 | Once per run, charged when the monitor starts and polls the calendar. Covers the poll and change computation even when there are no new bookings. |
| `result` | $0.03 | Once per emitted slot record. |

In the default `changes` mode, a run where nothing changed emits zero records and costs only the one run-start event. Runs never charge the `result` event on failure, and free Apify accounts are capped at 10 billable records per run.

### Honest note on patient data

This actor reads only what Doctoralia publishes on the public profile and calendar: the slot datetime, whether it is booked or free, and the location. The **patient name, phone and WhatsApp are not included**, because that information is private and only exists inside the doctor's own logged-in Doctoralia account. It is not part of the public data and this actor does not fabricate it. The actor tells you a slot is taken and when; it does not tell you who booked it.

# Actor input Schema

## `doctorUrl` (type: `string`):

Full Doctoralia profile URL of the doctor to monitor, e.g. https://www.doctoralia.co/perfil/diego-armando-huertas-castelli . This is the recommended input. If empty, provide Doctor slug + Country below.

## `doctorSlug` (type: `string`):

Optional. The doctor's profile slug, e.g. diego-armando-huertas-castelli. Combined with Country to build the profile URL when Doctor profile URL is empty.

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

Doctoralia country domain, used only when building the URL from Doctor slug.

## `daysAhead` (type: `integer`):

How many days of calendar to read from today (1 to 60). For a 30-minute sync cron, 7 is a good default.

## `output` (type: `string`):

changes = only slots whose booked status changed since the previous run (new bookings + cancellations); this is what a 30-minute cron should consume. booked = every currently booked slot. all = the full grid (booked + free).

## `maxSlots` (type: `integer`):

Safety cap on how many slot records to emit in one run.

## Actor input object example

```json
{
  "doctorUrl": "https://www.doctoralia.co/perfil/diego-armando-huertas-castelli",
  "country": "co",
  "daysAhead": 7,
  "output": "changes",
  "maxSlots": 500
}
```

# 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 = {
    "doctorUrl": "https://www.doctoralia.co/perfil/diego-armando-huertas-castelli",
    "country": "co",
    "daysAhead": 7,
    "output": "changes",
    "maxSlots": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/doctoralia-doctor-schedule-monitor").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 = {
    "doctorUrl": "https://www.doctoralia.co/perfil/diego-armando-huertas-castelli",
    "country": "co",
    "daysAhead": 7,
    "output": "changes",
    "maxSlots": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/doctoralia-doctor-schedule-monitor").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 '{
  "doctorUrl": "https://www.doctoralia.co/perfil/diego-armando-huertas-castelli",
  "country": "co",
  "daysAhead": 7,
  "output": "changes",
  "maxSlots": 500
}' |
apify call scrapers_lat/doctoralia-doctor-schedule-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapers_lat/doctoralia-doctor-schedule-monitor"
        }
    }
}

```

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/wTcWNYbOYs9ygFMQd/builds/75GrsSq22b4qI4b1u/openapi.json
