Skip to content

Periods and ?asOf=

Every metric value is computed over a period — a range like last_fy, a month, or a point-in-time snapshot like "cash balance today". The API supports two query parameters:

  • ?period=… — required. Tells the registry which window to compute over.
  • ?asOf=… — optional. Tells the registry what date to treat as "today", so all relative periods resolve historically.

?period=

Three forms are accepted.

Relative keys

KeyMeaning
mtdMonth to date
qtdQuarter to date
ytdYear to date (FY-aligned)
this_monthThe current calendar month
last_monthThe previous calendar month
this_quarterThe current FY quarter
last_quarterThe previous FY quarter
this_fyThe current financial year
last_fyThe previous financial year
last_2_fyThe two FYs before this one
todaySnapshot — a point in time (use with asOf-style metrics like cash.balance)

Trailing windows: trailing_3, trailing_6, trailing_12 (any positive integer is accepted).

Absolute ISO range

?period=2024-04-01:2025-03-31

Both bounds are inclusive. Start must be on or before end, both must be valid YYYY-MM-DD.

Period kinds

The registry distinguishes range metrics (revenue, expenses, P&L totals) from snapshot metrics (cash balance, headcount, AR aging). Each metric declares which kind it accepts:

json
{ "id": "cash.balance", "periodKind": "snapshot" }
{ "id": "revenue.total", "periodKind": "range" }

Pass an incompatible period and you'll get 400 PERIOD_KIND_MISMATCH. Use today (or another snapshot key) for snapshot metrics; use mtd / last_fy / ISO range for range metrics.

?asOf=

Pin all relative period resolution to a historical date. Two acceptable values:

  • today (or omitted) — resolves against the current moment
  • ISO date YYYY-MM-DD — resolves as if today were that date
sh
# Today's MTD revenue
curl ".../metrics/revenue.total/value?period=mtd"

# MTD revenue as it stood on 1 December 2024
curl ".../metrics/revenue.total/value?period=mtd&asOf=2024-12-01"

Both calls hit the same metric with the same period spec. The asOf parameter rewrites what "today" means for the duration of that single request — so mtd, qtd, ytd, last_fy, trailing_12 and friends all resolve relative to the pinned date.

Snapshot metrics ignore asOf

If the period itself is fully self-contained (e.g. ?period=as_of:2024-12-01 for snapshot metrics), asOf has no effect. The period date wins.

Future dates are rejected

?asOf=2099-01-01
json
{ "error": { "code": "INVALID_AS_OF",
             "message": "asOf cannot be in the future: '2099-01-01'. We don't fabricate forward-looking values." } }

Worked example

A dashboard wants to render "what did the business look like on 1 December 2024?" Make one batch request with asOf at the top level — every metric in the batch shares the same reference date, so the dashboard is internally consistent:

json
POST /api/v1/metrics/batch
{
  "asOf": "2024-12-01",
  "queries": [
    { "key": "rev",    "id": "revenue.total",        "period": "ytd" },
    { "key": "expense","id": "expenses.total",       "period": "ytd" },
    { "key": "cash",   "id": "cash.balance",         "period": "today" },
    { "key": "people", "id": "headcount.active",     "period": "today" }
  ]
}

rev and expense resolve their YTD windows against the pinned date; cash and people snapshot at the same date. All four numbers describe one consistent moment in time.

OneBusiness · Built for businesses that work.