Reports
Choose server-calculated financial and operational report views
Last Updated: 2026-10-03
Version: 1.4
Reports are server-calculated views over journals and business resources. Use returned rows, totals, currency, dates, and filters rather than recomputing financial statements in a client.
Choose A Report
| Question | Report |
|---|---|
| What revenue and expense activity occurred in a period? | Profit and loss |
| What is the financial position at a date? | Balance sheet |
| Do account debits and credits agree? | Trial balance |
| What guest or channel receivables remain? | Guest balances |
| How do trust liabilities compare with trust assets? | Trust reconciliation |
| What sales-tax liability is recorded? | Sales-tax liability |
| What manager-side activity belongs to each month? | Manager statements |
| What did each owner earn and receive over a date range? | Owner summaries |
| How much does each ownership owe its owners on a date? | Owner balances |
| Which postings make up a reported balance? | Journal entries |
The generated operation defines exact date, listing, ownership, account,
currency, view, and export parameters. JSON, CSV, and PDF endpoints can have
different response contracts; do not assume a format query exists unless the
operation declares it.
Calculation Rules
Manager Statement Totals
Manager statements report active trust-ledger postings of the manager party
in the team's default currency. Postings whose unique reference ends in -a/p
are excluded.
- The year list returns the 12 months of
year. Months before the team'sstatementStartAtare omitted, but their activity still reaches later balances. balanceStartincludes all earlier revenue, expense, adjustment, and transfer activity. Assets and liabilities and the Other section never enter it.netIncome(shown as Net earnings) isnetRevenue + expenses.balanceEndisbalanceStart + netIncome + adjustments + transfers.assetsAndLiabilitiesis cumulative through the statement end.availableBalanceisbalanceEnd + assetsAndLiabilities.totalisnetIncome + adjustments.- The detail
endAtparameter and every returnedendAtare exclusive.dateRangefollowsisDateRangeEndInclusive.
Owner Statement Summary Totals
Owner statement summaries return one row per owner contact and currency, sorted by contact name.
- The range end is exclusive only when
startAtandendAtare both the first of a month. Otherwise the end day is included. An end before the start returns400 BAD_REQUEST. - When the team has a
statementStartAt, the range starts no earlier than the earlier ofstatementStartAtand the first Published statement. A range ending on or before that date returns no rows. - The manager view sums all owner-party postings on accounts mapped in the listing's layout, attached or not and whatever the statement status.
- The owner view counts postings attached to Published statements. When
ownerPortalShowDraftStatementsis true, it also counts postings not yet attached to a statement. Postings attached to In Review statements never count. - Amounts are split across the ownership period's owners by ownership percentage. Payouts follow the attribution rule in Statements.
- When an ownership period has an In Review or Published statement before the range, that statement's ending balance replaces earlier activity as the starting balance.
Owner Balance Rows
GET /reports/owner-balances returns one row
per ownership and currency. It needs statements:read and is not available to owner
sessions. date is required and inclusive. listingIds and ownerIds are optional
comma-separated UUID lists.
balanceis the owner balance at the end ofdate. Positive means the owner is owed money. It sums the owner revenue, expense, and payout postings that statements count, from the later of the ownership start and the team'sstatementStartAt, whatever their statement status. Draft activity, activity attached to Published statements, and payouts all count.- A first ownership that covers
statementStartAtadds the listing's opening balance oncedatereachesstatementStartAt. Amanagedownership that starts where aco_hostownership ended takes over that ownership's last saved ending balance, and theco_hostrow no longer shows it. Any other ownership starts at zero. reserveis the ownership's reserve.availableBalanceisbalance - reserve.- Every ownership active on
dateis listed, with a zero balance when it has no activity. An ownership that ended beforedateis listed only while its balance is not zero. - A listing group reports on the parent listing's ownership. Child listing activity rolls up to it.
- The balance is read from journals, not from saved statements. It equals a statement's
balanceEndon the statement's last day when that statement's saved totals match the journals. The endpoint changes no payout, statement, or paid status.
Profit and Loss Views
viewisledger,party(default),listing,month,quarter, oryear.- Without
party, the report includes owner and manager activity. - Without
endDate, the end is today. WithoutstartDate, the start is the first of the end month forparty,listing, andledger, and January 1 of the end year for time views. - Reversed dates are swapped.
startDateandendDateare both inclusive;dateRangefollowsisDateRangeEndInclusive. - Amounts are negated journal totals of active postings in the team's default currency, so revenue is positive and expenses are negative.
Guest Balance Rows
Only reservations and transactions with a non-zero receivable balance appear.
occupancyStatusselectsdeparted(booked, check-out on or before the as-of date),inHouse(booked, checked in on or before the date and checking out after it),upcoming(booked, check-in after the date),cancelled,unassigned(receivable postings without a reservation), orall.channelsfilters reservations by comma-separated booking channels.chargessums reservation charge postings.paymentssums deposit postings with the sign flipped.- Rows group by booking status (
booked,cancelled,unassigned), then by listing. - Unassigned rows identify their transaction through
transactionReferenceId,transactionDate, andtransactionDescription.
Trust Reconciliation Sections
Trust Reconciliation uses active trust-ledger postings through the as-of date. Its asset sections are Bank Accounts and Other Assets. Its liability sections are Taxes Payable, Other Liabilities, Guest Receivables & Deposits (by occupancy status), Owner Payables (by listing), and Manager Payable.
Owner Dashboard Metrics
Two monthly metrics feed an owner dashboard for one owner contact. Both take
ownerId, an optional comma-separated listingIds (default: every listing of
the owner), an optional currency (default: the team currency), and a
dateRange with an exclusive end by default. Each month is returned once, dated on its first day.
GET /metrics/owner-performance
returns booking activity:
- Each booked stay is split per night. Only nights inside the owner's ownership periods count, and each night carries an equal share of the stay's rent and owner revenue.
- Rent is the sum of reservation lines whose account is in the Rents revenue category. A line uses its own account, else the booking-channel mapping of its line type, else the base mapping.
- Owner revenue comes from the reservation's journal. A stay without a journal,
such as one before the books start, is estimated as its rent × the listing's
owner share of rent over its journaled stays in the requested range. Such a
month has
estimated: true. A stay excluded from accounting counts as booked nights and rent but adds no owner revenue. availableNightssums the owned days of each selected physical listing in the month. A purchase includes its start day; a sale excludes its end day. Overlapping periods count each listing-day once. ADR is rent per booked night, occupancy is booked ÷ available nights, and RevPAR is rent per available night.- Before the first booked night in the range,
hasBookingHistoryisfalseand ADR, occupancy, and RevPAR arenull. - Stays in another currency are left out. A stay without a currency counts in the team currency.
- In a listing group, children's stays count under the parent's ownership periods. Selecting the parent includes its children; selecting a child returns only that child's stays. Each included physical listing contributes capacity, even without bookings, and estimates use only its own journaled stays. Selecting siblings does not pool their owner shares. Statements of a selected child are the parent's statements.
- With
asOf, only stays booked by the end of that day (UTC) and not cancelled by then count, including stays cancelled later. A cancelled stay without a cancellation date does not count. Amounts use each stay's current lines, as inGET /metrics/booked-revenue. Cancellation deactivates a stay's journal, so a stay cancelled later gets an estimated owner revenue from its current rent lines and is flaggedestimated. The owner dashboard sends last year's date to compare booking pace.
GET /metrics/owner-financials
returns the owner's statements summed per month in the selected currency, plus
currencies for a currency switch:
- A month with statements has
source: statementand a paymentstatus. With several statements it ispaidwhen all are paid or overpaid,partiallyPaidwhen some are, and otherwise the least advanced status. - A month without a statement has
source: estimateand the booked owner revenue from the performance metric asnetRevenue, orsource: nonebefore the first booked night. ownershipSplitis the owner's percentage when exactly one listing is requested and every statement of the month has the same split.
An owner session can only request its own contact and listings; other values
return 404. It sees draft and In Review months only when the team shows draft
statements to owners. Hidden statements do not contribute totals, counts, payment status,
payout dates, ownership splits, or the currency list. A month containing only hidden statements
uses the same estimate or none result as a month without a statement.
status=published selects published statements; status=all includes drafts only when
permitted. Manager previews may use either value. Owner sessions can read
ownerPortalShowDraftStatements from GET /team.
For the month's reservation and expense cards, use the batched owner detail read.
settings.showOwnerDashboard on GET /team and PUT /team decides whether the owner
portal opens on the dashboard. It defaults to false; owners then land on their statements.
The setting changes only the owner portal home page. Both metrics return the same data either
way.
Manager Dashboard Metrics
Two metrics compare revenue excluding taxes by check-in month. Amounts are in cents. Revenue excluding taxes is the sum of a reservation's lines, except lines without an account and lines whose account is a lodging or occupancy taxes-payable account or the sales-tax account. A line uses its own account, else the booking-channel mapping of its line type, else the base mapping. Taxes mapped to a revenue account count as revenue.
GET /metrics/take-rate-trend
returns the requested month and the 11 months before it:
takeRateispmRevenue÷revenueExcludingTaxesas a percentage. Both count only booked stays with a PM/owner split, meaning active reservation journal entries and not excluded from accounting. Deposit, payout and other transaction entries on a stay do not count.coverageis the share oftotalRevenueExcludingTaxes, which counts every booked stay, that has a split.statusisavailablewhen coverage is at least 90%,insufficientCoveragebelow that, andnoDatawithout revenue.takeRateisnullunless the month isavailable. A zero take rate is a real zero.
GET /metrics/booked-revenue
returns the month of the reference date and the next three, each with the
same month last year:
revenueandlastYearFinalRevenuecount booked stays.lastYearAtDateRevenuecounts last year's stays booked by the end of the same day last year (UTC; Feb 29 uses Feb 28) and not cancelled by then, including stays cancelled later. A cancelled stay without a cancellation date does not count.- All amounts use each stay's current lines. Changes made to a stay after last year's date are not reversed.
GET /metrics/average-daily-rate-over-time
returns the average daily rate per check-in bucket, the same way
GET /metrics/average-daily-rate
computes it for one window:
revenueis the reservation total of booked stays, in cents.nightsis their booked nights. A stay counts in the bucket of its check-in.averageDailyRateisrevenue÷nights, rounded to cents, andnullwithout booked nights.- To compare with last year, request a range that starts one year earlier and match each bucket with the same bucket a year before.
GET /metrics/occupancy-rate-over-time
returns occupancy per check-in bucket:
occupiedNightsis the booked nights of stays that check in during the bucket.availableNightscounts each listing-day covered by an active ownership period. A group child uses its parent's periods and drops out on the days of its own deactivation period. A purchase includes its start day; a sale excludes its end day. A listing without ownership periods adds no available nights.occupancyRateisoccupiedNights÷availableNightsas a percentage, and0without available nights.
Generated Artifact Scope
Every generated report artifact supports awaited GET and durable POST. Follow the generated export contract for request shapes, fallback handling, operation polling, and result links. The limits below determine whether GET can await a selection. They do not change the POST contract.
A GET for a one-month manager-statement PDF or a one contact-month owner-summary PDF or ZIP renders in the API request and returns the same file and download link. Every other report artifact renders in Trigger, and the API receives only artifact metadata. Limits measure the deduplicated data query, not how many files the selected data produces. Every PDF date range spans at most 60 calendar months, and each selector accepts at most 100 unique values.
Manager Statements
Manager-statement JSON routes require pm-statements:read. CSV and PDF routes
also require pm-statements:export. General report permissions do not grant
manager-statement access, and neither do the owner-statement permissions.
Manager-statement PDF scope is the complete contiguous month span from the earliest through the latest selected month. Sparse selections still load the months between those boundaries.
- A span through 60 queried months is supported.
- GET awaits spans through 12 queried months; larger supported spans require POST.
- A span above 60 months fails the export operation.
- Duplicate
startAtsare removed before counting, and no more than 100 uniquestartAtsmay be supplied.
Selecting January and December has a 12-month query scope even when the archive contains only those two selected statement PDFs.
Owner Statement Summaries
An explicit owner-summary batch uses contact-month scope:
unique contactIds × queried calendar months- POST supports a scope through 1,200 contact-months.
- GET awaits a scope through 100 contact-months; larger supported scopes require POST.
- A scope above 1,200 contact-months fails the export operation.
contactIdsandlistingIdseach accept at most 100 unique supplied values.
Omitting contactIds means all matching contacts. The export task resolves and
deduplicates the contacts and validates the final scope before loading
per-contact detail.
A one-contact owner-summary detail PDF uses the same operation flow and remains subject to the 60-month range and 100-listing selector limits.
The export task publishes a file only after rendering and upload succeed. A failure marks the operation as failed without publishing a partial result.
Trust Reconciliation by Listing JSON requests accept source, nestedParent,
and parentRollup display modes. The CSV and PDF exports support parent and
group totals only: omit listingDisplay or set it to parentRollup.
The main Trust Reconciliation JSON, CSV, and PDF endpoints accept listingId
as a comma-separated list of listing UUIDs and reject malformed IDs before
report work starts.
Trust Reconciliation also exports as a PDF for readers outside the product, such as a qualifying broker. The PDF is rendered as of the same date the JSON and CSV exports use, restates the on-screen section totals, and expands each section into its rows. The main report groups its sections under Assets and Liabilities; the by-listing report keeps its own group order. Both PDF routes support GET for awaited temporary download metadata and POST for a durable export operation. Rendering runs outside the API Worker for both methods. Trust artifact GETs admit at most 100 selected or tenant listings; use POST for larger supported portfolios.
Journal-entry CSV GETs use the filtered total before rendering and admit at most 5,000 rows. Resource CSVs have the same 5,000-row result cap. Use POST when the filtered journal export is larger or durable status is required.
Guest Balances is an as-of accounts-receivable report. Guest payments are
gross amounts applied to accounts receivable; payment-processing fees are
separate expenses and do not reduce payment received. Reservation-scoped
deposit rebalances whose deposit postings net to zero are internal accounting
reclassifications, so they do not appear as guest payments or change Guest
Balances. A deposit that nets to zero only because a payment-direction
accounts-receivable leg is offset by a merchant-fee leg (a payment grossed up
for credit card fees) is a real guest payment and is counted. A Co-Host Payouts offset contributes to net-zero detection for a
payment-direction accounts-receivable leg when the reservation has no active
charge on an accounts-receivable account. A positive accounts-receivable
reversal remains in the report so it can clear an earlier payment. When the
charge is on accounts receivable, the matching negative deposit leg remains
payment relief so the paid charge and payment net to zero. An aggregate payout
can still contain valid activity for other reservations. The date filter
accepts a single date or a date range; a range uses its inclusive end as the
report's as-of date. Malformed ranges are rejected before report queries run.
Manager-statement section filters apply consistently to journal-entry JSON and
CSV exports. Preserve the section ID when moving from statement detail to an
export. Omit an unselected comma-separated journal filter. For compatibility,
the journal endpoints treat -, inclusive all, and exclusion none UI
sentinels as no selection. Relationship ID filters accept unmapped to select
journal entries whose corresponding relationship is null, including
transaction and attached owner-statement filters. The trial-balance
accountIds filter accepts comma-separated account UUIDs or unmapped and
rejects malformed IDs. On its own, unmapped returns no named account rows;
the Unassigned figures are always included. The sentinel is ignored when real
account UUIDs are also selected, because the Unassigned figures are included
either way. An entity selection that does not
map to a supported journal relation returns an empty report instead of a
database error.
The Sales-tax liability report derives taxable income from the selected
reservation-line mappings. Its taxableLineIds filter accepts a
comma-separated list of reservation line-mapping UUIDs and rejects malformed
IDs. Synthetic A/R adjustment mirrors do not contribute to taxable income,
including when a selected excluded line type has no mapped account. Taxable
Income drilldowns contain the exact journal entries used by the report.
Collectable Taxes includes active Trust postings to the lodging-and-occupancy
tax liability category when they are either direct reservation postings or
reservation-attributed transaction postings backed by a revenue posting in the
same transaction. Tax-authority remittances and other cash- or payable-backed
transaction activity are excluded. An exact transaction duplicate of a direct
reservation tax posting is counted once, and Collectable Taxes drilldowns
contain the exact journal entries used by the report.
For historical reporting, distinguish live and historical ledgers. Historical imports preserve pre-go-live detail without changing live post-go-live balances.
Owner statement summaries include imported historical statements. Their
payouts count like the statement's own payouts, and a historical payout
without a contact is split by ownership share. Pre-go-live postings that an
imported statement's balance already carries are not counted again. Summary
drilldowns set includeHistoricalLedger, so journal-entry detail shows the
imported entries next to live trust activity.
Common Workflows
For month-end review, use the trial balance to check account balance, trust reconciliation to inspect trust position, profit and loss for period activity, and owner or manager statements for their respective audiences. These reports answer different questions and should not be reconciled by comparing unrelated totals.
For a discrepancy, preserve the selected date, view, currency, listing, ownership, and account filters when opening journal-entry detail. Rebuilding a report with different filters can create a false mismatch.
See Statements, Accounting model, and Locking.
