> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pylon.mortgage/llms.txt
> Use this file to discover all available pages before exploring further.

# Full rate sheet optimizations

> Show the full rate stack across all products, including eligible structures and ineligible products and structures with their reasons. Includes performance expectations and UI/UX guidance.

The **full rate sheet** returns the complete set of pricing results across all products and structures for a loan. Unlike [most optimal structure](/guides/getting-started/pricing-optimizations/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

<CardGroup cols={2}>
  <Card title="Full product matrix" icon="grid">
    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.
  </Card>

  <Card title="Eligible and ineligible structures" icon="check-circle">
    See which structures qualify and which don’t, with specific reasons (e.g., [DTI](/entity-models/key-concepts/dti), [LTV](/entity-models/key-concepts/ltv), [reserves](/entity-models/key-concepts/reserves), [QM fee cap](/entity-models/key-concepts/qualified-mortgage)). Essential for transparency and compliance.
  </Card>

  <Card title="Custom comparison UI" icon="layout">
    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.
  </Card>

  <Card title="Explaining unavailability" icon="eye">
    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”).
  </Card>
</CardGroup>

For a single best structure per objective, use [most optimal structure](/guides/getting-started/pricing-optimizations/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.

<Warning>
  **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.
</Warning>

### 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](/guides/getting-started/pricing-optimizations/overview#borrower-preferences-and-pricing-constraints), 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.

| Argument          | Required | Description                                                                                                                                  |
| ----------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `loanId`          | Yes      | The loan for which to compute the full rate sheet.                                                                                           |
| `objectiveIntent` | No       | Optimization goal; see [Overview – Optimization objectives](/guides/getting-started/pricing-optimizations/overview#optimization-objectives). |
| `overrides`       | No       | Optional 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](#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](/guides/getting-started/pricing-optimizations/overview#pricing-response-types) for type definitions.

```graphql theme={null}
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](/guides/getting-started/pricing-optimizations/overview#pricing-response-types).

***

## Related

* [Most optimal structure](/guides/getting-started/pricing-optimizations/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](/guides/getting-started/pricing-optimizations/fixed-loan-structures) — Get a fixed structure (e.g. 90% LTV) using `MIN_DOWN_PAYMENT` with `maxLTV`.
* [Pricing optimizations (Overview)](/guides/getting-started/pricing-optimizations/overview) — Optimization objectives, constraints, and pricing response types.
