Review a listing in one call
Use /analyze to combine a property lookup, rent estimate, financial metrics, and selected AI report sections. Supply your target rent or purchase price to override an estimate.
Use one request to look up a U.S. property, estimate rent, calculate rental underwriting metrics, and create an AI-assisted report—or call each step on its own.
Responses contain normalized estimates and calculations. The API does not return raw property-provider records or comparable listings.
The API is served under /api/v1. Set a base URL for the environment you have been authorized to use, then append the operation path shown below.
Current deployment status: the public API is not enabled on the production website yet. Production API routes deliberately return 404. The current staging preview at https://rentmaxdev.vercel.app is protected by Vercel deployment authentication and returns 401 without that access. Use staging only with authorized deployment access; do not send production traffic until the production API is announced as enabled.
For an authorized staging integration, set the base URL to the preview host provided for your deployment. Do not include /api/v1 in the variable; the examples append that path.
export RENTMAX_AI_API_BASE_URL="https://your-authorized-preview-host"
export RENTMAX_AI_API_KEY="rmai_..."
The preview host may require Vercel deployment authentication in addition to the RentMax AI API key. In Windows PowerShell, use $env:RENTMAX_AI_API_BASE_URL, $env:RENTMAX_AI_API_KEY, and curl.exe.
Create a key, add API credits, send a request from your server, and inspect the response.
RENTMAX_AI_API_KEY. Never put it in browser code, a mobile app, a public repository, or client-visible logs.RENTMAX_AI_API_BASE_URL to the authorized API host for your environment, as described above.Idempotency-Key for each new operation. It is optional, but strongly recommended so you can safely retry after a timeout. Reuse it only for the same operation and exact same request body.curl "$RENTMAX_AI_API_BASE_URL/api/v1/analyze" \
-H "Authorization: Bearer $RENTMAX_AI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: property-123-run-001" \
-d '{"address":"123 Main St, Austin, TX 78701","values":{"purchasePrice":350000,"targetRent":2400},"sections":["dealSummary","keyMetrics","risks"]}'
The address is illustrative. Use a real U.S. street address for a live property lookup. The supplied rent and purchase price act as underwriting overrides.
Billing: each new operation that completes successfully costs one prepaid credit; a successful idempotency replay is not charged again. Validation errors detected before credit reservation are not charged. If a reserved operation fails, the API attempts to refund it; if it cannot confirm the refund, it returns API_CREDIT_STATUS_UNKNOWN with a request ID so you can contact support. There is no free API trial.
Choose the smallest workflow that answers your question. Each endpoint call is a separate operation.
Use /analyze to combine a property lookup, rent estimate, financial metrics, and selected AI report sections. Supply your target rent or purchase price to override an estimate.
Use /rent-estimate when you need a normalized property and rent estimate with its confidence, sources, and warnings, without generating an underwriting report.
Use /underwrite when you already know the rent and purchase price. Send a new request for each financing or expense scenario you want to compare.
Use /report to pair deterministic metrics with an AI-assisted explanation, without looking up an address. Select only the report sections your workflow needs.
Your server can queue one /analyze request per listing, store each request ID with your own record, and present results for review. There is no batch endpoint; observe the rate limit when scheduling calls.
A multi-step flow uses one credit per completed step. For example, calling rent estimate, underwriting, and report separately costs three credits. A single /analyze call costs one.
| POST endpoint | Use it when… | Required JSON | What you get |
|---|---|---|---|
/api/v1/analyze | You want a property lookup and complete analysis together. | address; optional values, sections | Normalized property and rent estimate, underwriting metrics, selected AI report sections |
/api/v1/rent-estimate | You only need the property and rent estimate. | address | Property and rent estimate, confidence, sources, warnings |
/api/v1/underwrite | You already have the numbers and want calculated metrics. | values | Reviewed inputs and deterministic financial metrics |
/api/v1/report | You have the numbers and also want an AI-assisted explanation. | values; optional sections | Underwriting metrics and selected AI report sections |
Every operation is an HTTPS POST with an application/json object body of at most 5,000 bytes. Only the top-level fields shown in the table are accepted; extra fields are rejected. address must be a complete, supported U.S. street address between 10 and 240 characters.
underwrite and report require positive values.targetRent and values.purchasePrice. analyze always requires an address. It can fill either financial value from the property lookup, and positive values you provide override the lookup; the completed analysis still needs both values. sections is accepted only by analyze and report.
For /underwrite or /report, put the assumptions inside a values object. The example below calculates metrics from supplied numbers without a street address.
curl "$RENTMAX_AI_API_BASE_URL/api/v1/underwrite" \
-H "Authorization: Bearer $RENTMAX_AI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: scenario-austin-001" \
-d '{"values":{"targetRent":2400,"purchasePrice":350000,"propertyTaxAnnual":4200,"insurance":160,"vacancyRatePct":5,"downPct":20,"ratePct":6.5,"termYears":30,"useLoan":true}}'
curl "$RENTMAX_AI_API_BASE_URL/api/v1/rent-estimate" \
-H "Authorization: Bearer $RENTMAX_AI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: rent-austin-001" \
-d '{"address":"123 Main St, Austin, TX 78701"}'
curl "$RENTMAX_AI_API_BASE_URL/api/v1/report" \
-H "Authorization: Bearer $RENTMAX_AI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: report-austin-001" \
-d '{"values":{"targetRent":2400,"purchasePrice":350000},"sections":["dealSummary","keyMetrics","risks"]}'
Send values as an object. Money values are JSON numbers in U.S. dollars; percentages use percentage points, so send 6.5 for 6.5%. Each numeric field has an inclusive range below. Unknown fields, strings in place of numbers, non-finite values, and text instructions are rejected. useLoan must be a JSON boolean.
| Field | Type and valid range | Default or requirement | Meaning |
|---|---|---|---|
targetRent | Number, 0–1,000,000 | Estimate or required | Monthly rent in USD. Must be positive when used for underwriting. |
purchasePrice | Number, 0–100,000,000 | Estimate or required | Purchase price in USD. Must be positive when used for underwriting. |
vacancyRatePct | Number, 0–100 | 0 | Vacancy allowance as a percentage of monthly rent. |
mgmtFeePct | Number, 0–100 | 0 | Management fee as a percentage of monthly rent. |
propertyTaxAnnual | Number, 0–10,000,000 | 0 | Annual property tax in USD. |
insurance | Number, 0–1,000,000 | 0 | Monthly insurance cost in USD. |
hoa | Number, 0–1,000,000 | 0 | Monthly HOA cost in USD. |
maintenance | Number, 0–1,000,000 | 0 | Monthly maintenance cost in USD. |
otherMonthlyCosts | Number, 0–1,000,000 | Omitted | Other monthly costs in USD. If supplied, automatic additions for capexAnnual and PMI are not added. |
capexAnnual | Number, 0–10,000,000 | 0 | Annual capital expenditure in USD. Converted to a monthly cost only when otherMonthlyCosts is omitted. |
mortgagePI | Number, 0–1,000,000 | 0 | Manual monthly principal-and-interest payment in USD. Used when loan payment calculation is disabled or unavailable; otherwise the calculated payment is used. |
downPct | Number, 0–100 | 20 | Down payment as a percentage of purchase price. |
ratePct | Number, 0–30 | 6.5 | Annual loan interest rate in percentage points. |
termYears | Number, 0–50 | 30 | Loan term in years. |
closingCostPct | Number, 0–30 | 0 | Closing costs as a percentage of purchase price. |
pmiAnnualPct | Number, 0–10 | 0 | Annual PMI rate in percentage points. It is estimated when a calculated loan has less than 20% down and otherMonthlyCosts is omitted. |
useLoan | Boolean | true | Calculate principal and interest from purchase price, down payment, rate, and term. |
For underwrite and report, targetRent and purchasePrice are required in values. For analyze, property estimates supply them when available; include positive overrides for any missing or changed value. If useLoan is true and the loan inputs are usable, mortgagePI is ignored. All defaults are assumptions, not verified property facts. Enter realistic taxes, insurance, HOA, maintenance, vacancy, and financing details.
For analyze and report, omit sections to request all supported report sections. To request a smaller report, send a non-empty array of unique supported names. Arbitrary prompts and unsupported names are rejected.
{"values":{"targetRent":2400,"purchasePrice":350000},"sections":["dealSummary","keyMetrics","risks"]}
Supported sections: dealSummary, keyMetrics, strengths, risks, areaInsights, nextSteps, and assumptions.
Successful operations return HTTP 200 and JSON. Every success includes ok: true, requestId, creditCost: 1, and creditsRemaining. The request ID is also returned in the X-Request-Id header. A successful replay additionally includes replayed: true.
| Operation | Result fields |
|---|---|
rent-estimate | property, rentEstimate, sources, warnings, generatedAt |
underwrite | inputs, metrics |
report | inputs, metrics, analysis |
analyze | Property and rent-estimate fields, plus inputs, metrics, and analysis |
{
"ok": true,
"requestId": "server-generated-request-id",
"property": {
"matchedAddress": "123 Main St, Austin, TX 78701",
"beds": 3,
"baths": 2,
"sqft": 1500,
"price": 350000
},
"rentEstimate": {
"monthly": 2400,
"low": 2200,
"high": 2600,
"confidence": "medium",
"comparableSignals": 4
},
"sources": {
"propertyData": "Property data source",
"rentEstimate": "Rent estimate source"
},
"warnings": [],
"generatedAt": "2026-10-06T18:00:00.000Z",
"creditCost": 1,
"creditsRemaining": 24
}
Numeric property details and estimate bounds can be null when a source does not provide them; matchedAddress is a string. Each warning is an object with a code and readable message. The API returns normalized fields, not raw provider records or comparable listings.
underwrite, report, and analyze include a metrics object calculated from the normalized inputs. All money amounts are USD.
| Fields | Meaning |
|---|---|
rentLow, rentMid, rentHigh | Monthly rent band centered on the underwriting targetRent; it uses ±2.5% and is separate from the property-source range in rentEstimate. |
vacancy, mgmtFee, effectiveRentMid | Monthly USD deductions for vacancy and management, then rent after those deductions. |
taxMonthly, otherFixed, monthlyOperatingExpenses, monthlyDebtService, monthlyFixed, monthlyExpenses, monthlyPI, monthlyPMI, capexMonthly, otherMonthlyCosts | Monthly cost breakdown. monthlyFixed and monthlyExpenses include operating expenses and debt service. monthlyPMI is currently zero; an estimated PMI amount, when applicable, is included in otherMonthlyCosts. |
monthlyCashFlow, annualProfit, noi, annualDebt, cashInvested, opExAnnual | Monthly and annual cash-flow, net operating income, debt-service, cash-invested, and operating-expense totals in USD. NOI excludes debt service; annual profit includes it. Cash invested is the down payment plus closing costs. |
capRate, cashOnCash, expenseRatio, grossYield, vacPct, mgmtPct, downPct, ratePct, closingPct, pmiPct | Percentages in percentage points: for example, 6.5 means 6.5%. |
dscr, breakEvenRent, breakEvenOcc | Debt-service coverage ratio; monthly rent needed to break even; and break-even occupancy as a fraction from 0 to 1. |
purchasePrice, loanAmount, termYears, capexAnnual, hasLoanInputs | Normalized purchase, loan, term, and capex inputs, plus whether the calculator could derive a loan payment. |
projection | Ten annual rows with year, propertyValue, loanBalance, equity, and annualCashFlow. The illustration assumes 3% annual property appreciation and 2% annual rent and expense growth; these are not customized forecasts. |
Metrics that cannot be calculated because their denominator is zero are null. In the normalized inputs response, useLoan is represented as "1" or "0".
analysis contains only the requested supported keys. dealSummary and assumptions are strings; keyMetrics is an array of { "label": string, "value": string } objects; strengths, risks, areaInsights, and nextSteps are arrays of strings.
Errors returned by the RentMax AI API are JSON with ok: false, a readable error, stable machine-readable code, and requestId. Some validation errors also include detail.fields. A deployment-protection response can come from Vercel before the API runs and may use a different response body.
{"ok":false,"error":"A valid RentMax AI API key is required.","code":"INVALID_API_KEY","requestId":"server-generated-request-id"}
Send a unique Idempotency-Key with 8–128 letters, numbers, dots, colons, underscores, or hyphens. The header is optional, but if you omit it the server generates a random key that you may not know after a network timeout. For requests that reach credit reservation, the Idempotency-Key response header echoes the supplied or generated key. Retry an uncertain request with the same operation, exact same body, and same key. A completed retry returns the saved result with replayed: true and does not charge again. Reusing a key with a different request returns 409 IDEMPOTENCY_CONFLICT. If the first request is still running, the API returns 409 IDEMPOTENCY_IN_PROGRESS and Retry-After: 5; wait, then retry with the same key. A previously failed request returns 409 IDEMPOTENCY_FAILED; after checking its request ID and credit status, start a new attempt with a new key.
| Status | Meaning | What to do |
|---|---|---|
| 400 | Invalid JSON, missing or unexpected fields, invalid values/address/sections, or invalid idempotency key | Read code and optional detail.fields, correct the request, and use a new idempotency key if you changed the request. |
| 401 | From the API handler: missing, invalid, or revoked API key. From Vercel: deployment protection blocked the request before the API ran. | For an API-handler response, send Authorization: Bearer <key> from your server and check the stored secret. For a protected preview, use authorized deployment access. |
| 402 | Not enough API credits | Choose a credit pack in RentMax AI. |
| 403 | Request origin is not allowed | Call the API from your server; browser cross-origin requests are not enabled. |
| 404 | Unknown endpoint, unavailable property match, or public API disabled for this deployment. Production currently returns this status by design. | Check the URL, address, and environment. Use an authorized staging preview while production access is disabled. |
| 405 | Wrong HTTP method | Send POST. |
| 409 | Idempotency conflict, request still running, or an earlier attempt failed | Follow the matching code: keep the same key for an in-progress retry; use a new key for a new or previously failed attempt. |
| 413 | JSON body exceeds 5,000 bytes | Remove unused fields or shorten the address. |
| 415 | Request is not marked application/json | Set Content-Type: application/json. |
| 429 | Request rate limit reached | Honor Retry-After. The endpoint throttle allows up to 30 requests per minute per endpoint and source IP, and each API key is limited to 60 new operations per minute; whichever limit is reached first may return 429. |
| 503 | Property data, AI report, API service, or credit status is unavailable | Check code and requestId, then retry only when appropriate. For API_CREDIT_STATUS_UNKNOWN, contact support before starting a duplicate operation with a new key. |
If an AI report cannot be generated, the API returns AI_REPORT_UNAVAILABLE and refunds the reserved credit when that refund is confirmed. If no usable monthly rent estimate is available, rent-estimate returns RENT_ESTIMATE_UNAVAILABLE and refunds the credit when confirmed. A full analyze request can continue with a supplied positive targetRent; the response flags the missing estimate. If the API cannot confirm a refund, it returns API_CREDIT_STATUS_UNKNOWN. Keep the request ID and contact support before submitting a duplicate operation.
Reports are informational, not financial, legal, or tax advice. Verify property records and market assumptions independently.