hospitable.heal_messages
Recover this tenant's Hospitable MESSAGE backlog — messages the 15-min poll-reconcile can no longer reach because their reservation aged past its rolling 14-day lookback window (e.g. messages created between the historical backfill snapshot and live-capture go-live). Walks hospitable_property_mappings, pages reservations over a WIDE lookbackDays window, and — comparing each reservation's Hospitable last_message_at against the latest message Foyer has stored — re-ingests ONLY the drifted ones through the idempotent shared path (no AI replay, no duplicates). Pass dryRun=true to count drifted reservations without writing. Returns { ok:true, reservationsScanned, drifted, messagesRecovered, sample } or { ok:false, reason, message }. Mutating (unless dryRun) — requires _confirm: true.
Input parameters
| Field | Type | Required | Notes |
|---|---|---|---|
lookbackDays | integer | no | Default: 60 |
dryRun | boolean | no | Default: false |
Output fields
One of 2 shapes, depending on the outcome:
Shape 1
| Field | Type | Required | Notes |
|---|---|---|---|
ok | literal | yes | One of: true |
reservationsScanned | integer | yes | |
drifted | integer | yes | |
messagesRecovered | integer | yes | |
sample | array of object | yes | |
sample.reservationUuid | string | yes | |
sample.hospitableLastMessageAt | string | yes | |
sample.foyerLastMessageAt | string · nullable | yes | |
sample.recovered | integer | yes | |
dryRun | boolean | yes |
Shape 2
| Field | Type | Required | Notes |
|---|---|---|---|
ok | literal | yes | One of: false |
reason | enum | yes | One of: no_api_key, auth_failed, api_error, internal |
message | string | yes |
hospitable.import_reservations
Backfill this tenant's Hospitable reservations into Foyer stays (+ minimal guests), so a newly connected hotel doesn't start with an empty calendar. Walks the tenant's hospitable_property_mappings and queries reservations per mapped property; unmapped properties are never imported. Idempotent on (tenant, ota_source='hospitable', reservation.code) — re-running updates rather than duplicates. Pass dryRun=true to count would-create/would-update without writing. Returns either { ok: true, ...counts, sample } or { ok: false, reason, message }. Mutating action (unless dryRun) — requires _confirm: true.
Input parameters
| Field | Type | Required | Notes |
|---|---|---|---|
lookbackDays | integer | no | Default: 365 |
dryRun | boolean | no | Default: false |
Output fields
One of 2 shapes, depending on the outcome:
Shape 1
| Field | Type | Required | Notes |
|---|---|---|---|
ok | literal | yes | One of: true |
propertiesQueried | integer | yes | |
reservationsFetched | integer | yes | |
staysCreated | integer | yes | |
staysUpdated | integer | yes | |
guestsCreated | integer | yes | |
skipped | array of object | yes | |
skipped.code | string | yes | |
skipped.reason | string | yes | |
sample | array of object | yes | |
sample.code | string | yes | |
sample.room | string | yes | |
sample.action | string | yes | |
sample.status | string | yes | |
dryRun | boolean | yes |
Shape 2
| Field | Type | Required | Notes |
|---|---|---|---|
ok | literal | yes | One of: false |
reason | enum | yes | One of: no_api_key, auth_failed, api_error, internal |
message | string | yes |
hospitable.resync_reservation
Re-pull ONE Hospitable reservation's messages into Foyer on demand — the targeted fix for a reservation the 15-min poll-reconcile can no longer reach (it aged past the rolling 14-day lookback). Fetches every message on the reservation and re-ingests through the idempotent shared path (no AI replay, no duplicates), so re-running is a no-op. Takes the reservation UUID (NOT the reservation code). Returns { ok:true, messagesSeen, messagesInserted, skipped } or { ok:false, reason, message }. Mutating — requires _confirm: true.
Input parameters
| Field | Type | Required | Notes |
|---|---|---|---|
reservationUuid | string | yes |
Output fields
One of 2 shapes, depending on the outcome:
Shape 1
| Field | Type | Required | Notes |
|---|---|---|---|
ok | literal | yes | One of: true |
messagesSeen | integer | yes | |
messagesInserted | integer | yes | |
skipped | integer | yes |
Shape 2
| Field | Type | Required | Notes |
|---|---|---|---|
ok | literal | yes | One of: false |
reason | enum | yes | One of: no_api_key, auth_failed, api_error, internal |
message | string | yes |