---
title: "Bookings, metrics, cleaning, reviews and pricing for a date range"
method: GET
path: "/api/v1/short-stay"
tags: ["Short stay"]
---

# Bookings, metrics, cleaning, reviews and pricing for a date range

`GET /api/v1/short-stay`

## Request

- Base URL: `http://localhost:5180`
- URL: `http://localhost:5180/api/v1/short-stay`
- Auth: API key in cookie `better-auth.session_token`

The window defaults to the trailing 12 months, matching the cashflow chart. `bookings`, `cleaning`, `reviews`, `pricingRules` and `connections` are the whole operation rather than the window: only `metrics` and `channels` are computed against `range`.

## Query parameters

- `from` string
- `to` string

## Response `200`

Bookings, metrics and the operation around them.

- object
  - `ok` unknown, required
  - `data` object, required
    - `range` object, required
      - `from` string, required: A calendar date, `YYYY-MM-DD`.
      - `to` string, required: A calendar date, `YYYY-MM-DD`.
    - `bookings` object[], required
      - `id` string, required: Stable record id, e.g. `lse_012`.
      - `reference` string, required
      - `unitId` string, required: Stable record id, e.g. `lse_012`.
      - `channel` string, required
      - `guestContactId` string, required: Stable record id, e.g. `lse_012`.
      - `status` string, required
      - `checkIn` string, required: A calendar date, `YYYY-MM-DD`.
      - `checkOut` string, required: Exclusive. A checkout and a check-in on the same date is a turnover, not a clash.
      - `nights` number, required
      - `nightlyRate` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `accommodationTotal` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `cleaningFee` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `touristTax` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `channelCommission` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `netPayout` integer, required: What actually lands in the bank.
      - `currency` string, required
    - `metrics` object, required: ADR, RevPAR and occupancy across the range.
      - `stays` number, required: Bookings that earned, counted once each however many nights they ran.
      - `nights` number, required: Nights actually sold inside the window.
      - `availableNights` number, required: Nights the units could have sold, which is what occupancy is measured against.
      - `occupancy` number, required: nights ÷ availableNights, 0–1.
      - `adr` integer, required: Average daily rate: gross accommodation revenue ÷ nights sold.
      - `revpar` integer, required: Revenue per available night, which is occupancy and rate in one figure.
      - `revpan` integer, required: Revenue per available night after commission and cleaning, so it is what the owner keeps.
      - `alos` number, required: Average length of stay, in nights.
      - `leadTimeDays` number, required: Average days between a booking being taken and the guest arriving.
      - `cancellationRate` number, required: 0–1, against everything that was due to arrive in the window.
      - `commissionDrag` number, required: commission ÷ gross, 0–1. What the channels take before anything else.
      - `cleaningCostPerStay` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `costPerBookedNight` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `gross` integer, required: Everything charged to guests before any deduction.
      - `commission` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `cleaningCost` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `touristTax` integer, required: Collected on behalf of the city, so it was never income.
      - `net` integer, required: What actually lands in the bank.
    - `channels` object[], required: Booking mix by channel. The connected accounts are `connections`, and the two are never the same thing.
      - `channel` string, required: `airbnb`, `booking_com`, `vrbo`, `direct`, `expedia` or `other`.
      - `bookings` number, required
      - `nights` number, required
      - `revenue` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `commission` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `net` integer, required: Money, always in integer cents. €1,250.00 is 125000.
      - `nightsShare` number, required: Share of booked nights won by this channel, 0–1.
      - `revenueShare` number, required: Share of gross revenue. It diverges from `nightsShare` when a channel sells cheap nights.
      - `effectiveCommissionRate` number, required: commission ÷ revenue for this channel alone, which is the real blended take rate.
    - `cleaning` object[], required: The turnovers. `isSameDayTurnover` marks the tightest window in the operation, one guest out and the next in on the same date.
      - `id` string, required: Stable record id, e.g. `lse_012`.
      - `unitId` string, required: Stable record id, e.g. `lse_012`.
      - `bookingOutId` string: The booking checking out, if there is one.
      - `bookingInId` string: The booking checking in, if there is one.
      - `date` string, required: A calendar date, `YYYY-MM-DD`.
      - `windowStart` string
      - `windowEnd` string
      - `isSameDayTurnover` boolean, required: True when one guest checks out and the next checks in on this same date. Booking ranges are half-open, so a checkout date is not an occupied night and the same date can legitimately carry both. That is the tightest window in the operation and the one worth watching.
      - `cleanerContactId` string: Stable record id, e.g. `lse_012`.
      - `status` 'unassigned' | 'assigned' | 'confirmed' | 'in_progress' | 'done' | 'issue_reported' | 'missed' | 'cancelled', required
      - `cost` integer: Money, always in integer cents. €1,250.00 is 125000.
      - `checklistCompleted` number
      - `checklistTotal` number
      - `issuesReported` string[]
      - `linenChange` boolean, required
      - `consumablesRestock` boolean, required
      - `photoRefs` string[], required
    - `reviews` object[], required: What guests said, with any reply. A reply is usually drafted by the AI and approved before it goes out.
      - `id` string, required: Stable record id, e.g. `lse_012`.
      - `bookingId` string, required: Stable record id, e.g. `lse_012`.
      - `unitId` string, required: Stable record id, e.g. `lse_012`.
      - `channel` 'airbnb' | 'booking_com' | 'vrbo' | 'direct' | 'expedia' | 'other', required
      - `guestContactId` string, required: Stable record id, e.g. `lse_012`.
      - `receivedAt` string, required: ISO 8601 timestamp.
      - `overall` number, required: The headline score the channel published, on that channel’s own scale.
      - `categories` object, required: Sub-scores such as cleanliness, accuracy, check-in, communication, location and value.
      - `publicComment` string
      - `privateComment` string: Feedback the guest sent only to the host.
      - `response` object: The owner’s reply, usually drafted by the AI and approved before it goes out.
        - `body` string, required
        - `postedAt` string: ISO 8601 timestamp.
        - `status` 'draft' | 'pending_approval' | 'posted', required
      - `extractedIssues` string[]: Problems the AI pulled out of the text, so a recurring complaint becomes a maintenance job.
    - `pricingRules` object[], required: Applied in `priority` order, so a later rule can override an earlier one. A rate is never taken below `floorPrice`.
      - `id` string, required: Stable record id, e.g. `lse_012`.
      - `unitId` string: Absent when the rule applies to every short-stay unit.
      - `name` string, required
      - `kind` 'base' | 'seasonal' | 'day_of_week' | 'lead_time' | 'length_of_stay' | 'orphan_gap' | 'event' | 'occupancy_pace' | 'min_stay', required
      - `active` boolean, required
      - `priority` number, required: Rules are applied in this order, so a later one can override an earlier one.
      - `multiplier` number: An adjustment as a factor, 1.15 being plus 15%. A rule uses this or absoluteAmount, not both.
      - `absoluteAmount` integer: Money, always in integer cents. €1,250.00 is 125000.
      - `minStayNights` number
      - `conditions` object, required
        - `dateFrom` string: A calendar date, `YYYY-MM-DD`.
        - `dateTo` string: A calendar date, `YYYY-MM-DD`.
        - `daysOfWeek` number[]: 0 is Sunday.
        - `leadTimeMaxDays` number
        - `leadTimeMinDays` number
        - `gapNights` number: The size of the orphan gap this rule is meant to fill.
        - `occupancyBelow` number: A decimal ratio. 0.21 is 21%.
      - `floorPrice` integer: The rate is never taken below this, whatever the rules compute.
      - `ceilingPrice` integer: Money, always in integer cents. €1,250.00 is 125000.
      - `description` string, required
    - `connections` object[], required: The channel accounts and what each can actually do. An iCal-only channel cannot be pushed prices or availability.
      - `id` string, required: Stable record id, e.g. `lse_012`.
      - `channel` 'airbnb' | 'booking_com' | 'vrbo' | 'direct' | 'expedia' | 'other', required
      - `unitIds` string[], required
      - `status` 'connected' | 'syncing' | 'error' | 'disconnected', required
      - `lastSyncAt` string: ISO 8601 timestamp.
      - `commissionRate` number, required: A decimal ratio. 0.21 is 21%.
      - `capabilities` string[], required: What this connection can actually do. An iCal-only channel cannot be pushed prices or availability.
      - `calendarUrl` string, uri: The channel’s iCalendar export, which a sync fetches when no feed is sent with it. Absent until the owner adds it.
      - `errorMessage` string
      - `payoutReader` object: How each stay’s payout is read off its own calendar description, learned once per template and checked against every description before a figure is taken.
        - `shape` string, required: The outlines of the descriptions a model was asked about, one paragraph each. Any other outline is asked about again.
        - `label` string: The words the payout follows on its line. Absent when the descriptions were read and state no payout.
        - `line` string: That line with its figures written `#`. A description whose line reads otherwise is not priced.
        - `decimal` '.' | ','
        - `currency` string: The currency the line names. A figure in another currency than the stay is never taken.
        - `checkedAt` string, required: ISO 8601 timestamp.
  - `meta` object, required
    - `requestId` string, required: Echoed in the x-request-id header. Quote it in a bug report.

## Other responses

- `400`: `to` is before `from`, a date is not `YYYY-MM-DD`, or it names a day that is not on the calendar.

---

[API](https://skmtc.dev/dardaris/apis/dardaris-api.md) · [All operations](https://skmtc.dev/dardaris/apis/dardaris-api/llms.txt) · [OpenAPI document](https://skmtc.dev/dardaris/apis/dardaris-api/revisions/4aff33835c73?raw)
