Read what the platform made and spent on a merchant account in a month
const url = 'https://api.aerandil.com/v1/merchant-accounts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/platform-earnings?month=example';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://api.aerandil.com/v1/merchant-accounts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/platform-earnings?month=example' \ --header 'Authorization: Bearer <token>'A fold over the platform’s own balance transactions for one hotel’s merchant account in the house’s calendar month (platform_ledger_line, read off Stripe with the platform’s key by the platform-ledger worker): the guest’s money captured, refunds, the application fees earned, Stripe’s processing fees paid, what chargebacks cost after pass-through (dispute_costs), the net of every line (net_platform_earning, to the penny) and what the fee and dispute lines do not explain (unexplained — a refund not reversed from the hotel, a capture never transferred). variance is Stripe’s actual fee less the class estimate over the payments carrying both; variance_gaps counts the payments missing one side. The platform operator’s read (tenant_admin:write): the margin and the variance are the platform’s, never the hotel’s — the night-audit close shows the hotel only what it paid.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The property’s merchant account.
Query Parameters
Section titled “Query Parameters”The house’s calendar month, YYYY-MM.
Responses
Section titled “Responses”The month’s platform earnings on the account.
object
object
object
object
object
Examplegenerated
{ "case_count": 1, "from": "2026-04-15", "line_count": 1, "merchant_account_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "month": "example", "payment_count": 1, "property_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "to": "2026-04-15", "totals": [ { "currency": "example", "dispute_costs": { "amounts_recovered": "example", "amounts_withdrawn": "example", "carried": "example", "fees_charged": "example", "fees_recovered": "example" }, "gross_captured": "example", "net_platform_earning": "example", "platform_fees_earned": "example", "processor_fees_paid": "example", "refunded": "example", "unexplained": "example", "variance": { "estimates": "example", "payments_compared": 1, "processor_fees": "example", "variance": "example" } } ], "unmatched_count": 1, "variance_gaps": { "missing_actual": 1, "missing_estimate": 1, "other_currency": 1 }}Headers
Section titled “Headers”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.
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
object
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).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
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" }}No such object in the caller’s tenant — which is also the answer when it exists in another tenant, by design.
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
object
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).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
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.
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
object
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).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
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" }}