> ## 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.

# Pricing scenarios

> Show borrowers real-time pricing scenarios before creating a loan application. This stateless endpoint evaluates thousands of loan structures against live rates and guidelines.

The scenarios endpoint is a powerful, stateless API that enables you to show borrowers real-time pricing options before they even create a loan application. Unlike traditional mortgage calculators that use static rates or lack guideline integration, Pylon's scenarios endpoint evaluates loan structures against live rates and guidelines at runtime.

## Why use scenarios?

<CardGroup cols={2}>
  <Card title="Real-time rates" icon="bolt">
    Scenarios use live rates and guidelines at the time of the API call,
    ensuring borrowers see accurate, current pricing.
  </Card>

  <Card title="No loan required" icon="file-x">
    Show pricing options before creating a loan application, reducing friction
    in the borrower experience.
  </Card>

  <Card title="All products" icon="grid">
    Returns all eligible products and scenarios across all takeouts, not just a
    single product.
  </Card>

  <Card title="Optimized structures" icon="sparkles">
    Evaluates thousands of loan structure permutations to find the most optimal
    options for the borrower.
  </Card>
</CardGroup>

## When to use scenarios

Use the scenarios endpoint when:

* **Borrower knows their out-of-pocket budget**: If the borrower knows how much they want to spend out of pocket for the entire transaction, use the optimized `purchasePricing` endpoint.
* **Comparing traditional vs. optimized structures**: Show borrowers how optimized structures compare to traditional down payment amounts (3%, 20%, etc.).

<Warning>
  Always use the optimized `purchasePricing` endpoint for production
  applications. The `purchasePricingNoRestructure` endpoint is only recommended
  for comparison purposes to demonstrate the value of optimized structures.
</Warning>

## Basic usage

The scenarios endpoint requires minimal information to return comprehensive pricing options:

```graphql theme={null}
query {
  scenario {
    purchasePricing(
      input: {
        salesContractAmount: 500000
        outOfPocketMax: 100000
        monthlyIncome: 10000
        monthlyDebt: 2000
        qualifyingFicoScore: 750
        fipsCountyCode: "06037"
        propertyUsageType: PRIMARY_RESIDENCE
        neighborhoodHousingType: SINGLE_FAMILY
        isFirstTimeHomeBuyer: true
        isBorrowerSelfEmployed: false
        loanTermYears: 30
        rateLockDays: 30
        concessions: 0
        objectiveIntent: MIN_OUT_OF_POCKET
      }
    ) {
      products {
        ... on EligibleProductPricing {
          product {
            id
            description
            type
          }
          rateStack {
            ... on EligibleProductStructure {
              rate
              apr
              monthlyPayment
              cashFromToBorrower
              principal
              downPaymentAmount
              totalPoints
            }
          }
        }
      }
      userErrors {
        message
        code
      }
    }
  }
}
```

### Required input fields

| Field                     | Type                       | Description                                                        |
| ------------------------- | -------------------------- | ------------------------------------------------------------------ |
| `salesContractAmount`     | `NonNegativeInt!`          | Purchase price of the property                                     |
| `outOfPocketMax`          | `Float!`                   | Maximum amount the borrower wants to spend out of pocket           |
| `monthlyIncome`           | `Float!`                   | Borrower's total monthly income                                    |
| `monthlyDebt`             | `Float!`                   | Borrower's total monthly debt payments                             |
| `fipsCountyCode`          | `String!`                  | Five-digit FIPS county code (e.g., "06037" for Los Angeles County) |
| `propertyUsageType`       | `PropertyUsageType!`       | `PRIMARY_RESIDENCE`, `SECOND_HOME`, or `INVESTMENT`                |
| `neighborhoodHousingType` | `NeighborhoodHousingType!` | Property type (e.g., `SINGLE_FAMILY`, `CONDOMINIUM`)               |
| `isFirstTimeHomeBuyer`    | `Boolean!`                 | Whether the borrower is a first-time homebuyer                     |

### Optional input fields

