# The maximum allowable offer

import { Card } from "zudoku/ui/Card";
import { Code2, SlidersHorizontal, CircleAlert } from "zudoku/icons";

Read the maximum allowable offer and its costs to decide whether the returned amount is usable.

**This is the investor's ceiling — your offer to the seller is this minus your fee.**

## Read the ceiling and its flag

`max_allowable_offer` is the highest purchase price at which a cash flip buyer on standard financing clears the target margin.
It reverses a flip profit calculation; it does not predict what the property will trade at.

`max_allowable_offer.amount` is in whole dollars, rounded to the nearest thousand.
`max_allowable_offer.clamped` is `true` when no purchase price clears the target margin at this repair budget.
When it is `true`, the amount is **not an offer** and must not be presented as one.

The flag uses the raw calculation before rounding.
A small negative result therefore stays clamped instead of becoming a usable zero-dollar offer.
Read the flag before acting on the amount.

Both members are present whenever the offer is a priced object.
On a priced answer, the object is absent whenever `comp_band`, the range implied by comparable sales, is absent.
A partial answer instead carries `max_allowable_offer: null`.

## Read the cost stack

`cost_stack` accompanies a priced `max_allowable_offer` object.
A partial answer has a null offer and no cost stack.
Its amounts are whole dollars; its holding period is days.

| Member | Meaning |
| --- | --- |
| `cost_stack.down_payment` | Cash the buyer puts into the purchase. |
| `cost_stack.loan` | Borrowed amount: the maximum allowable offer less the down payment. |
| `cost_stack.interest` | Interest on the loan over the holding period. |
| `cost_stack.points` | Lending points charged on the loan. |
| `cost_stack.hold_days` | Holding period; a larger repair budget means a longer hold. |
| `cost_stack.closing_costs` | Costs charged on both purchase and resale. |
| `cost_stack.target_profit` | Target margin multiplied by the unrounded repaired value. |

The response's `target_margin` states the fraction used.
Multiplying the published `rehab_adjusted_arv` by it can differ from `cost_stack.target_profit` because the published repaired value is rounded.
The offer uses the unrounded value.

## Check the arithmetic

**The down payment plus the loan equals the maximum allowable offer exactly.**
That identity holds even when the offer is clamped.

When `max_allowable_offer.clamped` is `false`, add the down payment, loan, repair budget, interest, points, closing costs and target profit.
They reconcile to `rehab_adjusted_arv`, subject to rounding.
This whole-stack comparison is different from the exact down-payment-plus-loan identity.

The offer and repaired value round to the nearest thousand; other amounts round to whole dollars.
The reconciliation gap stays a little over a thousand dollars across the service's repair brackets.
Very large repair budgets can increase it because longer holds put more financing cost on each rounded dollar.

When the flag is `true`, the published price is a floor, not a solved price.
The stack still describes that price, but it does not reconcile to the repaired value.
The difference can be large.

## Understand the assumptions

Down payment, interest, points, closing costs, holding period and margin are policy figures chosen by judgment and intended to be tuned.
They are not fitted to a data set or quoted by a lender.
[Accuracy and limits](/scoring/accuracy-and-limits) separates checked arithmetic from market accuracy.

**`cost_stack.assumptions` — the figures the offer was solved with.**

On `POST /v1/predict`,
`cost_stack.assumptions` carries the figures used to compute the offer: `cost_stack.assumptions.down_fraction`, `cost_stack.assumptions.annual_interest_rate`, `cost_stack.assumptions.days_per_year`,
`cost_stack.assumptions.points_fraction`, `cost_stack.assumptions.closing_fraction`, `cost_stack.assumptions.closing_applies_to_purchase`, `cost_stack.assumptions.carry`,
`cost_stack.assumptions.hold_base_days`, `cost_stack.assumptions.hold_days_per_thousand_rehab`, `cost_stack.assumptions.rehab_lift_low_share`,
`cost_stack.assumptions.rehab_lift_high_share`, `cost_stack.assumptions.offer_rounding_increment` and `cost_stack.assumptions.arv_rounding_increment`.

The last two are separate publication increments; the cost stack uses the unrounded repaired value.
With those and `comp_band`, you can
recompute the offer for a different repair budget or margin yourself.

Batch answers do not
carry it.

## Next steps

<div className="docs-next-steps">

<Card className="docs-next-card"><a href="/scoring/score-a-property"><Code2 className="docs-next-icon" size={18} strokeWidth={1.5} aria-hidden="true" focusable="false" /><strong>Score a property</strong><span className="docs-next-description">Make the default call and read its answer.</span><span className="docs-next-arrow" aria-hidden="true">→</span></a></Card>

<Card className="docs-next-card"><a href="/scoring/your-own-numbers"><SlidersHorizontal className="docs-next-icon" size={18} strokeWidth={1.5} aria-hidden="true" focusable="false" /><strong>Use your own numbers</strong><span className="docs-next-description">Set your repair budget and margin.</span><span className="docs-next-arrow" aria-hidden="true">→</span></a></Card>

<Card className="docs-next-card"><a href="/scoring/accuracy-and-limits"><CircleAlert className="docs-next-icon" size={18} strokeWidth={1.5} aria-hidden="true" focusable="false" /><strong>Accuracy and limits</strong><span className="docs-next-description">Understand what has been verified.</span><span className="docs-next-arrow" aria-hidden="true">→</span></a></Card>

</div>
