Developers
API reference

Plan

get/v1/plan

Get the plan

plan.getread tokenidempotent

The plan's settings (retirement age, return and inflation assumptions, overrides) and where the household stands today. A ledger that never set a plan answers with the defaults.

Parameters

X-Organization-Id
string | null · header

Returns 200 · PlanOut

settings
PlanSettings · required
starting_point
StartingPoint · required
Example
curl -X GET "https://api.lumaledger.app/v1/plan" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
patch/v1/plan

Update the plan

plan.updatewrite tokenidempotent

Change the plan's settings: birth year, retirement age, how long to plan for, income or spending overrides, and the return, volatility, inflation and growth assumptions. Only the fields sent change.

Parameters

X-Organization-Id
string | null · header

Body · PlanUpdate

birth_year
integer | null
expected_return_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.
income_growth_rate_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.
inflation_rate_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.
monthly_income_override
string | null
Pattern: ^\d{1,12}(\.\d{1,2})?$.
monthly_spending_override
string | null
Pattern: ^\d{1,12}(\.\d{1,2})?$.
plan_to_age
integer | null
After retirement_age.
property_growth_rate_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.
retirement_age
integer | null
retirement_income_monthly
string | null
Pattern: ^\d{1,12}(\.\d{1,2})?$.
retirement_spending_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.
return_volatility_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.

Returns 200 · PlanOut

settings
PlanSettings · required
starting_point
StartingPoint · required
Example
curl -X PATCH "https://api.lumaledger.app/v1/plan" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
get/v1/plan/milestones

List plan milestones

plan_milestones.listread tokenidempotent

The milestones on the plan: a home, a car, a big purchase, a windfall, a change in income, a new recurring cost.

Parameters

limit
integer · query
Page size, 1–200.
cursor
string | null · query
The next_cursor of the previous page.
X-Organization-Id
string | null · header

Returns 200 · PlanMilestoneList

data
array of PlanMilestone · required
has_more
boolean · required
next_cursor
string | null · required
Example
curl -X GET "https://api.lumaledger.app/v1/plan/milestones" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
post/v1/plan/milestones

Add a plan milestone

plan_milestones.createwrite tokenidempotent

Put something the household can see coming on the plan: "a $650k house in June 2028, 20% down", a windfall, a raise, childcare from next year. The projection accounts for it from then on.

Parameters

Idempotency-Key
string | null · header
Any unique string (a UUID is ideal). A retry with the same key returns the first attempt's response instead of doing the work twice. Keys are kept for 24 hours.
X-Organization-Id
string | null · header

Body · PlanMilestoneCreate

amount
string · required
Decimal string. Positive, except an income_change, which may be negative (a cut) but not zero. Pattern: ^-?\d{1,12}(\.\d{1,2})?$.
ends_on
date | null
For income_change and recurring_expense only.
is_enabled
boolean
Default: true.
kind
string · required
One of: home_purchase, vehicle_purchase, big_purchase, windfall, income_change, recurring_expense, time_off.
label
string · required
starts_on
date · required
This month or later.
terms
object
The kind's own terms; every one is optional and has a default. home_purchase: down_payment_pct, mortgage_rate_pct, term_years, maintenance_pct, hoa_monthly, replaces_housing (bool), appreciation_pct (null: the plan's property growth). vehicle_purchase: down_payment_pct, loan_rate_pct, term_years, depreciation_pct. Other kinds take none. Numbers other than term_years are decimal strings.

Returns 201 · PlanMilestone

amount
Money · required
A price or a windfall in that day's money; a monthly cost or change in earnings in today's money. Negative only for an income cut.
ends_on
date | null · required
For income_change and recurring_expense only.
id
integer · required
is_enabled
boolean · required
Switched off: kept, but left out of the projection.
kind
string · required
One of: home_purchase, vehicle_purchase, big_purchase, windfall, income_change, recurring_expense, time_off.
label
string · required
starts_on
date · required
terms
object · required
The kind's own terms; every one is optional and has a default. home_purchase: down_payment_pct, mortgage_rate_pct, term_years, maintenance_pct, hoa_monthly, replaces_housing (bool), appreciation_pct (null: the plan's property growth). vehicle_purchase: down_payment_pct, loan_rate_pct, term_years, depreciation_pct. Other kinds take none. Numbers other than term_years are decimal strings.
Example
curl -X POST "https://api.lumaledger.app/v1/plan/milestones" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "650000.00",
    "kind": "…",
    "label": "…",
    "starts_on": "2026-09-01"
  }'
