Developers & AI agents

The REIzer deal-analysis API

Underwrite any residential investment deal over plain JSON — the same engine, scoring, and stress tests as the REIzer analyzers, across all six strategies.

  • Free analysis endpoints
  • No key, no account
  • Shareable report pages
Terminal
$ curl -X POST https://reizer.io/api/v1/analyze \
    -d '{"strategy":"ltr","inputs":{"price":285000,…}}'

{ "score": 96, "verdict": "Strong", "report_url": "…" }
7endpoints
6strategies
$0analysis tier
30-dayreport pages
Docs navigation

Quickstart — one curl, no key

Terminal
$ curl -X POST https://reizer.io/api/v1/analyze \
    -H "Content-Type: application/json" \
    -d '{"strategy":"ltr","inputs":{"price":285000,"marketRent":3100,
         "downPct":0.25,"rate":0.0675}}'
response (live, abbreviated)
{
  "score": 96, "verdict": "Strong",
  "metrics": { "monthly_cash_flow": 636.85, "dscr": 1.4594,
               "cap_rate": 0.0852, "cash_on_cash": 0.0989,  },
  "stress": [ 7 scenarios, each with a verdict ],
  "thresholds": { "break_even_rent": 2282.47, "max_rate": 0.0878,  },
  "assumptions": { "estimated_fields": ["taxes", "insurance", ] },
  "summary": "Strong (96/100). $637/mo cash flow, DSCR 1.46, …",
  "report_url": "https://reizer.io/report.html?id=…"
}

Endpoints

EndpointWhat it doesAccess
POST /api/v1/analyzeFull underwrite of one strategy: score, metrics, stress tests, thresholds, shareable report.FREE
POST /api/v1/best-useRuns every strategy the inputs qualify for and ranks them.FREE
POST /api/v1/maoMaximum allowable offer for your return targets — solved on the real engine.FREE
GET /api/v1/strategiesMachine-readable input schema for every strategy.FREE
GET /api/v1/reports/:idThe analysis data behind a shareable report page (30-day TTL).FREE
POST /api/v1/compsReal sale + rental comparables and ZIP market stats for an address.API KEY
POST /api/v1/str-compsNearby STR listings with ADR / occupancy / revenue for coordinates.API KEY

Input rules

Money-field units

Dollar inputs use these periods (same on every strategy, including STR). Percents stay fractions as above. Discover the full schema at GET /api/v1/strategies.

FieldUnitNotes
price, arv, rehabBudget, …$ (one-time)Purchase / sale / rehab dollars
marketRent, ltrRent$/moGross monthly rent
hoa$/moAll strategies, including STR
utilities$/moOwner-paid utilities
otherIncome$/mo
taxes, insurance$/yrAnnual totals
reserves$/yrFlat annual reserve (not CapEx %)

Changelog (2026-08-16): hoa is monthly on every strategy, including STR. Earlier engine builds treated STR HOA as annual; callers that inferred that from behaviour should send monthly dollars going forward. API_VERSION remains v1 — the old annual-STR behaviour was never documented.

Best-use ranking

Send one property's inputs as a superset; strategies missing required fields are skipped with the reason:

POST /api/v1/best-use — response (real ranking)
"best_use": "ltr"
"ranked":  1. ltr 91 · 2. str 77 · 3. brrr 29 · 4. flip 5
"skipped": multifamily, newc  (missing unit / land inputs)

Max allowable offer

Targets are optional — rentals default to cash-on-cash ≥ 8%, DSCR ≥ 1.2, cash flow ≥ $0; flips to after-tax margin ≥ 10% and annualized ROI ≥ 15%; BRRRR adds capital recovery ≥ 80%. The response names the binding constraint and each target's individual price ceiling:

POST /api/v1/mao — response (real solve)
"mao": 303657   "binding_constraint": "cash-on-cash return ≥ 8%"
"metrics_at_mao": { "monthlyCF": 546.10, "dscr": 1.3697 }
"ceilings_per_target": { "cocReturn": 303657, "dscr": 346599, "monthlyCF": 333691 }