| Field                    | Type                     | Default     | Description                                                                                        |
| ------------------------ | ------------------------ | ----------- | -------------------------------------------------------------------------------------------------- |
| `qualifyingFicoScore`    | `Int`                    | `null`      | FICO score for rate qualification (if not provided, scenarios will show rates across score ranges) |
| `loanTermYears`          | `Float!`                 | `30`        | Loan term in years                                                                                 |
| `rateLockDays`           | `Float!`                 | `30`        | Number of days to lock the rate                                                                    |
| `concessions`            | `NonNegativeInt!`        | `0`         | Seller concessions in dollars                                                                      |
| `isBorrowerSelfEmployed` | `Boolean!`               | `false`     | Whether the borrower is self-employed                                                              |
| `objectiveIntent`        | `PricingObjectiveIntent` | `MIN_PITIA` | Optimization objective: `MIN_OUT_OF_POCKET`, `MIN_PITIA`, or `MIN_DOWN_PAYMENT`                    |

## Comparing traditional vs. optimized structures

Some borrowers may be familiar with traditional mortgage structures (3% down, 20% down to avoid PMI, etc.). You can demonstrate the value of optimized structures by comparing them:

<Steps>
  <Step title="Get traditional scenarios">
    Use `purchasePricingNoRestructure` with a specific down payment amount to
    see scenarios with unbounded cash to close:

    ```graphql theme={null}
    query {
      scenario {
        purchasePricingNoRestructure(input: {
          salesContractAmount: 500000
          loanAmount: 400000
          downPayment: 100000
          monthlyIncome: 10000
          monthlyDebt: 2000
          qualifyingFicoScore: 750
          fipsCountyCode: "06037"
          propertyUsageType: PRIMARY_RESIDENCE
          neighborhoodHousingType: SINGLE_FAMILY
          isFirstTimeHomeBuyer: true
          isBorrowerSelfEmployed: false
        }) {
          products {
            ... on EligibleProductPricing {
              rateStack {
                ... on EligibleProductStructure {
                  rate
                  apr
                  cashFromToBorrower
                  monthlyPayment
                }
              }
            }
          }
          userErrors {
            message
            code
          }
        }
      }
    }
    ```
  </Step>

  <Step title="Extract cash to close">
    From the traditional scenario, note the `cashToClose` value for a specific
    rate the borrower likes.
  </Step>

  <Step title="Run optimized scenarios">
    Use `purchasePricing` with `outOfPocketMax` set to the cash to close from
    step 2:

    ```graphql theme={null}
    query {
      scenario {
        purchasePricing(input: {
          salesContractAmount: 500000
          outOfPocketMax: 105000  # From step 2
          monthlyIncome: 10000
          monthlyDebt: 2000
          qualifyingFicoScore: 750
          fipsCountyCode: "06037"
          propertyUsageType: PRIMARY_RESIDENCE
          neighborhoodHousingType: SINGLE_FAMILY
          isFirstTimeHomeBuyer: true
          objectiveIntent: MIN_OUT_OF_POCKET
        }) {
          products {
            ... on EligibleProductPricing {
              rateStack {
                ... on EligibleProductStructure {
                  rate
                  apr
                  cashFromToBorrower
                  monthlyPayment
                  principal
                  downPaymentAmount
                }
              }
            }
          }
          userErrors {
            message
            code
          }
        }
      }
    }
    ```
  </Step>

  <Step title="Compare results">
    Compare the cost for the same rate between traditional and optimized
    structures. The optimized structure often provides: - Lower total cost for
    the same rate - Different [loan-to-value ratios](/entity-models/key-concepts/ltv) (not necessarily 3%, 20%,
    etc.) - Better overall terms for the borrower
  </Step>
</Steps>

## Understanding the response

The scenarios endpoint returns a structured response with products and their eligible scenarios:

```json theme={null}
{
  "data": {
    "scenario": {
      "purchasePricing": {
        "products": [
          {
            "product": {
              "id": "prod_conforming_30yr_fixed",
              "description": "Conforming 30-Year Fixed",
              "type": "Conforming"
            },
            "rateStack": [
              {
                "rate": 6.5,
                "apr": 6.713,
                "monthlyPayment": 2527.32,
                "cashFromToBorrower": 102500,
                "principal": 397500,
                "downPaymentAmount": 102500,
                "totalPoints": 0.5
              }
            ]
          }
        ],
        "userErrors": []
      }
    }
  }
}
```

### Response fields

Each `EligibleProductPricing` exposes a `rateStack` of `EligibleProductStructure` entries with the following fields:

