# Rental Calendar Sync Check (`tharjaken/rental-calendar-sync-check`) Actor

Compare blocked nights in two all-day iCalendar exports for one rental property. Find dates blocked in only one calendar. Includes HTML and JSON reports without guest names or event notes.

- **URL**: https://apify.com/tharjaken/rental-calendar-sync-check.md
- **Developed by:** [Tharjaken](https://apify.com/tharjaken) (community)
- **Categories:**
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / completed comparison

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

## Rental Calendar Sync Check

Compare two all-day iCalendar (.ics) exports for the **same rental property**. Find nights blocked in only calendar A, only calendar B, or both calendars. Use the report to review calendar differences before changing availability.

This is a snapshot comparison. It does not connect to a rental platform, refresh feeds, synchronize calendars, change availability, identify actual reservations or establish double bookings. Matching blocked dates do not prove that the exports are fresh or complete. No affiliation with a booking platform is claimed.

### Quick start

1. Obtain two .ics exports you are permitted to process, from calendars for the same property. Remove guest names, contact information, private notes and feed URLs before uploading; keep occupancy dates, UIDs, status and transparency properties intact.
2. Paste their text into **Calendar A** and **Calendar B**. Replace both fictional examples.
3. Choose the first night and the exclusive end date in `YYYY-MM-DD` format, covering 1 to 366 nights. September 10 to September 13 compares the nights of September 10, 11 and 12.
4. Check the current price and spending cap. Run the comparison and open **Readable report (HTML)** or **Full report (JSON)**.

The dataset has one summary item and a `report_json` string containing the full report. Grouped date ranges use an inclusive start and exclusive end. Shared blocks are listed as shared, not classified as conflicting reservations. A difference may be intentional or caused by export/sync timing; investigate it on the original platforms.

### Supported calendars

Each input must contain one UTF-8 `VERSION:2.0` VCALENDAR, at most 256 KiB and 1,000 VEVENTs. Only all-day `DTSTART;VALUE=DATE` events are supported. A corresponding all-day DTEND is exclusive. If no end or duration is present, an event lasts one day. Positive whole-day/week durations such as `P2D` or `P1W` are supported. An unfolded line is limited to 8,192 characters.

Cancelled and transparent events do not block nights. Tentative events count as blocked and produce a warning. Overlapping entries are combined into occupied-night sets. An empty calendar is allowed but explicitly warns that completeness needs checking. UTF-8 BOM, CRLF/LF endings and folded lines are supported. Alarm and time-zone metadata are ignored because occupancy is restricted to calendar dates.

Timed events, recurrence rules/dates/exceptions, duplicate UIDs, repeated occupancy properties, scheduling messages and unsupported components are rejected. Expand recurring events and resolve revisions before comparing. Unsupported events are rejected even outside the comparison window. This is a restricted occupancy reader, not a complete iCalendar validator; provider-specific booking rules are outside its scope. URLs and uploaded binary files are not supported in this version.

### Billing and recovery

The Store pricing panel is the source of truth. One completed comparison requests one `comparison-completed` event after the HTML and JSON reports are saved, including when blocked dates match. Invalid input does not request a comparison event. A budget below one comparison stops publication before a charge request. Any platform charges are shown by Apify before execution.

A restart with the same input and an existing report retains it without requesting another event. Uncertain interrupted publication stops automatic recharging. Check the original run’s output and billing before starting a separate run, which is a separate comparison. A network failure may leave a delivered report even when the run fails; failed status does not prove there was no charge.

### Privacy

Processing occurs on Apify. The two calendar inputs use secret input fields but must be decrypted to compare dates. Original input storage can contain private calendar content. The report omits guest names, descriptions, UIDs, calendar names and feed URLs; it contains dates, counts and fixed explanations. Reports are not encrypted by this Actor.

Only the current run’s default storage is used. No guest data is sent to AI, no calendar URL is fetched, and no separate customer database is maintained. Application logs omit calendar text. Access and retention depend on your Apify settings. Delete the run’s input/output key-value store and dataset when no longer needed; immediate or automatic deletion is not promised. Treat storage links as sensitive.

### Support

Use the Actor’s **Issues** tab with a run ID and a small fictional example. Never post guest information or private feed links. Suspected incorrect charges should identify the original run/event so they can be reviewed through Apify. Refunds and support follow the applicable platform terms. This pilot does not offer instant support.

Pilot version 0.1. Review the original calendars before acting on the results.

# Actor input Schema

## `calendarA` (type: `string`):

Paste iCalendar text, not a URL. Maximum 256 KiB and 1,000 events. All-day VALUE=DATE only; recurring/timed events and duplicate UIDs are rejected.

## `calendarB` (type: `string`):

Paste iCalendar text, not a URL. Maximum 256 KiB and 1,000 events. All-day VALUE=DATE only; recurring/timed events and duplicate UIDs are rejected.

## `windowStart` (type: `string`):

The window must cover 1 to 366 nights. This is a calendar date, without a time or time zone.

## `windowEnd` (type: `string`):

The window must cover 1 to 366 nights. This is a calendar date, without a time or time zone.

## Actor input object example

```json
{
  "calendarA": "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Fictional test//EN\nBEGIN:VEVENT\nUID:fictional-1\nDTSTART;VALUE=DATE:20260910\nDTEND;VALUE=DATE:20260913\nSUMMARY:Fictional block A\nEND:VEVENT\nEND:VCALENDAR\n",
  "calendarB": "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Fictional test//EN\nBEGIN:VEVENT\nUID:fictional-1\nDTSTART;VALUE=DATE:20260912\nDTEND;VALUE=DATE:20260915\nSUMMARY:Fictional block B\nEND:VEVENT\nEND:VCALENDAR\n",
  "windowStart": "2026-09-01",
  "windowEnd": "2026-10-01"
}
```

# Actor output Schema

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

No description

## `readableReport` (type: `string`):

No description

## `jsonReport` (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 = {
    "calendarA": `BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Fictional test//EN
BEGIN:VEVENT
UID:fictional-1
DTSTART;VALUE=DATE:20260910
DTEND;VALUE=DATE:20260913
SUMMARY:Fictional block A
END:VEVENT
END:VCALENDAR`,
    "calendarB": `BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Fictional test//EN
BEGIN:VEVENT
UID:fictional-1
DTSTART;VALUE=DATE:20260912
DTEND;VALUE=DATE:20260915
SUMMARY:Fictional block B
END:VEVENT
END:VCALENDAR`,
    "windowStart": "2026-09-01",
    "windowEnd": "2026-10-01"
};

