Skip to main content
The full rate sheet returns the complete set of pricing results across all products and structures for a loan. Unlike most optimal structure, which returns a single best structure (and is faster), the full rate sheet runs the optimizer across the entire rate stack so you can display every product, every structure, and—for structures that don’t qualify—the specific reasons they’re ineligible. Use this when you need a full comparison matrix, compliance or audit views, or when you need to explain to borrowers why certain options aren’t available.

When to use the full rate sheet

Full product matrix

Show rates and structures for every product (e.g., 30-year fixed, 15-year fixed, 7/1 ARM) in a single response, so you can build comparison tables or rate sheets without multiple API calls.

Eligible and ineligible structures

See which structures qualify and which don’t, with specific reasons (e.g., DTI, LTV, reserves, QM fee cap). Essential for transparency and compliance.

Custom comparison UI

Build your own comparison tables, rate cards, or “what if” views. You get the full data in one response and can filter, sort, or present it however your UX requires.

Explaining unavailability

When a product or structure isn’t offered, use the returned ineligibility or error details to explain to the borrower why (e.g., “This rate would exceed your maximum monthly payment” or “Reserves requirement not met”).
For a single best structure per objective, use most optimal structure instead.

Performance and response time

The full rate sheet is computationally heavy. The system solves for optimal structures across the entire rate stack—all products and multiple structure permutations per product—so response times are typically 10–20 seconds, and can be longer for complex loans or under heavy load.
Design your UI/UX around this latency. Do not treat this as a quick, inline request. Users will abandon the flow if they think the app is stuck.

UI/UX recommendations

  • Set expectations before the request — Tell the user that loading the full rate sheet may take 10–20 seconds (e.g., “Loading full rate comparison… this usually takes 10–20 seconds”).
  • Show a dedicated loading state — Use a clear loading indicator (spinner, skeleton, or progress message). Avoid leaving the screen static with no feedback. Consider a message like “Comparing rates across all products…” or “Building your rate sheet…”.
  • Don’t block critical actions — If possible, allow the user to navigate away or cancel. Avoid modal dialogs that prevent closing until the request completes, unless you explicitly require the user to wait (e.g., “You must stay on this page until the comparison is ready”).
  • Trigger intentionally — Call the full rate sheet when the user explicitly asks for a full comparison (e.g., “Compare all options” or “Show full rate sheet”), not on every page load or on subtle filter changes. This keeps usage predictable and avoids unnecessary long waits.
  • Avoid repeated calls — Once you have the full rate sheet, cache or reuse it until the user changes something that invalidates it (e.g., loan data, borrower preferences, or objective). Don’t refetch on every tab focus or minor UI interaction.
  • Handle errors and timeouts — Implement a reasonable timeout (e.g., 30–60 seconds) and show a clear error state with retry. If the backend returns an error or partial data, explain what went wrong and offer a retry or fallback (e.g., “Use most optimal structure” for a single result).
  • Progressive disclosure (optional) — If your product supports it, you can show a quick “best option” first (e.g., via most optimal structure) and then load the full rate sheet in the background or on a separate “See all options” view, so users with limited patience still get value quickly.

Endpoint and request

Use the pricing.productPricing query for an existing loan. You must supply the loan ID and can optionally set the optimization objective and overrides.
ArgumentRequiredDescription
loanIdYesThe loan for which to compute the full rate sheet.
objectiveIntentNoOptimization goal; see Overview – Optimization objectives.
overridesNoOptional overrides for the loan application for this pricing run (experimental).
The response is synchronous (one request, no job ID or polling). See Performance and response time for timing expectations.

Example query

Use the fragment spreads below to handle eligible vs ineligible products and the rateStack union types. See Overview – Pricing response types for type definitions.
query FullRateSheet($loanId: ID!, $objectiveIntent: PricingObjectiveIntent) {
  pricing {
    productPricing(loanId: $loanId, objectiveIntent: $objectiveIntent) {
      products {
        ... on EligibleProductPricing {
          product { id description type }
          term
          lock
          rateStack {
            ... on EligibleProductStructure {
              id
              rate
              apr
              monthlyPayment
              closingCosts
              downPaymentAmount
              ltv
              dti
              pitia { principalAndInterest taxes homeownersInsurance mortgageInsurance floodInsurance hoaDues }
              product { id description type }
            }
            ... on IneligibleProductStructure {
              rate
              apr
              monthlyPayment
              ltv
              dti
              ineligibilityDetails {
                ... on DebtToIncomeViolation { __typename }
                ... on LoanToValueViolation { __typename }
                ... on QmFeeCapViolation { __typename }
                ... on ReservesNotMetViolation { __typename }
              }
              product { id description type }
            }
            ... on StructuringError {
              rate
              product { id description type }
              unsatisfiabilityDetails {
                ... on GuidelineViolation { __typename }
                ... on OptimizerUnsatisfied { __typename }
              }
            }
          }
        }
        ... on IneligibleProductPricing {
          product { id description type }
          term
          details { __typename }
        }
      }
      userErrors { message code }
    }
  }
}
Always check userErrors before relying on products. If there are user errors, the request may have failed validation or the loan may be in an invalid state for pricing. For type definitions and response structure, see Overview – Pricing response types.
  • Most optimal structure — Get the single best structure for your objective (and optional per-product breakdown). Use this when you don’t need the full rate stack; it’s faster and better suited for “show me the best option” flows.
  • Fixed loan structures — Get a fixed structure (e.g. 90% LTV) using MIN_DOWN_PAYMENT with maxLTV.
  • Pricing optimizations (Overview) — Optimization objectives, constraints, and pricing response types.