Channel management, unified guest inbox, dynamic pricing, automated check-in with smart-lock integration, turnover operations and owner payouts — a standalone WaoBiz module.
The Shortlets module (WaoShortlet) turns WaoBiz into a short-term rental management system for serviced apartments, holiday lets and Airbnb-style properties. It covers six areas:
| Feature | What it does |
|---|---|
| Channel Manager | Keeps calendars in step across Airbnb, Booking.com, Vrbo and your direct booking page so the same night is never sold twice. |
| Unified Inbox | Collects guest messages from every channel into one conversation list. |
| Dynamic Pricing | Adjusts nightly rates by occupancy, lead time, day of week and season — with an optional AI refinement pass. |
| Automated Check-In | Sends directions, house rules, WiFi and the door code on a schedule before arrival. |
| Cleaning & Operations | Creates and assigns a turnover clean the moment a guest checks out. |
| Financial Reporting | Tracks ADR, RevPAR, occupancy and margin, and produces owner payout statements. |
Shortlets owns its own properties and reservations. It does not require the hotel module: you can license Shortlets on its own, HMS on its own, or both.
Only one: Shortlets enabled on your subscription plan. Everything else — properties, rates, bookings — is created inside the module.
Shortlets has ten permissions, assignable per role under User Management → Roles in the Shortlets group.
| Permission | Grants access to |
|---|---|
shortlet_view | Read-only access to every shortlet screen. Required for all other permissions to be useful. |
shortlet_manage_bookings | Take bookings, check guests in and out, record payments, block dates. |
shortlet_manage_units | Create and edit units and property owners. |
shortlet_manage_channels | Connect channels, map listings, trigger syncs and rate pushes. |
shortlet_manage_pricing | Create pricing rules, run repricing, set manual rate overrides. |
shortlet_manage_inbox | Reply to guests and change thread status. |
shortlet_manage_automations | Edit message templates, connect smart locks, issue and revoke door codes. |
shortlet_manage_tasks | Manage cleaning tasks and the operations team. |
shortlet_manage_payouts | Generate, approve and pay owner statements. |
shortlet_settings | Change module-wide settings. |
shortlet_view + shortlet_manage_tasks only.
Front-desk staff need shortlet_manage_bookings. Keep shortlet_manage_payouts
restricted to finance — it controls money owed to landlords.
All screens live under Dashboard → Shortlets:
| Screen | Purpose |
|---|---|
| Dashboard | Live occupancy, month KPIs, today's arrivals and departures, channel health. |
| Bookings | Every stay. Take a direct booking, check in and out, record payments. |
| Units | Add apartments and set rate, address, owner, WiFi and lock details. |
| Owners | Landlords, their bank details and commission rates. |
| Calendar | Availability grid across all units and channels. |
| Channel Manager | OTA connections, listing mappings, imported stays, sync log. |
| Guest Inbox | All guest conversations. |
| Dynamic Pricing | Rate calendar and pricing rules. |
| Automations | Message templates, send queue, access codes. |
| Cleaning & Ops | Task board and team. |
| Owner Payouts | Statements and payment status. |
| Reports | ADR, RevPAR, occupancy, margin, channel mix. |
| Settings | Module defaults. |
Go to Shortlets → Units → Add unit.
| Unit code | Short identifier, unique per business. Shown wherever there is no display name. |
| Display name | Friendly name shown throughout the module in place of the unit code. |
| Property type | Free text ("Studio", "2-Bedroom", "Penthouse"). For your own grouping; nothing depends on it. |
| Nightly rate | The base price dynamic pricing scales. Supports per-weekday overrides. |
| Max guests | Occupancy cap shown on the booking form. |
| Min / max nights | Overrides the module default for this unit. Leave blank to inherit. |
| Cleaning fee | Becomes the default cost on auto-generated turnover tasks, and is deducted on the owner statement. |
| Security deposit | Recorded for reference on the unit profile. |
| Commission % | Your management fee for this unit. Overrides the owner's rate and the module default. |
| WiFi name / password | Injected into guest messages via template variables. |
| Smart lock | Manual (keypad) or a connected vendor. Picking a vendor lets you select the specific lock. See section 8.3. |
| Fixed door code | Leave blank to generate a unique code per stay. Fill it in only if the lock has one permanent code. |
| Directions | Free text used by the {{directions}} variable in pre-arrival messages. |
Owners are the landlords whose properties you manage. Add them under Shortlets → Owners. Beyond contact details, record their bank name, account number and account name — these print on the payout statement.
Owners are automatically linked into the central Contacts ledger, so they appear alongside your other customers and suppliers rather than living in a silo.
When a payout is generated, the commission rate is resolved from the most specific setting available:
So a unit with 15% set overrides an owner set to 20%, which in turn overrides the 20% module default. Leave the unit and owner fields blank to simply use the default everywhere.
Bookings live under Shortlets → Bookings. Most stays arrive on their own through the channel manager; this is for the ones you take directly — a phone enquiry, a repeat guest, a walk-in.
| Action | What it does |
|---|---|
| Check in | Marks the guest in house. |
| Check out | Creates the turnover cleaning task, expires the door code and withdraws it from the lock. |
| Take payment | Records it against the booking. The first payment posts the sale into Sales and Reports; later ones update it. |
| Cancel | Stops queued guest messages and revokes the door code. The booking stays on record. |
For maintenance, an owner stay or a deep clean, add a block instead of a dummy booking. Blocks appear on the calendar, feed the availability guard, and go out on your channel feeds so the OTAs stop selling those nights. A block that would overlap a live booking is refused.
Sync uses iCal, the calendar format Airbnb, Booking.com and Vrbo all publish. It needs no API approval and works with a standard host account. Sync runs in both directions:
| Direction | What happens |
|---|---|
| Import (OTA → WaoBiz) | On a schedule, WaoBiz fetches each listing's iCal URL and records every reservation as a calendar hold. Those holds then block the dates everywhere else. Use Sync now for an immediate pull. |
| Export (WaoBiz → OTA) | WaoBiz publishes a feed URL per listing. The OTA polls it on their own schedule and blocks the dates it contains. |
A channel connection alone syncs nothing. You must map each unit to its listing on that channel.
Where to find the import URL on each platform:
| Platform | Location |
|---|---|
| Airbnb | Calendar → Availability → Connect to another website → Export calendar |
| Booking.com | Rates & Availability → Sync calendars → Export |
| Vrbo | Calendar → Import/Export → Export calendar |
Each mapped listing gets a feed URL of the form
https://your-domain/api/shortlets/ical/<token>.
Copy it from the listing card and paste it into the OTA's calendar import setting.
The feed includes:
Every attempt to create a booking — whether from the dashboard or your public booking page — checks three sources before it is allowed:
If any of the three overlaps the requested dates, the booking is rejected with a message naming the blocker.
Use Push rates on a channel to publish your computed nightly rates, with that channel's markup applied.
The Sync log tab records every attempt. Columns read +added / ~updated / −removed.
| Status | Meaning |
|---|---|
| success | All listings on the channel synced. |
| partial | Some listings synced, others failed. The message names them. |
| failed | No listing synced. Usually a bad or expired feed URL. |
A conflict count means an imported reservation overlaps something you already had. The import still records it — the OTA booking exists in the real world whether or not it clashes — but you should resolve the clash immediately.
Shortlets → Calendar shows a 30-day grid: one row per unit, one column per night. Each booked night is colour-coded by its source, so you can see at a glance which platform is filling your calendar.
| Colour | Source |
|---|---|
| Blue | Direct booking taken in WaoBiz |
| Rose | Airbnb |
| Indigo | Booking.com |
| Grey | Manually blocked (maintenance, owner stay) |
Free nights display the current nightly rate in thousands, drawn from the dynamic pricing calendar. If those numbers are missing, run a reprice (section 6.3). Use the arrows to move a month at a time.
| Layer | Behaviour |
|---|---|
| Base rate | The unit's own nightly rate, including any per-weekday overrides set on it. |
| Demand rules | Deterministic and free. They stack multiplicatively, highest priority first. Always run. |
| AI pass | Optional. Reads the computed signals and refines the result against market patterns. Consumes AI credits. |
Every night in the calendar stores its base rate, the rules that fired, and a plain-English reason, so you can always see why a price is what it is.
| Type | Triggers on | Typical use |
|---|---|---|
| Occupancy | Portfolio occupancy % for that date | +25% when above 80% booked |
| Lead time | Days between today and the stay | −12% inside 3 days to fill late gaps |
| Day of week | Selected weekdays | +20% Friday and Saturday |
| Season | A date range | +40% over the December holidays |
| Event | A date range | +60% during a nearby conference |
| Gap night | Orphan nights between two bookings | −20% on a single stranded night |
| Length of stay | Length of the free run available | Discount long empty stretches |
Rules apply to all units by default, or you can scope one to a single unit. Priority controls order — higher runs first.
Two buttons on the Dynamic Pricing screen:
Repricing covers your pricing horizon (90 days by default). Filter to one unit first to reprice just that unit.
Settings define a floor and ceiling as multiples of the base rate (0.6× and 2.5× by default). No computed price can fall outside them — the bounds cap both the rules and the AI. This is your protection against a misconfigured rule discounting a unit to nothing.
A price you set by hand becomes the final rate and always wins over the suggestion. Overridden nights are tagged manual in the calendar. Clear the override to return that night to automatic pricing.
Shortlets → Guest Inbox collects every guest conversation into one list, whatever channel it arrived on. Messages are matched to an existing thread in this order:
This is why a guest who messages you on WhatsApp and later books does not end up with two separate threads. Automated messages are mirrored into the thread too, so you always see the complete history with a guest.
| Thread source | Reply behaviour |
|---|---|
| WhatsApp / SMS / Direct | Sends over WhatsApp, falling back to SMS automatically. |
| Sends by email using your configured mail transport. | |
| Airbnb / Booking.com / Vrbo | Saved to the thread and flagged, because these platforms provide no outbound messaging API. Send the message in their extranet. |
Threads are open, pending or closed. Opening a thread clears its unread badge. Close a thread once the guest's question is resolved; it can always be reopened.
An automation is a message template that fires at an offset from a point in the booking. A negative offset means before, positive means after.
| Trigger | Anchor | Example |
|---|---|---|
| Booking confirmed | The moment the booking is created | Confirmation, sent immediately |
| Before check-in | Arrival date/time | −24h directions, −3h door code |
| Check-in day | Arrival date/time | Arrival-day welcome |
| Mid-stay | Midpoint of the stay | "Everything OK?" check-in |
| Before check-out | Departure date/time | −12h checkout reminder |
| After check-out | Departure date/time | +3h thank-you and review request |
Messages are queued the moment a booking is created and sent as each falls due. Cancelling a booking cancels its pending messages automatically.
Wrap variables in double braces. The editor has a clickable list to insert them.
| Variable | Resolves to |
|---|---|
{{guest_name}} | The guest's name, or "there" if unknown |
{{unit_name}} | The unit's display name |
{{address}} | The unit's street address |
{{directions}} | The unit's directions text |
{{house_rules}} | The unit's house rules |
{{checkin_notes}} | The unit's check-in notes |
{{access_code}} | The door code — see 8.3 |
{{wifi_name}} / {{wifi_password}} | WiFi credentials |
{{check_in_date}} / {{check_out_date}} | Formatted stay dates |
{{checkin_time}} / {{checkout_time}} | Property check-in/out times from HMS settings |
{{nights}} | Number of nights booked |
{{brand_name}} | Your shortlet brand name |
Turn on Include the door code for any template that needs to hand over access. Codes are issued per stay and expire at checkout, so a past guest cannot re-enter.
{{access_code}}
renders as a placeholder instead of the real code — so a confirmation message written weeks ahead
cannot leak the door code weeks ahead.
Go to Settings → Smart locks and connect an account. Five platforms are supported:
| Provider | Notes |
|---|---|
| TTLock | Needs a Client ID and secret from the TTLock Open Platform, plus the account's own username and password. |
| Nuki | A single Web API token, generated under Nuki Web → Account → API with keypad permissions. |
| igloohome | Client ID and secret from the igloodeveloper portal. |
| Seam | One API key. Seam brokers Yale, Schlage, August, SmartThings and many others — use it if your brand is not listed separately. |
| Tuya / Smart Life | Access ID, secret and the data centre your Tuya project was created in. Covers a long tail of locks sold under other brand names. |
Once an account is connected, open a unit and pick its lock from the dropdown. Each unit points at one specific lock.
The On device column on the Access codes tab tells you where each code stands:
| Status | Meaning |
|---|---|
| on lock | The vendor accepted the code. Nothing to do. |
| manual | No integration for this unit — set the code on the keypad yourself. Not an error. |
| not sent | The vendor rejected it or was unreachable. Retried automatically up to five times; set it by hand if it keeps failing. |
The Message queue tab shows every scheduled send and its outcome.
| Status | Meaning |
|---|---|
| pending | Queued, not yet due. |
| sent | Delivered successfully. |
| failed | Failed three times. Usually a missing or invalid guest phone number. |
| skipped | Not sent because automated messaging is off in Settings. |
| cancelled | The booking was cancelled or the template deleted. |
Send due now dispatches everything currently due without waiting for the scheduled job — useful when testing a new template.
When a guest checks out, a turnover cleaning task is created automatically, with a seven-point checklist covering linen, bathroom, kitchen, floors, restocking, damage check and lock-up.
The due time is set from your turnover window (4 hours after checkout by default), with one exception:
Four columns track work: Unassigned, Assigned, In progress, Completed.
Besides cleaning, you can raise maintenance, inspection, restock and other tasks manually at any time.
Add cleaners and maintenance staff on the Team tab. New turnover tasks are assigned to whichever active cleaner has the fewest open jobs, spreading work evenly without manual dispatch.
If no cleaner is configured, tasks are still created but left unassigned. Removing a team member returns their open tasks to the unassigned pool rather than deleting them.
| Metric | Formula | What it tells you |
|---|---|---|
| ADR Average Daily Rate | Room revenue ÷ nights sold | What you earn per night actually booked. Measures pricing. |
| RevPAR Revenue Per Available Night | Room revenue ÷ nights available | Earnings across your whole portfolio, occupied or not. Measures overall performance. |
| Occupancy | Nights sold ÷ nights available | How full you are. |
| Net margin | Gross revenue − operating costs | What remains after cleaning and maintenance. |
Revenue is attributed to the nights actually stayed, not to the date the booking was made. A stay from 28 June to 3 July contributes its June nights to June and its July nights to July.
This is what keeps ADR, RevPAR and occupancy comparable month to month. Attributing the whole booking to one month would inflate that month and leave a hole in the next.
The Channel mix tab breaks revenue down by source, showing gross revenue, the platform's commission and your net. Bookings traced to an OTA show that platform; everything else counts as Direct.
The By unit tab ranks every apartment by revenue with its own ADR, RevPAR, occupancy and margin, and exports to CSV. The 6-month trend tab charts revenue, margin and occupancy over time.
The calculation is:
Gross booking revenue (pro-rated to nights within the period) − Management commission (unit rate → owner rate → default) − Cleaning costs (completed tasks in the period) − Maintenance costs − Other costs ± Adjustments ───────────────────────── = Net payable to owner
| Status | Meaning | Can it change? |
|---|---|---|
| draft | Calculated but not agreed. Regenerating replaces its lines. | Yes, freely |
| approved | Agreed. Its task costs are locked as billed. | Locked |
| paid | Money sent. Cannot be deleted, only cancelled. | Locked |
| cancelled | Voided. Its task costs are released back to unbilled. | — |
View statement opens the full document: header, the owner's bank details, and every backing line — each booking with its nights and pro-rated revenue, each commission charge, each cleaning and maintenance cost.
It shows nights sold, booking count and the period ADR, and prints cleanly for sending to the landlord. Because every figure traces to a specific booking or task, an owner query can always be answered precisely.
| Setting | Effect |
|---|---|
| Brand name | Title shown across shortlet screens and in guest messages via {{brand_name}}. |
| Unit label | Replaces the word "Room" with your term, e.g. "Apartment". |
| Check-in / check-out time | Your property-wide clock, used by the {{checkin_time}} and {{checkout_time}} template variables. |
| Currency symbol | Symbol used in rates, reports and statements. |
| Default min / max nights | Stay limits when a unit does not set its own. |
| Auto-create cleaning | Master switch for automatic turnover tasks at checkout. |
| Turnover due within | Minutes after checkout that a turnover clean is due. Overridden by a same-day arrival. |
| Send automated messages | Master switch for the guest journey. Off leaves messages queued but undelivered. |
| Pre-arrival lead | Default hours before arrival for pre-arrival messaging. |
| Release door code | Hours before arrival that {{access_code}} resolves to a real code. |
| Smart locks | Connect a lock vendor account so codes reach the keypad automatically. See section 8.3. |
| Enable AI pricing | Turns on the AI refinement pass. Rules run regardless. |
| Apply rates automatically | When on, suggested rates become live without manual confirmation. |
| Price floor / ceiling | Multiples of the base rate that bound every computed price. |
| Pricing horizon | How many days ahead repricing covers. |
| Default commission % | Fallback management fee when neither unit nor owner sets one. |
| Payout cadence | Your statement rhythm: weekly, fortnightly, monthly or quarterly. |
Three background jobs keep the module current. They run automatically on the hosted platform.
| Job | Schedule | What it does |
|---|---|---|
| Channel sync | Daily, 02:00 | Imports every active channel calendar, respecting each channel's own sync interval. |
| Guest messages | Daily, 05:00 | Delivers automated messages that have come due, and retries any door code that failed to reach its lock. |
| Turnover sweeper | Daily, 04:30 | Creates turnover tasks for recent checkouts that do not have one — a safety net for bookings closed outside the app. |
vercel.json), or press
Sync now on the Channel Manager before confirming a direct booking.
Each has a manual equivalent in the interface — Sync now, Send due now, and creating a turnover from a booking — so you never have to wait for the schedule when testing.
Its nightly rate is zero. Dynamic pricing scales that rate, so with nothing to scale the unit is skipped. Set a rate on the unit and reprice. The units list flags any unit in this state.
Check the On device column on Automations → Access codes:
Either way the guest still received a code — only the lock is out of step, so setting it by hand resolves it.
Check in order:
Expected behaviour outside the release window. The code resolves only within access code lead time of arrival. Raise that value in Settings if you want codes sent earlier.
The double-booking guard is doing its job — an OTA already holds those dates. Check the Imported stays tab. If the OTA booking was cancelled, run Import now to clear the stale hold.
Revenue is pro-rated to nights within the period. A stay spanning the period boundary contributes only its in-period nights — the remainder appears on the adjacent statement. Also confirm every relevant unit is assigned to that owner.
If any is missing, the module falls back to rules-only output and reports this in the result message.
Stated here rather than left to be discovered.
Five platforms are supported: TTLock, Nuki, igloohome, Seam and Tuya. Between them they cover most locks on the market — Seam alone brokers Yale, Schlage, August and others, and Tuya is the white-label behind many unbranded locks. A lock outside all five still works, you just set the code on the keypad yourself.
Two behaviours are worth knowing. igloohome locks are offline by design: they derive their PIN from an algorithm built into the lock, so igloohome's code is used rather than the one WaoBiz generated, and there is nothing to revoke — the PIN simply stops working at the end of its window. Nuki requires six digits not beginning with 1 or 2, so a non-compliant code is adjusted. In both cases the guest receives the code that actually opens the door.
The background jobs run once daily, because the hosting plan permits daily schedules only. That is fine for turnover tasks and post-stay messages, but it means an OTA booking may go unimported for up to 24 hours, and a door code scheduled for three hours before arrival may be dispatched earlier in the day than intended.
If you sell the same units across several platforms, either raise the schedules on a paid hosting plan, or press Sync now on the Channel Manager before confirming a direct booking.
The availability check reads current bookings and then writes the new one. Two people booking the same unit for the same dates in the same instant could in principle both succeed.
Practical effect: very unlikely in normal operation, and the window is narrow. Cross-channel protection against OTA bookings is unaffected — that is the far more common risk and it is fully covered. A database-level constraint is the planned fix.
Airbnb, Booking.com and Vrbo do not expose outbound messaging APIs to third-party tools. Replies to those threads are recorded in WaoBiz but must be sent from the platform's own extranet. This is a platform restriction, not a WaoBiz gap.
WaoBiz POS — Shortlets Module User Guide · Version 2.0 · August 2026