Subscription Billing month grid (scheduled, at risk, settled)
Returns one row per date in the requested month — what is scheduled to bill, how much of it is graded at risk, and what already settled — plus the previous month’s totals for the month-over-month figure. Both months come from one service call over a single widened range, so the comparison cannot be assembled from two reads of different data.
Two halves, two sources. Days still to come read
commerce_subscriptions.next_bill_date, bucketed in the tz
the operator is reading in (echoed back as time_zone). Days
that have run read commerce_billing_events, whose
local_billed_date is already local.
Money is price * quantity, which is what a renewal charges.
Note that the Home > Overview subscription-engine and
payment-recovery cards still sum bare price, so they read low
against this endpoint for any fleet carrying quantity > 1
until that is corrected.
Renewals are graded at risk by a deterministic read of dunning state — prior declines, hard declines, staleness, whether the retry chain has them in hand. No per-renewal likelihood is served; nothing in the platform produces one.
Authorizations
Bearer token authentication. Requires a company-admin token
whose role holds reports.view.
Query Parameters
Calendar month to report on, as YYYY-MM. Defaults to the
current month. A value that is not this exact shape (or names
a month that does not exist, such as 2026-13) returns 400
rather than being coerced.
^\d{4}-\d{2}$"2026-09"
ISO alpha-2 code of one of the requesting company's configured
countries (see GET /countries). When present, every service
on this endpoint filters its data to that country and reports
money in the country's own currency. Omit (or send "all")
for the aggregate-across-countries view, which is the default
and matches pre-Phase-004 behavior. Unknown ISO codes or ones
the company is not configured for return 400.
"US"
IANA timezone name (e.g. America/Denver) or Rails-style
alias (Eastern Time (US & Canada)) used to anchor
"today" boundaries and hour-of-day bucketing. The
frontend sends
Intl.DateTimeFormat().resolvedOptions().timeZone.
Unknown or malformed values silently fall back to UTC —
callers omit the param when the endpoint doesn't need
wall-clock alignment (see CURRENT-3077).
"America/Denver"
Response
Month grid payload
First of the month reported.
"2026-09-01"
IANA zone the scheduled half was bucketed in — the tz
that was sent, or UTC when it was missing or unknown.
Echoed so the grid can label which day boundaries it is
drawing. The settled half needs no such note: billing
events carry an already-local date.
"America/Denver"
ISO 4217 three-letter code (uppercase).
3"USD"
One entry per date in the month, ascending, always the full month. A quiet month returns zero-filled days rather than an empty array, so the grid can tell "nothing happened" from "nothing loaded".
Month-level sums. renewal_* rolls scheduled and overdue
together; the two questions differ, and a previous month is
always read after its own overdue floor has passed, so a
month-over-month comparison against scheduled_* alone would
show nothing there.
Month-level sums. renewal_* rolls scheduled and overdue
together; the two questions differ, and a previous month is
always read after its own overdue floor has passed, so a
month-over-month comparison against scheduled_* alone would
show nothing there.