Channel Manager

Connect your property to online travel agencies (OTAs) like Booking.com, Expedia, Agoda, and Airbnb. The channel manager syncs availability, rates, and reservations automatically through ChanneX middleware, with AI-powered room mapping, rate suggestions, and error diagnosis.

Where to find it

Settings → Integrations → Channel Manager. The channel manager lives under Settings because it is configuration-oriented. OTA reservations flow into your normal hotel views (Front Desk, Reservations) automatically once ingested.

Overview

The channel manager is built on a provider-agnostic abstraction. The first supported provider is ChanneX, which connects to 200+ OTAs through a single integration. The architecture supports adding direct OTA APIs (Booking.com Direct, Expedia Direct) or other middleware (SiteMinder) as drop-in providers.

What Gets Synced

DataDirectionFrequencySource of Truth
AvailabilityPush (PMS → OTA)Every 15 minResource count minus active allocations
RatesPush (PMS → OTA)Every 30 minRate Calendar (overrides) + base price
RestrictionsPush (PMS → OTA)On changeStop sell, min/max stay, CTA/CTD
ReservationsPull (OTA → PMS)Webhook + poll every 5 minOTA booking → MasterReservation

Setting Up a Channel Connection

The setup wizard guides you through connecting an OTA in 4 steps. AI auto-maps your room types to reduce manual work.

Step 1: Choose Provider

Select your channel manager provider. Currently supported: ChanneX. Future providers (SiteMinder, Booking.com Direct, Expedia Direct) will appear here as they are added.

Step 2: Enter Credentials

  1. Enter a Connection Name (e.g. "ChanneX - Main Property")
  2. Enter your API Key from the provider dashboard
  3. Enter your External Property ID (the property ID in the provider system)
  4. Click Test Connection to verify credentials are valid

The system validates credentials against the provider API. If successful, you see the property name and can proceed. If it fails, check that the API key is active and the property ID is correct.

Step 3: Map Room Types

The system fetches room types from the channel and your local services (room types). AI auto-mapping matches them by name similarity and suggests mappings with confidence scores. You review the mapping table and adjust if needed.

  • Each local room type maps to one external room type
  • Unmapped room types are listed separately so you can add them manually
  • You can skip mappings for room types you don't want to sell on that OTA

Step 4: Confirm & Connect

Review the configuration summary and click Create Connection. The system creates the connection, saves room type mappings, generates a webhook URL for receiving OTA bookings, and triggers an initial availability sync.

Dashboard

The channel manager dashboard (Settings → Integrations → Channel Manager) shows:

  • Connection Status Cards — One per connection, color-coded (green = connected, yellow = pending, red = error), with last sync time and error count
  • OTA Bookings Today / This Week — Count of incoming OTA reservations
  • Sync Success Rate — Percentage of successful syncs over the last 7 days
  • Pending Errors — Number of unresolved sync failures
  • Quick Actions — "Add Channel" and "Refresh" buttons

Rate Calendar

The rate calendar shows a grid of room types (rows) vs dates (columns). Each cell shows the effective nightly rate.

How Rates Work

  • Base Price — Set on the Rate Plan. Used when no calendar override exists for a date
  • Calendar Override — Per-date price set manually or by AI. Overrides the base price
  • Channel Markup — Optional per-channel markup (percentage or fixed amount) applied on top of the effective rate
  • Effective Rate = (Calendar Override ?? Base Price) + Channel Markup

Editing Rates

  1. Click any cell in the rate calendar grid
  2. Enter the new price in the inline editor
  3. Press Enter to save or Escape to cancel
  4. The rate is saved as a "MANUAL" override and will be pushed to channels on the next rate sync

Rate Plan Types

TypeDescription
STANDARDDefault flexible rate with standard cancellation
NON_REFUNDABLEDiscounted rate (typically 10% off), no cancellation
EARLY_BIRDDiscount for booking far in advance
LAST_MINUTEDiscounted rate for bookings within a few days
LONG_STAYDiscount for extended stays (7+ nights)
PROMOTIONALSpecial offer or seasonal promotion

Visual Legend

  • Amber background — Custom rate override (manual or accepted AI suggestion)
  • Blue background — AI-suggested rate (pending acceptance)
  • Gray background — Weekend
  • Regular text = base price (no override)
  • Bold text = override price

AI Features

The channel manager includes three AI-powered capabilities.

AI Room Type Mapping