delete/v1/plan/milestones/{milestone_id}

Delete a plan milestone

plan_milestones.deletewrite tokendestructiveidempotent

Take a milestone off the plan.

Parameters

milestone_id
integer · path · required
X-Organization-Id
string | null · header

Returns 204 with no body.

Example
curl -X DELETE "https://api.lumaledger.app/v1/plan/milestones/{milestone_id}" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
get/v1/plan/milestones/{milestone_id}

Get a plan milestone

plan_milestones.getread tokenidempotent

One milestone by its id.

Parameters

milestone_id
integer · path · required
X-Organization-Id
string | null · header

Returns 200 · PlanMilestone

amount
Money · required
A price or a windfall in that day's money; a monthly cost or change in earnings in today's money. Negative only for an income cut.
ends_on
date | null · required
For income_change and recurring_expense only.
id
integer · required
is_enabled
boolean · required
Switched off: kept, but left out of the projection.
kind
string · required
One of: home_purchase, vehicle_purchase, big_purchase, windfall, income_change, recurring_expense, time_off.
label
string · required
starts_on
date · required
terms
object · required
The kind's own terms; every one is optional and has a default. home_purchase: down_payment_pct, mortgage_rate_pct, term_years, maintenance_pct, hoa_monthly, replaces_housing (bool), appreciation_pct (null: the plan's property growth). vehicle_purchase: down_payment_pct, loan_rate_pct, term_years, depreciation_pct. Other kinds take none. Numbers other than term_years are decimal strings.
Example
curl -X GET "https://api.lumaledger.app/v1/plan/milestones/{milestone_id}" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
patch/v1/plan/milestones/{milestone_id}

Update a plan milestone

plan_milestones.updatewrite tokenidempotent

Change a milestone, or switch it off and on (is_enabled) to see the projection with and without it. Only the fields sent change.

Parameters

milestone_id
integer · path · required
X-Organization-Id
string | null · header

Body · PlanMilestoneUpdate

amount
string | null
Pattern: ^-?\d{1,12}(\.\d{1,2})?$.
ends_on
date | null
is_enabled
boolean | null
kind
string | null
label
string | null
starts_on
date | null
terms
object | null
The kind's own terms; every one is optional and has a default. home_purchase: down_payment_pct, mortgage_rate_pct, term_years, maintenance_pct, hoa_monthly, replaces_housing (bool), appreciation_pct (null: the plan's property growth). vehicle_purchase: down_payment_pct, loan_rate_pct, term_years, depreciation_pct. Other kinds take none. Numbers other than term_years are decimal strings.

Returns 200 · PlanMilestone

amount
Money · required
A price or a windfall in that day's money; a monthly cost or change in earnings in today's money. Negative only for an income cut.
ends_on
date | null · required
For income_change and recurring_expense only.
id
integer · required
is_enabled
boolean · required
Switched off: kept, but left out of the projection.
kind
string · required
One of: home_purchase, vehicle_purchase, big_purchase, windfall, income_change, recurring_expense, time_off.
label
string · required
starts_on
date · required
terms
object · required
The kind's own terms; every one is optional and has a default. home_purchase: down_payment_pct, mortgage_rate_pct, term_years, maintenance_pct, hoa_monthly, replaces_housing (bool), appreciation_pct (null: the plan's property growth). vehicle_purchase: down_payment_pct, loan_rate_pct, term_years, depreciation_pct. Other kinds take none. Numbers other than term_years are decimal strings.
Example
curl -X PATCH "https://api.lumaledger.app/v1/plan/milestones/{milestone_id}" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
get/v1/plan/projection

Project net worth

plan.projectionread tokenidempotent

Run the forecast: net worth month by month to the end of the plan, as a median and ranges over many market paths, with the odds of each milestone and of the money lasting through retirement. Slower than the other reads; call it when the answer is needed, not on every change.

Parameters

X-Organization-Id
string | null · header

Returns 200 · Projection