| Field                | Description                                                                                             |
| -------------------- | ------------------------------------------------------------------------------------------------------- |
| `rate`               | Interest rate for this structure                                                                        |
| `apr`                | [Annual Percentage Rate (APR)](/entity-models/key-concepts/apr) (includes fees)                         |
| `monthlyPayment`     | Principal, interest, taxes, insurance, and association fees ([PITIA](/entity-models/key-concepts/piti)) |
| `cashFromToBorrower` | Net change in cash from/to the borrower at closing                                                      |
| `principal`          | Loan principal amount                                                                                   |
| `downPaymentAmount`  | Down payment amount                                                                                     |
| `totalPoints`        | Total [points](/entity-models/key-concepts/points-vs-rate) after adjustments for this rate              |

## Optimization objectives

The `objectiveIntent` parameter controls how scenarios are optimized:

<CardGroup cols={3}>
  <Card title="MIN_OUT_OF_POCKET" icon="dollar-sign">
    Minimizes the total cash required at closing. Best for borrowers with
    limited funds.
  </Card>

  <Card title="MIN_PITIA" icon="calendar">
    Minimizes the monthly payment (Principal, Interest, Taxes, Insurance, Association) ([PITIA](/entity-models/key-concepts/piti)). Best
    for borrowers focused on monthly affordability.
  </Card>

  <Card title="MIN_DOWN_PAYMENT" icon="arrow-down">
    Middle ground between MIN\_OUT\_OF\_POCKET and MIN\_PITIA: buys down the rate as
    much as possible given available cash to close but does not exhaust
    available assets. With maxLTV, yields [fixed structures](/guides/getting-started/pricing-optimizations/fixed-loan-structures) (e.g. 90% LTV).
  </Card>
</CardGroup>

## Best practices

<Note>
  **Always use optimized scenarios**: For production applications, always use
  the `purchasePricing` endpoint with `outOfPocketMax` rather than
  `purchasePricingNoRestructure`. The optimized endpoint evaluates thousands of
  structure permutations to find the best options for borrowers.
</Note>

1. **Use borrower's actual budget**: When the borrower knows their out-of-pocket budget, use `outOfPocketMax` with the optimized endpoint.

2. **Show multiple options**: Display scenarios across different rates and products to give borrowers choice.

3. **Explain the value**: Help borrowers understand that optimized structures may differ from traditional down payment percentages but often provide better terms.

4. **Handle edge cases**: If no scenarios are returned, the borrower may not qualify for any products with the given parameters. Consider adjusting inputs or explaining qualification requirements.

5. **Cache appropriately**: While scenarios use live rates, you may want to cache results for a short period (e.g., 5-15 minutes) to reduce API calls during active borrower sessions.

## Example: complete integration

Here's a complete example of fetching and displaying scenarios:

```typescript theme={null}
interface ScenarioInput {
  salesContractAmount: number;
  outOfPocketMax: number;
  monthlyIncome: number;
  monthlyDebt: number;
  qualifyingFicoScore?: number;
  fipsCountyCode: string;
  propertyUsageType: "PRIMARY_RESIDENCE" | "SECOND_HOME" | "INVESTMENT";
  neighborhoodHousingType: string;
  isFirstTimeHomeBuyer: boolean;
}

async function getPricingScenarios(input: ScenarioInput) {
  const query = `
    query GetPricingScenarios($input: PurchasePricingInput!) {
      scenario {
        purchasePricing(input: $input) {
          products {
            ... on EligibleProductPricing {
              product {
                id
                description
                type
              }
              rateStack {
                ... on EligibleProductStructure {
                  rate
                  apr
                  monthlyPayment
                  cashFromToBorrower
                  principal
                  downPaymentAmount
                  totalPoints
                }
              }
            }
          }
          userErrors {
            message
            code
          }
        }
      }
    }
  `;

  const response = await fetch("https://pylon.mortgage/graphql", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${accessToken}`,
    },
    body: JSON.stringify({
      query,
      variables: {
        input: {
          ...input,
          loanTermYears: 30,
          rateLockDays: 30,
          concessions: 0,
          isBorrowerSelfEmployed: false,
          objectiveIntent: "MIN_OUT_OF_POCKET",
        },
      },
    }),
  });

  const { data } = await response.json();
  return data.scenario.purchasePricing;
}
```

## Related resources

* [Pricing optimizations](/guides/getting-started/pricing-optimizations/overview) - Learn how Pylon's pricing differs from traditional PPE/LOS systems
* [Marketing rates](/recipes/marketing-rates) - Display competitive rates on your website
* [Prequalification](/recipes/prequalification) - Determine maximum affordability before creating a loan
