Skip to content

Read the platform's whole month on its own Stripe balance

GET
/v1/platform-earnings
curl --request GET \
--url 'https://api.aerandil.com/v1/platform-earnings?month=example' \
--header 'Authorization: Bearer <token>'

A fold over every line the platform-ledger worker read off the platform’s own Stripe balance in a UTC calendar month, across every tenant: hotels — every merchant account’s lines, the per-account month (/v1/merchant-accounts/{id}/platform-earnings) summed; platform — the lines no hotel owns, recorded at the operator’s own tenant (AERANDIL_PLATFORM_TENANT_ID): its payouts, Stripe’s fees on the platform and the tax on them, reserves, and what no merchant account holds (unattributed); net — every line, the balance’s change. ties_to_stripe is the arithmetic of Stripe’s Balance summary report run in UTC — Activity (every category bar the payouts: count, gross, fee, net), Total payouts, and their sum — and by_category its balance-change-from-activity summary, so the operator ties the month to Stripe to the penny. unplaced_count is what was read while no operator tenant was configured: counted, never recorded, so a month carrying any will not tie. The platform operator’s read (tenant_admin:write).

month
required
string
/^[0-9]{4}-[0-9]{2}$/

The UTC calendar month, YYYY-MM.

The platform’s month.

Media typeapplication/json
object
account_count
required
integer
from
required
string format: date
line_count
required
integer
month
required
string
platform_tenant_id
string | null format: uuid
timezone
required
string
to
required
string format: date
totals
required
Array<object>
object
by_category
Array<object>
object
count
integer
fee
string format: decimal
gross
string format: decimal
net
string format: decimal
reporting_category
string
currency
string
hotels

Every hotel’s lines: the per-account month summed.

object
account_count
integer
dispute_costs
object
amounts_recovered
string format: decimal
amounts_withdrawn
string format: decimal
carried
string format: decimal
fees_charged
string format: decimal
fees_recovered
string format: decimal
gross_captured
string format: decimal
net
string format: decimal
platform_fees_earned
string format: decimal
processor_fees_paid
string format: decimal
refunded
string format: decimal
unexplained
string format: decimal
net
string format: decimal
platform

The platform’s own lines, each bucket the net of its lines.

object
line_count
integer
net
string format: decimal
other
string format: decimal
payouts
string format: decimal
reserves
string format: decimal
stripe_fees
string format: decimal
tax_on_fees
string format: decimal
unattributed
string format: decimal
ties_to_stripe
object
activity
object
count
integer
fee
string format: decimal
gross
string format: decimal
net
string format: decimal
balance_change
string format: decimal
payouts
object
count
integer
net
string format: decimal
unplaced_count
required
integer
Examplegenerated
{
"account_count": 1,
"from": "2026-04-15",
"line_count": 1,
"month": "example",
"platform_tenant_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"timezone": "example",
"to": "2026-04-15",
"totals": [
{
"by_category": [
{
"count": 1,
"fee": "example",
"gross": "example",
"net": "example",
"reporting_category": "example"
}
],
"currency": "example",
"hotels": {
"account_count": 1,
"dispute_costs": {
"amounts_recovered": "example",
"amounts_withdrawn": "example",
"carried": "example",
"fees_charged": "example",
"fees_recovered": "example"
},
"gross_captured": "example",
"net": "example",
"platform_fees_earned": "example",
"processor_fees_paid": "example",
"refunded": "example",
"unexplained": "example"
},
"net": "example",
"platform": {
"line_count": 1,
"net": "example",
"other": "example",
"payouts": "example",
"reserves": "example",
"stripe_fees": "example",
"tax_on_fees": "example",
"unattributed": "example"
},
"ties_to_stripe": {
"activity": {
"count": 1,
"fee": "example",
"gross": "example",
"net": "example"
},
"balance_change": "example",
"payouts": {
"count": 1,
"net": "example"
}
}
}
],
"unplaced_count": 1
}
Cache-Control
string

Always no-store. Object and link state is live data and is never cacheable.

The bearer authenticated but does not hold the scope this operation requires.

Media typeapplication/json

Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.

object
error
required
object
code
required

Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).

string
instance_id

Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.

string
message
required

Human-readable explanation of the failure.

string
parameters

Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).

Examplegenerated
{
"error": {
"code": "example",
"instance_id": "example",
"message": "example",
"parameters": "example"
}
}

month is missing or not YYYY-MM.

Media typeapplication/json

Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.

object
error
required
object
code
required

Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).

string
instance_id

Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.

string
message
required

Human-readable explanation of the failure.

string
parameters

Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).

Examplegenerated
{
"error": {
"code": "example",
"instance_id": "example",
"message": "example",
"parameters": "example"
}
}