MIN_DOWN_PAYMENT as the optimization objective and set maxLTV in your pricing constraints to the LTV you want. The result will have that exact LTV and the matching down payment.
You can do this with either most optimal structure (single best structure) or full rate sheet optimizations (full rate stack). Same objective and constraint in both cases.
How to request it
Most optimal structure: CallcalculateOptimalStructure with objectiveIntent: "MIN_DOWN_PAYMENT" and pricingConstraints.maxLtv set to your target (e.g. 0.90 for 90% LTV). Poll for the job, then read the result.
Full rate sheet: Call productPricing with objectiveIntent: "MIN_DOWN_PAYMENT" and ensure the loan has a maxLTV constraint (e.g. via borrower preferences or your API’s equivalent). You get the full rate stack with that fixed LTV applied. See Full rate sheet optimizations for the query and response shape.
Example (most optimal structure):
maxLtv: 0.90, the returned structure will be 90% LTV and 10% down. Other common values: 0.80 (80% LTV, 20% down), 0.95 (95% LTV, 5% down), 0.97 (97% LTV, 3% down).
Where maxLTV comes from: In some flows you pass maxLtv in the request (e.g. pricingConstraints.maxLtv in the most-optimal-structure mutation). In others it is not in the request—it’s already set on the loan (e.g. borrower preferences) and the pricing call uses that. Check the API for the flow you’re using.
Why the structure is fixed
The optimizer minimizes the down payment (MIN_DOWN_PAYMENT) and is not allowed to exceed your maxLTV. So it lowers the down payment and increases the loan amount until LTV equals maxLTV, then stops. The solution is always at that boundary:
- LTV =
maxLTV - Down payment = Purchase price × (1 −
maxLTV)
maxLTV (for example because of program limits, DTI, reserves, or other guidelines), it returns the closest possible LTV that achieves a solve—so you may get a lower LTV (higher down payment) than you asked for, but you still get a valid structure.