---
title: "Rent vs buy over a holding period (present value)"
method: POST
path: "/v1/mortgage/rent-vs-buy"
tags: ["Utilities"]
---

# Rent vs buy over a holding period (present value)

`POST /v1/mortgage/rent-vs-buy`

## Request

- Base URL: `https://api.numeratica.com`
- URL: `https://api.numeratica.com/v1/mortgage/rent-vs-buy`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Compares the cost of buying a home against renting over a fixed holding period on a present-value basis. Every cash flow — mortgage, property tax, insurance, maintenance, HOA, rent, and the net proceeds from selling at the end — is discounted to today at the investment return, so the opportunity cost of the down payment is captured by the discount rate. The path with the lower present value of net cost wins. Most fields default to reasonable assumptions; deterministic; not lending, tax, or financial advice.

## Request body

- RentVsBuyRequest
  - `home_price` number, required
  - `down_payment` number, required: ≤ home_price.
  - `mortgage_rate` number, required: Annual APR.
  - `loan_term_months` integer: Omit for 360.
  - `closing_cost_rate` number: Buyer's closing costs, fraction of price; omit for 0.03.
  - `selling_cost_rate` number: Sale costs, fraction of price; omit for 0.06.
  - `property_tax_rate` number: Annual, fraction of home value; omit for 0.011.
  - `insurance_rate` number: Annual homeowner's, fraction of home value; omit for 0.005.
  - `maintenance_rate` number: Annual, fraction of home value; omit for 0.01.
  - `hoa_monthly` number
  - `home_appreciation` number: Annual; omit for 0.03, or set 0 for a flat market (a bare 0 is honored, not defaulted).
  - `monthly_rent` number, required
  - `rent_growth` number: Annual; omit for 0.03, or set 0 for flat rent (e.g. rent-controlled).
  - `renters_insurance_monthly` number
  - `holding_period_months` integer: Omit for 84 (7 yr).
  - `investment_return` number, required: Annual; the discount rate / opportunity cost.
  - `inflation` number: Annual; grows HOA + renters insurance; omit for 0.025, or set 0 to hold them flat.

## Response `200`

The rent-vs-buy comparison

- RentVsBuyResponse
  - `result_id` string
  - `engine_version` string
  - `inputs` RentVsBuyRequest
    - `home_price` number, required
    - `down_payment` number, required: ≤ home_price.
    - `mortgage_rate` number, required: Annual APR.
    - `loan_term_months` integer: Omit for 360.
    - `closing_cost_rate` number: Buyer's closing costs, fraction of price; omit for 0.03.
    - `selling_cost_rate` number: Sale costs, fraction of price; omit for 0.06.
    - `property_tax_rate` number: Annual, fraction of home value; omit for 0.011.
    - `insurance_rate` number: Annual homeowner's, fraction of home value; omit for 0.005.
    - `maintenance_rate` number: Annual, fraction of home value; omit for 0.01.
    - `hoa_monthly` number
    - `home_appreciation` number: Annual; omit for 0.03, or set 0 for a flat market (a bare 0 is honored, not defaulted).
    - `monthly_rent` number, required
    - `rent_growth` number: Annual; omit for 0.03, or set 0 for flat rent (e.g. rent-controlled).
    - `renters_insurance_monthly` number
    - `holding_period_months` integer: Omit for 84 (7 yr).
    - `investment_return` number, required: Annual; the discount rate / opportunity cost.
    - `inflation` number: Annual; grows HOA + renters insurance; omit for 0.025, or set 0 to hold them flat.
  - `result` object
    - `monthly_mortgage_payment` number
    - `upfront_cost` number: Down payment + buyer's closing costs.
    - `home_value_at_sale` number
    - `loan_balance_at_sale` number
    - `sale_proceeds` number: Home value × (1 − selling cost) − remaining balance.
    - `total_rent_paid` number: Nominal sum of rent over the holding period.
    - `buy_net_present_cost` number: PV of all ownership flows, net of sale proceeds.
    - `rent_net_present_cost` number: PV of all rental flows.
    - `cost_difference` number: rent − buy (positive ⇒ buying is cheaper by this PV).
    - `recommendation` 'buy' | 'rent'
  - `disclaimer` string

## Other responses

- `400`: Invalid request
- `401`: Missing or invalid API key.
- `405`: Method not allowed
- `429`: The key's per-minute request budget is exceeded. Retry after the delay in the Retry-After header.
- `503`: A dependency (e.g. the key store) is temporarily unavailable, or the request exceeded its compute deadline. Retryable.

---

[API](https://skmtc.dev/numeratica/apis/numeratica-financial-planning-calculations-api.md) · [All operations](https://skmtc.dev/numeratica/apis/numeratica-financial-planning-calculations-api/llms.txt) · [OpenAPI document](https://skmtc.dev/numeratica/apis/numeratica-financial-planning-calculations-api/revisions/075bcfbd1ebf?raw)
