Budget Analytics Endpoint
const url = 'https://example.com/api/v1/budget/analytics?include_empty_months=false&exclude_from_spending=false';const options = {method: 'GET'};
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://example.com/api/v1/budget/analytics?include_empty_months=false&exclude_from_spending=false'Full-history monthly income/expense totals, a per-category monthly
expense breakdown, and active budget limits – no time-window cap
(supersedes the original TODO.md stub’s ?year=&month= query params;
by design: no cap). date_from/date_to optionally
narrow the returned range (both inclusive); omitting both preserves the
original full-history, no-cap behavior. account_ids optionally narrows
both aggregate queries to the given accounts (repeatable, OR’d).
include_empty_months=true lists every calendar month of the window, months without a
transaction included; it needs both dates, a window of at most 60 months, and an end
date no later than 60 months after the current month. exclude_from_spending=true leaves out
the transactions whose category is flagged exclude_from_spending, from every figure.
Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Responses
Section titled “Responses”Successful Response
Full-history monthly income/expense analytics plus active budget limits, returned by GET /api/v1/budget/analytics – see get_budget_analytics() for aggregation details.
object
One month’s income/expense totals plus per-category expense breakdown, as aggregated by get_budget_analytics(). budget_rollovers only contains entries for rollover-enabled budgets active in this month (empty for months before a budget’s creation month).
object
One category(/subcategory)’s aggregated amount within a single month, built explicitly by get_budget_analytics() (no from_attributes – not a direct ORM row), matching TransactionConvertedOut’s convention. subcategory_id is None for the category’s own (no-subcategory) transactions, mirroring Transaction.subcategory_id’s own optional semantics – summing every row sharing a category_id (regardless of subcategory_id) reproduces the pre-subcategory category-level total exactly, which is what a category-level Budget (subcategory_id None) must still match against.
One rollover-enabled budget’s live-computed carryover for a single month, built by compute_rollover_balances() – never persisted (see Budget.rollover_enabled docstring). effective_limit is monthly_limit plus rollover_carried (the envelope credit brought into this month from prior months); rollover_carried floors at zero, so an over-budget month never creates a debt that reduces a future month’s effective_limit.
One active budget’s category/subcategory/limit, as returned by get_budget_analytics() alongside the monthly breakdown. subcategory_id is None for a category-level budget. id/created_at/rollover_enabled are exposed so a client can correlate this budget with the per-month BudgetRolloverOut entries keyed by budget_id. month_limits holds this budget’s own month limits by month key, overrides only: a month absent from the map uses monthly_limit.
object
object
Example
{ "months": [ { "budget_rollovers": [] } ], "budgets": [ { "month_limits": {} } ], "missing_rate_currencies": []}Validation Error
object
object
object
Example generated
{ "detail": [ { "loc": [ "example" ], "msg": "example", "type": "example", "input": "example", "ctx": {} } ]}