During setup, AI reads your local room types and the channel's room types and auto-matches them by name, description, and capacity. Each match includes a confidence score (0.5–1.0) and explanation. You review and confirm the mapping table instead of manually dragging and dropping.

AI Rate Intelligence

AI analyzes your occupancy history (last 90 days by day-of-week), upcoming occupancy levels, and current rate overrides to suggest optimal nightly rates. Suggestions follow these rules:

  • High occupancy (>80%) = increase rate 10–30%
  • Low occupancy (<40%) = decrease rate 5–15%
  • Weekend premium of 10–20%
  • Never below 60% of base price (floor)
  • Never above 200% of base price (ceiling)

Suggestions appear in the rate calendar with a blue "AI" indicator. Accept or reject each suggestion individually.

AI Error Diagnosis

When a sync fails, AI analyzes the error details and provides a human-readable diagnosis with root cause, severity level, and specific action items. Common diagnoses include:

  • 401/403 → API credentials invalid or expired
  • 404 → Property or room type not found on channel
  • 429 → Rate limiting, wait and retry
  • 5xx / timeout → Channel provider temporarily down

Qvi (AI Assistant) Integration

You can interact with the channel manager through the Qvi AI assistant. Examples:

  • "What's my channel sync status?" → Shows connection health table
  • "Why did the last sync fail?" → AI error diagnosis
  • "How many OTA bookings this week?" → Booking stats by channel
  • "Set Ocean View to $150 for Christmas week" → Creates rate calendar entries
  • "Stop selling Standard Rooms tomorrow" → Creates stop-sell restriction
  • "Sync now" → Triggers immediate availability push

OTA Reservations

Incoming OTA reservations are received via webhook or polling, and automatically converted into standard reservations.

Ingestion Flow

  1. OTA sends booking via webhook (or it is polled every 5 minutes)
  2. System verifies webhook signature and checks for duplicate (idempotency)
  3. Creates a ChannelReservation record with the raw OTA payload
  4. Maps the external room type to a local service via room type mappings
  5. Finds or creates the guest as a TradingPartner
  6. Calls the standard ReservationService.createReservation() to create a MasterReservation
  7. All normal accounting, tax, resource allocation, and fulfillment flows apply
  8. Triggers an availability re-sync to update all channels

OTA reservations appear in the Reservations list and Front Desk like any other booking, with a channelSource field indicating the origin (e.g. "booking_com").

OTA Reservations Tab

The OTA Reservations tab (Channel Manager → Reservations) shows a dedicated list of OTA bookings with:

  • Channel badge (color-coded: blue for Booking.com, yellow for Expedia, etc.)
  • Guest name and email
  • Check-in / check-out dates
  • Total amount and commission
  • Status (Pending, Confirmed, Modified, Cancelled)
  • Link to the master reservation (once processed)

Filter by channel or status using the dropdown filters.

Sync Monitor

The sync monitor (Channel Manager → Sync Monitor) shows a log of all sync operations with:

  • Time — When the sync ran
  • Type — AVAILABILITY, RATES, RESTRICTIONS, or RESERVATIONS
  • Direction — PUSH (to OTA) or PULL (from OTA)
  • Status — SUCCESS, IN_PROGRESS, PENDING, PARTIAL_FAILURE, or FAILED
  • Items — Success count / total count, with failure count highlighted
  • Duration — How long the sync took
  • Triggered By — CRON (automatic), MANUAL (user-triggered), or WEBHOOK

Filter by connection and sync type. Failed syncs show error details inline.

Auto-Suspension

If a connection accumulates 10+ consecutive errors, the system automatically suspends it to prevent further failed API calls. The hourly health check cron monitors all connections and flags stale syncs (no sync in 2+ hours).

Restrictions

Restrictions control selling rules per room type and date. They are pushed to channels alongside rates.

RestrictionEffect
Stop SellRoom type cannot be booked on this date
Closed to Arrival (CTA)Guests cannot check in on this date
Closed to Departure (CTD)Guests cannot check out on this date
Min StayMinimum number of nights required
Max StayMaximum number of nights allowed

Managing Connections

Connection Detail Page

Click a connection to see its detail page, which shows:

  • Connection status and last sync times
  • Room type mappings (local service ↔ external room type)
  • Rate plan mappings (local rate plan ↔ external rate plan with optional markup)
  • Manual sync buttons (Sync Availability, Sync Rates, Sync Restrictions)
  • Disconnect button (soft-deletes the connection)

Connection Statuses