Beyond the defaults, each strategy accepts optional targets that bind only when you name them: capRate on rentals and STR (plus dscr on STR), afterTaxProfit and rule70 on flips, and coc, cashLeft and rule70 on BRRRR. cashLeft is a ceiling, not a floor — the solve keeps cash left in the deal at or below your number. BRRRR metrics depend on which refinance you underwrite to, so "scenario": "refiLTV1" | "refiLTV2" | "refiLTV3" picks one; omit it and the engine's winning scenario is used.

Shareable reports

Every /analyze response carries a report_url — a public report page (score gauge, metrics, stress table) that needs no account to view and expires after 30 days. Built to be handed to the person you're advising; GET /api/v1/reports/:id serves the underlying data.

/analyze takes two optional blocks that only affect that page. propertyname, address, city, county, state, zip, beds, baths, sqft, type — puts a header and a map on the report; anything else in it is dropped, and nothing in it reaches the analysis. mao{ "targets": { … }, "scenario": "…" } — adds a max-allowable-offer section, re-solved server-side from the same inputs. A MAO that can't be solved drops the section rather than failing the analysis.

Keyed endpoints — licensed data

Analysis runs on REIzer's own engine and stays free. What costs money — licensed comps and STR market data — needs an API key from a paid plan (Investor and up), metered against the same monthly allowances as the web app. Create keys under Settings → API keys; send them as X-API-Key or Authorization: Bearer.

Terminal
$ curl -X POST https://reizer.io/api/v1/comps \
    -H "Content-Type: application/json" \
    -H "X-API-Key: rz_live_…" \
    -d '{"action":"comps",
         "address":{"street":"4917 Maple Ave","city":"Dallas","state":"TX"},
         "options":{"saleCount":10,"rentCount":10}}'

The comps body takes a nested address object (a flat street/city/state body returns an empty result, not an error). /api/v1/comps returns comparable sales with a value estimate and range, rental comps with a rent estimate, and ZIP-level market stats. /api/v1/str-comps takes latitude/longitude (+ optional bedrooms) and returns nearby STR listings with ADR, occupancy, and revenue quartiles. Full argument tables: tool catalog — the REST bodies match the MCP tool arguments.

Keys are shown once at creation, revocable instantly, and the plan is resolved live on every call — a downgrade or revocation takes effect immediately.

Rate limits & errors

StatusMeaning
400Invalid request — the error lists each offending field and why (missing, negative, percent-style, unknown strategy or target).
401Missing, malformed, unknown, or revoked API key on a keyed endpoint.
402Valid key, but the plan lacks API access or the monthly allowance is used up — the response links the fix.
404Unknown route or expired report id.
429Analysis rate limit, shared with the MCP server. Anonymous: 20/min, 500/day per IP. With an API key you're metered per account at your plan's ceiling (Investor 30/min · 1,000/day, Pro 60 · 5,000, Elite 120 · 20,000). The response carries retry_after, a Retry-After header, and metered_as.
503Key verification temporarily unavailable — fail-closed, retry shortly.

FAQ

Is it production-ready?

Yes — beta label, stable contract, and it's the same engine the REIzer product runs on, held to the same test suite.

Why fractions instead of percents?

No unit ambiguity for AI callers. 6.75 could mean 6.75% or 675% — so it's rejected loudly instead of guessed at.

Is any of the output AI-generated?

No. The engine is deterministic and the summaries are templated — same inputs, same answer, every time. Your AI adds the narration on its side.

What data do you store?

Anonymous analysis requests persist only the report payload behind report_url, which expires after 30 days. See the privacy policy.

Same engine, as AI-native tools.

The MCP server exposes all of this to Claude, Cursor, and ChatGPT — one command, nothing to host.

6native tools via MCP
1command to connect
0servers for you to host