// Run the Actor and wait for it to finish
const run = await client.actor("tharjaken/rental-calendar-sync-check").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 = {
    "calendarA": """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Fictional test//EN
BEGIN:VEVENT
UID:fictional-1
DTSTART;VALUE=DATE:20260910
DTEND;VALUE=DATE:20260913
SUMMARY:Fictional block A
END:VEVENT
END:VCALENDAR
""",
    "calendarB": """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Fictional test//EN
BEGIN:VEVENT
UID:fictional-1
DTSTART;VALUE=DATE:20260912
DTEND;VALUE=DATE:20260915
SUMMARY:Fictional block B
END:VEVENT
END:VCALENDAR
""",
    "windowStart": "2026-09-01",
    "windowEnd": "2026-10-01",
}

# Run the Actor and wait for it to finish
run = client.actor("tharjaken/rental-calendar-sync-check").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 '{
  "calendarA": "BEGIN:VCALENDAR\\nVERSION:2.0\\nPRODID:-//Fictional test//EN\\nBEGIN:VEVENT\\nUID:fictional-1\\nDTSTART;VALUE=DATE:20260910\\nDTEND;VALUE=DATE:20260913\\nSUMMARY:Fictional block A\\nEND:VEVENT\\nEND:VCALENDAR\\n",
  "calendarB": "BEGIN:VCALENDAR\\nVERSION:2.0\\nPRODID:-//Fictional test//EN\\nBEGIN:VEVENT\\nUID:fictional-1\\nDTSTART;VALUE=DATE:20260912\\nDTEND;VALUE=DATE:20260915\\nSUMMARY:Fictional block B\\nEND:VEVENT\\nEND:VCALENDAR\\n",
  "windowStart": "2026-09-01",
  "windowEnd": "2026-10-01"
}' |
apify call tharjaken/rental-calendar-sync-check --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tharjaken/rental-calendar-sync-check"
        }
    }
}

```

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/PrvgwHifl2uFRb7Tk/builds/EQo1RG2LJck8DwWLD/openapi.json
