# StayMatch: Three-Way Rooming List Reconciliation (`usta/staymatch-rooming-list-reconciliation`) Actor

Compare baseline, master and hotel rooming lists by reservation ID. Download proposed changes, reversible patches and unresolved conflicts. No bookings or hotel-system writes.

- **URL**: https://apify.com/usta/staymatch-rooming-list-reconciliation.md
- **Developed by:** [US Tech Automations](https://apify.com/usta) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / completed product packet

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

## StayMatch

Turn three rooming-list snapshots into reviewable changes, reversible patches and a conflict list.

### Named buyer

A hotel reservations or group-housing coordinator who must merge three rooming-list snapshots — contract baseline, internal master, and hotel — using exact reservation IDs.

This is not a property-management system. It does not talk to a hotel, book rooms, move guests, or settle contracts.

### What it does

It compares the same reservation ID across baseline, master, and hotel. Where two sides changed away from the third and disagree, the row is **unresolved**: the master record is left unchanged and a conflict is listed. You may supply `resolutions` that pick `baseline`, `master`, or `hotel` for a cell (`arrival`, `departure`, `room_type`, `room_unit`) or `__record__` for add/delete.

`PASS` means the merge packet was checked (including reversible patches). It does **not** mean every reservation is reconciled. Unresolved conflicts mean **manual review**.

Hotel room types are renamed only through the explicit `hotel_room_type_map` you provide.

### Exact limits (from the engine)

- At most **500** reservations in each snapshot (`baseline`, `master`, `hotel`)
- **1–100** `hotel_room_type_map` entries (identity mappings allowed)
- At most **1,500** resolution entries
- At least one snapshot must contain a reservation; empty lists are allowed
- IDs and room types: printable strings, 1–64 characters
- Dates: `YYYY-MM-DD`; stay length 1–365 nights; arrival inclusive, departure exclusive
- Optional `room_unit`; overlap checks run only when a unit id is supplied
- JSON input cap at the adapter: 1 MiB
- Unknown fields and non-finite numbers are refused

### Input JSON example

This is the native sample (`example.json`). Paste this object into the **payload** JSON field.

```json
{
  "synthetic": true,
  "baseline": [
    {"id": "RES-101", "arrival": "2026-11-01", "departure": "2026-11-04", "room_type": "KING", "room_unit": "ROOM-1"},
    {"id": "RES-102", "arrival": "2026-11-01", "departure": "2026-11-03", "room_type": "TWIN", "room_unit": "ROOM-2"},
    {"id": "RES-103", "arrival": "2026-11-02", "departure": "2026-11-04", "room_type": "KING", "room_unit": "ROOM-3"}
  ],
  "master": [
    {"id": "RES-101", "arrival": "2026-11-01", "departure": "2026-11-05", "room_type": "KING", "room_unit": "ROOM-1"},
    {"id": "RES-102", "arrival": "2026-11-02", "departure": "2026-11-03", "room_type": "TWIN", "room_unit": "ROOM-2"},
    {"id": "RES-103", "arrival": "2026-11-02", "departure": "2026-11-04", "room_type": "KING", "room_unit": "ROOM-3"}
  ],
  "hotel": [
    {"id": "RES-101", "arrival": "2026-11-01", "departure": "2026-11-04", "room_type": "K", "room_unit": "ROOM-1"},
    {"id": "RES-102", "arrival": "2026-10-31", "departure": "2026-11-03", "room_type": "T", "room_unit": "ROOM-2"},
    {"id": "RES-104", "arrival": "2026-11-06", "departure": "2026-11-08", "room_type": "K", "room_unit": "ROOM-4"}
  ],
  "hotel_room_type_map": {"K": "KING", "T": "TWIN"},
  "resolutions": {}
}
```

On this sample the engine reports **1 unresolved conflict** (RES-102 `arrival`: master and hotel both moved, and they disagree). RES-102 stays as the master row. RES-103 is removed in the proposed master (hotel dropped it, master matched baseline). RES-104 is added. A person still has to review the arrival conflict.

Public Apify input schema (`input_schema.json`) wraps that object as `payload` with a JSON editor. `example` and `default` are this sample. Extra fields are not documented and the engine rejects them.

### Exact artifacts

The adapter returns `status='PASS'`, the engine `summary` object, `files` (JSON/CSV/README bytes unchanged; HTML is the branded report), and `archive` (a zip of those files only).

Zip members:

| File | Contents |
| --- | --- |
| `merge.json` | Full merge evidence (entries, conflicts, patches, reverse patches, merged master, input SHA-256) |
| `merged_master.csv` | id, arrival, departure, room\_type, room\_unit, nights |
| `patch.csv` | id, before\_json, after\_json |
| `README.txt` | Limits, algorithm id, input hash, unresolved count, limitations |
| `report.html` | Branded merge report (conflicts, master, patches, USTA shell) |
| `styles.css` | Shared USTA stylesheet used by the report |

Apply a patch only if the normalized current record equals its `before` value. Reverse patches restore the original normalized master. Normalize omitted `room_unit` to null before comparing.

### What unresolved means

Unresolved records **remain unchanged in master** and receive no patch. That is a queue for **manual review**. The tool will not pick a winner, auto-book, or write back to a hotel.

### Claims this product does not make

- No hotel / PMS integration
- No auto-booking or guest-name matching (exact opaque IDs only)
- No contract, attrition, commission, billing, or payment conclusions
- Room type alone does not prove occupancy; overlap checks need `room_unit`

### Hosting

When you run this Actor, the payload is **sent to Apify**. It is not local-only. You control how long Apify keeps the run. US Tech Automations does not offer a lasting availability promise (no SLA) for Apify uptime.

### Run and download

1. Review the supported input and try the included synthetic example. Replace **payload** with your authorized records. For API runs, send an object with a single payload field containing that input.
2. Run the Actor. Open **Status and coverage** to inspect the result.
3. For a completed result, open **Download completed ZIP** or the artifact link in the dataset. Save and extract the ZIP before Apify retention expires. Open the HTML report where provided; retain the JSON and CSV evidence.

### Price and unsuccessful runs

**$0.50 per completed packet**, with one packet per run and no start fee. A retry of the same run reuses the packet and the same billing identity. Starting a separate run is a separate request. Invalid input or an incomplete UNKNOWN result produces a diagnostic without a completed-packet charge. A completed conflict or shortage report can still require manual review; PASS does not mean every business problem was resolved.

The minimum run budget is $0.50. The example is a normal run and follows the same price; it is not a free preview promise. Apify handles account billing. These files are not permanent storage: download them promptly.

### Access and support

Your input and output are processed on Apify under the run owner's account. Use authorized data and opaque IDs; do not upload passwords or sensitive personal records. Treat artifact URLs as access-bearing links and share them only intentionally. The USTA report may fetch the Satoshi font; it does not upload your report. For a product issue, use this Actor's Issues tab with the run ID and a redacted example. Never post private input or access-bearing links in a public issue.

# Actor input Schema

## `payload` (type: `object`):

Exact StayMatch object. Unknown fields are rejected by the native engine. Limits from code: at most 500 reservations per snapshot (baseline, master, hotel), 1–100 hotel\_room\_type\_map entries, at most 1500 resolutions, IDs 1–64 printable characters, stays 1–365 nights with YYYY-MM-DD dates (arrival inclusive, departure exclusive). At least one snapshot must contain a reservation. Empty lists are allowed.

## Actor input object example

```json
{
  "payload": {
    "synthetic": true,
    "baseline": [
      {
        "id": "RES-101",
        "arrival": "2026-11-01",
        "departure": "2026-11-04",
        "room_type": "KING",
        "room_unit": "ROOM-1"
      },
      {
        "id": "RES-102",
        "arrival": "2026-11-01",
        "departure": "2026-11-03",
        "room_type": "TWIN",
        "room_unit": "ROOM-2"
      },
      {
        "id": "RES-103",
        "arrival": "2026-11-02",
        "departure": "2026-11-04",
        "room_type": "KING",
        "room_unit": "ROOM-3"
      }
    ],
    "master": [
      {
        "id": "RES-101",
        "arrival": "2026-11-01",
        "departure": "2026-11-05",
        "room_type": "KING",
        "room_unit": "ROOM-1"
      },
      {
        "id": "RES-102",
        "arrival": "2026-11-02",
        "departure": "2026-11-03",
        "room_type": "TWIN",
        "room_unit": "ROOM-2"
      },
      {
        "id": "RES-103",
        "arrival": "2026-11-02",
        "departure": "2026-11-04",
        "room_type": "KING",
        "room_unit": "ROOM-3"
      }
    ],
    "hotel": [
      {
        "id": "RES-101",
        "arrival": "2026-11-01",
        "departure": "2026-11-04",
        "room_type": "K",
        "room_unit": "ROOM-1"
      },
      {
        "id": "RES-102",
        "arrival": "2026-10-31",
        "departure": "2026-11-03",
        "room_type": "T",
        "room_unit": "ROOM-2"
      },
      {
        "id": "RES-104",
        "arrival": "2026-11-06",
        "departure": "2026-11-08",
        "room_type": "K",
        "room_unit": "ROOM-4"
      }
    ],
    "hotel_room_type_map": {
      "K": "KING",
      "T": "TWIN"
    },
    "resolutions": {}
  }
}
```

# Actor output Schema

## `packet` (type: `string`):

No description

## `report` (type: `string`):

No description

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

// Run the Actor and wait for it to finish
const run = await client.actor("usta/staymatch-rooming-list-reconciliation").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("usta/staymatch-rooming-list-reconciliation").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 usta/staymatch-rooming-list-reconciliation --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,usta/staymatch-rooming-list-reconciliation"
        }
    }
}
```

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/9IBlYzOmdlkzHWrP4/builds/MqmXvZa8gHIM3wUei/openapi.json
