Skip to main content
When you want the one best structure for a borrower’s objective - without building or scanning a full rate sheet - use calculate optimal structure. The API runs the optimizer and returns the best result (e.g., minimum PITIA or minimum down payment) across all products and structures. Optionally, use Product Breakdown to see the best structure per product for that same objective.

How it works

1

Submit the job

Call the calculateOptimalStructure mutation with the loan ID, objective, and optional constraints.
2

Poll for completion

Query optimalStructure(id) with the job ID until status indicates completion.
3

Use the result

Read result for the single best structure across all products. Use productBreakdown for the best structure per product.
For optimization objectives (MIN_PITIA, MIN_OUT_OF_POCKET, MIN_DOWN_PAYMENT) and pricing constraints, see Overview - Optimization objectives and Borrower preferences and pricing constraints.

Performance and response time

Most optimal structure is asynchronous: you submit the job, then poll until complete. It is much faster than the full rate sheet, which evaluates the entire rate stack across all products. Response times are typically about 3 seconds, compared to 10-20 seconds for the full rate sheet. Use most optimal structure when you only need the single best structure and want quicker response times.

UI/UX recommendations

  • Show a loading state - Display a loading indicator while the asynchronous job completes and you poll for the result. A short message like “Finding your best option…” is sufficient; 3 seconds usually doesn’t require the longer copy used for the full rate sheet.
  • Avoid repeated calls - Cache or reuse the result until the user or loan data changes (e.g. loan data, borrower preferences, or objective). Don’t refetch on every tab focus or minor UI interaction.

1. Start the calculation (mutation)

mutation calculateOptimalStructure($input: CalculateOptimalStructureInput!) {
  pricing {
    calculateOptimalStructure(input: $input) {
      job {
        id
        status
      }
    }
  }
}
Variables example:
{
  "input": {
    "loanId": "app_5ap9raB5XUhQZLLkpg31Ve",
    "objectiveIntent": "MIN_DOWN_PAYMENT",
    "pricingConstraints": {
      "maxLtv": 0.90
    }
  }
}
For fixed LTV structures (e.g. 90% LTV) using MIN_DOWN_PAYMENT and maxLtv, see Fixed loan structures.

2. Get the result (query)

Poll pricing.optimalStructure(id) with the job id until status is complete, then read result and optionally productBreakdown.
query getOptimalStructure($id: ID!) {
  pricing {
    optimalStructure(id: $id) {
      id
      status
      result {
        id
        apr
        rate
        closingCosts
        monthlyPayment
        downPaymentAmount
        principal
        cashFromToBorrower
        cashOutAmount
        cashOutType
        concessionPoints
        dti
        floodInsurance
        interest
        loanTermYears
        lock
        ltv
        mortgageInsurance
        totalCost
        totalPoints
        apor {
          rate
        }
        pitia {
          floodInsurance
          hoaDues
          homeownersInsurance
          mortgageInsurance
          principalAndInterest
          taxes
        }
        product {
          id
          description
          type
        }
      }
      productBreakdown {
        ... on EligibleProductStructure {
          rate
          apr
          monthlyPayment
          downPaymentAmount
          product { id description type }
        }
        ... on IneligibleProductStructure {
          rate
          product { id description type }
          ineligibilityDetails { __typename }
        }
        ... on StructuringError {
          rate
          product { id description type }
          unsatisfiabilityDetails { __typename }
        }
      }
    }
  }
}

Result vs Product Breakdown

FieldDescription
resultThe single best structure for the loan for your objective (e.g., the structure with MIN_PITIA across all products and structures). Use this when you only need “the answer.”
productBreakdownThe best structure per product for the same objective. Each item is a StructuringResult (eligible, ineligible, or error). See Overview - Pricing response types.
Polling: optimalStructure is a job. Poll on status (e.g. COMPLETED, FAILED) and only read result / productBreakdown when the job has finished.