birth_year
integer | null · required
headline_age
integer | null · required
headline_date
date · required
headline_net_worth
Money · required
Median net worth at retirement, or at the end of the plan with no retirement age to stand on.
milestones
array of MilestoneOutcome · required
monthly_housing
Money · required
monthly_income
Money · required
What the projection ran on, after the plan's overrides.
monthly_spending
Money · required
paths
integer · required
How many market paths were simulated.
points
array of ProjectionPoint · required
One per month, from this month to the plan's end.
retirement
RetirementOutcome | null · required
runs_out_age
integer | null · required
runs_out_month
integer | null · required
Index into points where the median path runs out of money.
underwater
array of string · required
Debts whose payment never covers their interest, carried at their balance.
Example
curl -X GET "https://api.lumaledger.app/v1/plan/projection" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"

Objects

MilestoneOutcome

Fields

affordability
string | null · required
A home's mortgage-calculator verdict, as a rating.
age
integer | null · required
amount
Money · required
chance
string | null · required
Share of market paths, 0.0000–1.0000, in which it is paid for without the money running out. Null for money arriving and for a milestone switched off.
date
date · required
is_enabled
boolean · required
kind
string · required
label
string · required
milestone_id
integer · required
month
integer · required
Index into points: where on the projection it lands.
monthly
Money · required
What it costs (or brings in) each month after.
net_worth
Money · required
Median net worth that month.
rating
string | null · required
on_track, stretch or out_of_reach.
upfront
Money · required
What changes hands on the day.

Money

An amount and its currency. `amount` is a base-10 string with two decimal places and an optional leading minus sign. Parse it with a decimal type, not a float.

Fields

amount
string · required
Pattern: ^-?\d+\.\d{2}$.
currency
string · required
ISO 4217 code. Pattern: ^[A-Z]{3}$.

PlanDebt

Fields

account_id
integer · required
The liability account.
annual_rate_pct
string · required
balance
Money · required
monthly_payment
Money · required
name
string · required

PlanMilestone

Something the household can see coming, on the projection.

Fields

amount
Money · required
A price or a windfall in that day's money; a monthly cost or change in earnings in today's money. Negative only for an income cut.
ends_on
date | null · required
For income_change and recurring_expense only.
id
integer · required
is_enabled
boolean · required
Switched off: kept, but left out of the projection.
kind
string · required
One of: home_purchase, vehicle_purchase, big_purchase, windfall, income_change, recurring_expense, time_off.
label
string · required
starts_on
date · required
terms
object · required
The kind's own terms; every one is optional and has a default. home_purchase: down_payment_pct, mortgage_rate_pct, term_years, maintenance_pct, hoa_monthly, replaces_housing (bool), appreciation_pct (null: the plan's property growth). vehicle_purchase: down_payment_pct, loan_rate_pct, term_years, depreciation_pct. Other kinds take none. Numbers other than term_years are decimal strings.

PlanMilestoneCreate

Fields

amount
string · required
Decimal string. Positive, except an income_change, which may be negative (a cut) but not zero. Pattern: ^-?\d{1,12}(\.\d{1,2})?$.
ends_on
date | null
For income_change and recurring_expense only.
is_enabled
boolean
Default: true.
kind
string · required
One of: home_purchase, vehicle_purchase, big_purchase, windfall, income_change, recurring_expense, time_off.
label
string · required
starts_on
date · required
This month or later.
terms
object
The kind's own terms; every one is optional and has a default. home_purchase: down_payment_pct, mortgage_rate_pct, term_years, maintenance_pct, hoa_monthly, replaces_housing (bool), appreciation_pct (null: the plan's property growth). vehicle_purchase: down_payment_pct, loan_rate_pct, term_years, depreciation_pct. Other kinds take none. Numbers other than term_years are decimal strings.

PlanMilestoneList

A page of milestones, by id.

Fields

data
array of PlanMilestone · required
has_more
boolean · required
next_cursor
string | null · required

PlanMilestoneUpdate

Only the fields sent change. terms, when sent, replaces them all.

Fields

amount
string | null
Pattern: ^-?\d{1,12}(\.\d{1,2})?$.
ends_on
date | null
is_enabled
boolean | null
kind
string | null
label
string | null
starts_on
date | null
terms
object | null
The kind's own terms; every one is optional and has a default. home_purchase: down_payment_pct, mortgage_rate_pct, term_years, maintenance_pct, hoa_monthly, replaces_housing (bool), appreciation_pct (null: the plan's property growth). vehicle_purchase: down_payment_pct, loan_rate_pct, term_years, depreciation_pct. Other kinds take none. Numbers other than term_years are decimal strings.