StatusMeaning
PENDING_SETUPConnection created but not yet tested / synced
CONNECTEDActive and syncing normally
ERRORLast sync failed, will retry
SUSPENDEDAuto-suspended after 10+ errors
DISCONNECTEDManually disconnected, no longer syncing

Webhook Integration

Each connection gets a unique webhook URL for receiving real-time reservation notifications from the channel provider.

Webhook URL format
POST /webhooks/channel-manager/:channelConnectionId

The webhook endpoint:

  1. Loads the connection and determines the provider type
  2. Verifies the request signature using the connection's webhook secret
  3. Checks idempotency (prevents duplicate processing of the same event)
  4. Routes the event: new booking → ingestion, modification → update, cancellation → cancel
  5. Triggers an availability re-sync after any reservation change

Register this webhook URL in your channel provider's dashboard (e.g. ChanneX property settings).

GraphQL API Reference

The channel manager exposes these GraphQL queries and mutations. All require JWT authentication.

Queries

QueryDescription
channelManagerDashboard(businessUnitId)Dashboard with connections, booking counts, sync rate
channelConnections(businessUnitId)List all connections for a business unit
channelConnection(id)Single connection with mappings
externalRoomTypes(channelConnectionId)Fetch room types from the channel
ratePlans(businessUnitId)List rate plans
rateCalendar(input)Rate plans with calendar entries for a date range
channelReservations(input)List OTA reservations with filters
channelSyncLogs(input)Sync history log
aiRateSuggestions(businessUnitId, serviceId, startDate, endDate)AI-generated rate suggestions for a date range
aiDiagnoseChannelError(businessUnitId, channelConnectionId?)AI diagnosis of latest sync error
aiChannelSetupSuggestions(businessUnitId, channelConnectionId)AI-suggested room type mappings and rate plans

Mutations

MutationDescription
testChannelConnection(input)Test credentials without creating a connection
createChannelConnection(input)Create a new OTA connection
updateChannelConnection(id, input)Update connection settings
deleteChannelConnection(id)Soft-delete (disconnect) a connection
bulkCreateRoomTypeMappings(input)Map multiple room types at once
createRatePlan(input)Create a rate plan for a room type
setRateCalendar(input)Set per-date rate overrides
syncChannelAvailability(channelConnectionId)Trigger manual availability push
syncChannelRates(channelConnectionId)Trigger manual rate push
syncChannelRestrictions(channelConnectionId)Trigger manual restriction push

Data Model

The channel manager adds 8 database tables and 5 enums.

Tables

TablePurpose
channel_connectionsOTA connection per business unit (credentials, status, sync settings)
channel_room_type_mappingsMaps local Service to channel room type code
rate_plansRate plans per room type (Standard, Non-Refundable, etc.)
rate_calendarPer-date rate overrides with source tracking
channel_rate_plan_mappingsMaps local rate plan to channel rate plan + markup
channel_restrictionsPer-date selling restrictions (stop sell, min/max stay)
channel_reservationsIncoming OTA reservations with raw payload
channel_sync_logsAudit trail for all sync operations

Cron Jobs

CronSchedulePurpose
Availability SyncEvery 15 minPush availability to all connected channels
Rate Sync:05 and :35 of every hourPush rate changes to channels
Reservation PollEvery 5 minPoll channels for new reservations
Health CheckEvery hourCheck for stale syncs, auto-suspend failing connections

Troubleshooting

Connection test fails

  • Verify the API key is correct and active in your ChanneX dashboard
  • Verify the property ID matches exactly (case-sensitive)
  • Check that your ChanneX subscription is active

Availability not updating on OTAs

  • Check that the connection status is CONNECTED (not ERROR or SUSPENDED)
  • Check the Sync Monitor for recent AVAILABILITY sync failures
  • Verify room type mappings exist (unmapped room types are not synced)
  • Try a manual sync from the connection detail page

OTA bookings not appearing

  • Verify the webhook URL is registered in ChanneX
  • Check the OTA Reservations tab for pending or errored bookings
  • Check that the external room type in the booking maps to a local service
  • The reservation poll cron (every 5 min) is a fallback if webhooks are not configured

Connection auto-suspended

If a connection reaches 10+ consecutive errors, the hourly health check suspends it. To fix:

  1. Go to the connection detail page
  2. Review the error message and sync logs
  3. Fix the underlying issue (usually credentials or property ID)
  4. Click Test Connection to verify it works
  5. The connection will be reactivated on successful test

Related