Subscription Billing one day's renewals, each with its risk band
Returns one page of a single day’s renewals for the day drawer.
A day has two kinds of row and a subscription can be either: one still scheduled to bill on the date, or one whose charge already ran. Today has both. A renewal that qualifies as both — billed early and already scheduled again — is reported as settled, because an outcome that exists outranks a grade that predicts one.
The scheduled half repeats the billing pipeline’s own eligibility gates, so a renewal automatic billing will never claim is not listed as one the operator can expect to collect. The settled half applies none of them: what ran, ran.
Every row carries the risk band
Analytics::RenewalRiskBands gave it — the same classifier
behind the month grid’s at-risk figures. The band is served
rather than left to the caller precisely so a client cannot
keep a second copy of those rules and drift from the cell that
opened the drawer.
Authorizations
Bearer token authentication. Requires a company-admin token
whose role holds reports.view.
Query Parameters
Calendar date to list, as YYYY-MM-DD. Required and not
defaulted: the drawer is always opened from a day the operator
picked, so a missing date would answer for a different day than
the one on screen. A value that is not this exact shape, or one
that names a date which does not exist, returns 400 rather
than being coerced.
^\d{4}-\d{2}-\d{2}$"2026-09-17"
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"
1-based page number. Defaults to 1. Values below 1 are read
as 1.
x >= 11
Renewals per page. Defaults to 25 and is capped server-side at
100 — a day drawer is a working list rather than an export,
and the band lookup costs one extra query per page whatever its
size.
A larger value is clamped to the cap rather than rejected, so
the cap is deliberately not declared as a schema maximum:
doing so would publish a constraint the endpoint does not
enforce. Read per_page off the response for the size actually
applied.
x >= 125
Response
One page of the day's renewals
The date the roster covers.
Zone the scheduled half was bucketed in, echoed back so the drawer can label itself. The settled half ignores it: billing events carry an already-local date.
"America/Denver"
ISO code every amount on the response is quoted in.
"USD"
1-based page number this payload represents.
Page size actually applied, after clamping.
Renewals on the day across every page.
The day as a whole, independent of which page was requested — computed over the day's full scope, so paging never changes what these figures describe.
Two figures the prototype's day panel showed are absent rather
than estimated. A count of scheduled smart retries has no source:
billing events carry no retry marker, and the only real fact is
whether a retry is scheduled right now, which is per renewal.
New against returning is split per customer and not per
renewal, so it does not sum to renewal_count.