---
title: "Rent vs buy analysis"
method: POST
path: "/v1/rent-vs-buy"
tags: ["Data & Analytics"]
---

# Rent vs buy analysis

`POST /v1/rent-vs-buy`

## Request

- Base URL: `https://api.rateapi.dev`
- URL: `https://api.rateapi.dev/v1/rent-vs-buy`
- Auth: API key in header `X-API-Key`

Compares the projected cost of renting versus buying a home over a holding period, anchored to live market mortgage rates. Returns year-by-year cumulative cost of each path (rent vs PITI), equity built, net cost of owning after sale, the breakeven year, and a buy/rent recommendation. When no rate is supplied, the current best market rate for the state is resolved via the decision engine. This route is the single source of truth for the rent-vs-buy math; the MCP `analyze_rent_vs_buy` tool and the consumer app call it.

**Authentication required**: Pass your API key in the `X-API-Key` header.

## Request body

- object
  - `home_price` number, required: Purchase price in dollars. Required.
  - `monthly_rent` number, required: Current monthly rent in dollars. Required.
  - `down_payment` number: Cash down payment in dollars. Default 20% of home_price.
  - `rate` number: Annual interest rate (percent). If omitted, best market rate for the state is used (fallback 7.0).
  - `term_months` integer: Loan term in months. Default 360.
  - `state` string: 2-letter US state code. Default CA.
  - `holding_period_years` integer: Years you expect to stay before selling. Default 7.
  - `property_tax_rate` number: Annual property tax as % of home value. Default 1.1.
  - `annual_insurance` number: Homeowners insurance dollars/year. Default max(800, 0.35% of home price).
  - `monthly_hoa` number: Monthly HOA dues. Default 0.
  - `pmi_rate` number: Annual PMI as % of loan while LTV > 80%. Default 0.5.
  - `credit_score` number: Optional credit score passed to the rate engine.
  - `home_appreciation_rate` number: Annual home appreciation %. Default 3.0.
  - `rent_growth_rate` number: Annual rent growth %. Default 3.0.
  - `investment_return_rate` number: Opportunity-cost return % on invested savings if renting. Default 5.0.
  - `maintenance_rate` number: Annual maintenance as % of home value. Default 1.0.
  - `closing_cost_pct` number: Buyer closing costs as % of home price. Default 3.0.
  - `selling_cost_pct` number: Seller transaction costs as % of sale price. Default 6.0.
  - `marginal_tax_rate` number: Marginal tax rate % for mortgage-interest/property-tax deduction. Default 0 (no deduction modeled).

## Response `200`

Rent vs buy comparison

- object
  - `rate_used` number: The rate the calculation was run at, as an annual percentage.
  - `rate_source` 'provided' | 'market' | 'fallback': Where the rate used in this calculation came from: `provided` if the caller supplied it, `market` if it was taken from live offers, `fallback` if neither was available and a default was used.
  - `buy` object: The cost of buying over the holding period.
    - `monthly_piti` number: Monthly principal, interest, taxes, and insurance, in US dollars.
    - `monthly_breakdown` object: The monthly payment split into its components.
    - `year_by_year` object[]: Cost of owning in each year of the holding period.
    - `total_cost_over_period` number: Everything paid to own over the holding period, in US dollars.
    - `net_proceeds_at_sale` number: What the sale returns after the mortgage balance and selling costs, in US dollars.
    - `net_cost_after_equity` number: Total cost of owning less the equity recovered at sale, in US dollars — the figure comparable to renting.
  - `rent` object: The cost of renting over the same period.
    - `starting_monthly_rent` number: Rent in the first month, in US dollars.
    - `year_by_year` object[]: Cost of renting in each year of the holding period.
    - `total_cost_over_period` number: Everything paid in rent over the holding period, in US dollars.
    - `opportunity_value_of_invested_savings` number: What the money not spent on a down payment and ownership costs would be worth if invested instead, in US dollars.
  - `breakeven` object: When buying overtakes renting.
    - `year` integer, nullable: Year in which buying becomes cheaper, or null when it never does within the period.
    - `months` integer, nullable: Months until buying becomes cheaper, or null when it never does within the period.
    - `note` string: Plain-language explanation of what this result means.
  - `recommendation` 'buy' | 'rent' | 'too_close_to_call': Which option comes out ahead over the holding period.
  - `confidence` string: How decisive the gap between the two options is: `high` when one clearly wins, `medium` when the margin is narrower, `low` when they are close enough to call a tie.
  - `summary_note` string: Plain-language summary of the comparison.
  - `assumed_defaults` object[]: Values filled in where the caller supplied none, so the result is reproducible.
  - `next_actions` object[]: Other endpoints or tools that are the natural next step from this result.
  - `disclosures` string[]: Statements that must be shown to a consumer alongside this result.

## Other responses

- `400`: Invalid request
- `401`: No API key, or a key that is unknown or disabled. Send it in the `X-API-Key` header. Free keys are issued instantly by POST /keys with an email address. The response carries `WWW-Authenticate` pointing at this host's protected-resource metadata, and the `RateLimit-*` headers describing the Free-tier budget a key issued now would carry (scope `anonymous`) — a rejected request spends none of it, so `Remaining` equals `Limit`.
- `429`: Quota exhausted for the current window. `Retry-After` gives the seconds to wait; `upgradeInfo` explains how to lift the cap. Retrying before the reset will fail again and still counts as a request.

---

[API](https://skmtc.dev/rateapi/apis/rate-api.md) · [All operations](https://skmtc.dev/rateapi/apis/rate-api/llms.txt) · [OpenAPI document](https://skmtc.dev/rateapi/apis/rate-api/revisions/06a6db76995f?raw)