PlanOut

The plan's settings beside today's starting point. Milestones are listed by plan_milestones.list, the forecast by plan.projection.

Fields

settings
PlanSettings · required
starting_point
StartingPoint · required

PlanSettings

The assumptions the projection runs on.

Fields

birth_year
integer | null · required
Ages on the projection count from it. Null until set.
expected_return_pct
string · required
Mean yearly return on investments.
income_growth_rate_pct
string · required
inflation_rate_pct
string · required
monthly_income_override
Money | null · required
After-tax income per month to plan with instead of the ledger's average.
monthly_spending_override
Money | null · required
Spending per month to plan with instead of the ledger's average.
plan_to_age
integer · required
How far the projection runs.
property_growth_rate_pct
string · required
retirement_age
integer · required
retirement_income_monthly
Money · required
Pension or social security per month, in today's money.
retirement_spending_pct
string · required
Spending in retirement, as a percentage of today's.
return_volatility_pct
string · required
Yearly standard deviation of that return.

PlanUpdate

Only the fields sent change. null clears a nullable field.

Fields

birth_year
integer | null
expected_return_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.
income_growth_rate_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.
inflation_rate_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.
monthly_income_override
string | null
Pattern: ^\d{1,12}(\.\d{1,2})?$.
monthly_spending_override
string | null
Pattern: ^\d{1,12}(\.\d{1,2})?$.
plan_to_age
integer | null
After retirement_age.
property_growth_rate_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.
retirement_age
integer | null
retirement_income_monthly
string | null
Pattern: ^\d{1,12}(\.\d{1,2})?$.
retirement_spending_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.
return_volatility_pct
string | null
Pattern: ^-?\d{1,3}(\.\d{1,3})?$.

Projection

Projected net worth, month by month, over many market paths.

Fields

birth_year
integer | null · required
headline_age
integer | null · required
headline_date
date · required
headline_net_worth
Money · required
Median net worth at retirement, or at the end of the plan with no retirement age to stand on.
milestones
array of MilestoneOutcome · required
monthly_housing
Money · required
monthly_income
Money · required
What the projection ran on, after the plan's overrides.
monthly_spending
Money · required
paths
integer · required
How many market paths were simulated.
points
array of ProjectionPoint · required
One per month, from this month to the plan's end.
retirement
RetirementOutcome | null · required
runs_out_age
integer | null · required
runs_out_month
integer | null · required
Index into points where the median path runs out of money.
underwater
array of string · required
Debts whose payment never covers their interest, carried at their balance.

ProjectionPoint

Net worth one month out: the median path and the edges of three ranges.

Fields

age
integer | null · required
assets
Money · required
Owned outside cash and investments (the same on every path).
date
date · required
debts
Money · required
Owed (the same on every path).
high_50
Money · required
The 75th percentile.
high_80
Money · required
The 90th percentile.
high_95
Money · required
The 97.5th percentile.
inflation_factor
string · required
Divide an amount by this for today's money.
liquid
Money · required
Median of cash plus investments.
low_50
Money · required
The 25th percentile.
low_80
Money · required
The 10th percentile.
low_95
Money · required
The 2.5th percentile.
median
Money · required

RetirementOutcome

Fields

age
integer · required
chance
string · required
Share of paths, 0.0000–1.0000, in which the money lasts.
date
date · required
month
integer · required
Index into points.
net_worth
Money · required
rating
string · required
on_track, stretch or out_of_reach.
runs_out_at_age
integer | null · required

StartingPoint

Where the household stands, read from the ledger just now.

Fields

cash
Money · required
debts
array of PlanDebt · required
income_months
integer · required
Months the averages cover; 0 means nothing to average.
invested
Money · required
monthly_housing
Money · required
Rent, or the running costs of a home.
monthly_income
Money · required
After tax, averaged over the trailing months.
monthly_spending
Money · required
Everything but housing and debt service.
net_worth
Money · required
other_assets
Money · required
real_estate
Money · required
vehicles
Money · required