Reports

Accounts payable report

Ages the unpaid vendor bill line items into buckets by how far each one is from its due date. One row is one vendor, property or portfolio depending on groupBy, and each column is an age bucket holding an amount and a bill count.

GET
https://api.portal.magicdoor.com/company-app/reports/accounts-payable

Authorization

Authorizationstringrequired
Bearer token — Send your API token in the Authorization header as Bearer <token>. Requests without a valid token are rejected with 401 Unauthorized.

Query parameters

asOfDatestring · date

The date to age the bills against, included. Read in the company's timezone. Leave it out to age against everything recorded.

example: 2026-03-31
groupByenum<string>

What one row stands for: everything on one line, one line per vendor, per property, or per portfolio.

default: totalexample: vendortotalvendorpropertyportfolio
vendorIdsstring[]

Only include bills owed to these vendors. Repeat the parameter once per id.

boundariesDaysinteger[]

Where the age buckets break, in days. Repeat the parameter once per boundary. Leave it out for the default of 7, 15, 30 and 60.

default: 7, 15, 30, 60
includeOverdueboolean

Whether to add the mirrored overdue buckets for bills already past their due date.

default: true
companyBillsboolean

Filter on who pays. Leave it out to include everything, set it true for bills the management company pays, false for bills the owner pays.

portfolioIdsstring[]

Narrow the report to these portfolios. Repeat the parameter once per id. An id that does not exist returns 404.

propertyIdsstring[]

Narrow the report to these properties. Repeat the parameter once per id. An id that does not exist returns 404.

Response

200 · The aged payables.

groupHeadersobject[]

The age buckets in order, followed by a total column. Their id values are the keys used inside every columns and grandTotals object.

linesobject[]

One row per group.

grandTotalsobject

The same figures added across every row, keyed by bucket key.

vendorsobject[]

Every vendor named by a row.

propertiesobject[]

Every property named by a row.

portfoliosobject[]

Every portfolio named by a row.

401 · The access token is missing, expired, or not valid for this company.

404 · A portfolio, property or owner id in the query does not exist in the caller's company.

How scoping works

portfolioIds and propertyIds are resolved down to one set of properties and narrow each other rather than adding up. This report does not take ownerIds, unlike most of the others here.

groupHeaders names the age buckets in order, then adds a total column at the end. Every amount object in the report, on a row and in grandTotals, is keyed by those bucket keys. Each value is a pair: amount is money still owed, billCount is how many bills make it up.

boundariesDays moves the bucket edges. It defaults to 7, 15, 30, 60, which with includeOverdue left on produces these twelve columns:

Bucket keyHeadingWhich bills land in it
od_>60Overdue >60 DaysMore than 60 days past due
od_31-60Overdue 31-60 Days31 to 60 days past due
od_16-30Overdue 16-30 Days16 to 30 days past due
od_8-15Overdue 8-15 Days8 to 15 days past due
od_1-7Overdue 1-7 Days1 to 7 days past due
todayDue TodayDue on the as-of date itself
1-71-7 DaysFalling due in the next 1 to 7 days
8-158-15 DaysFalling due in 8 to 15 days
16-3016-30 DaysFalling due in 16 to 30 days
31-6031-60 DaysFalling due in 31 to 60 days
>60>60 DaysFalling due more than 60 days out
totalTotalThe row's whole outstanding balance

Sending your own boundariesDays rebuilds the keys the same way. Boundaries of 30 and 90 give od_>90, od_31-90, od_1-30, today, 1-30, 31-90, >90 and total. Turning includeOverdue off drops every od_ bucket.

It ages line items, not whole bills

A vendor bill's line items are aged one by one, and only those with an outstanding amount are counted. billCount counts the distinct bills contributing to a bucket, so one bill split across two buckets is counted in both.