Skip to main content
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?

Real-time rates

Scenarios use live rates and guidelines at the time of the API call, ensuring borrowers see accurate, current pricing.

No loan required

Show pricing options before creating a loan application, reducing friction in the borrower experience.

All products

Returns all eligible products and scenarios across all takeouts, not just a single product.

Optimized structures

Evaluates thousands of loan structure permutations to find the most optimal options for the borrower.

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

Basic usage

The scenarios endpoint requires minimal information to return comprehensive pricing options:
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 {
        product {
          name
          type
        }
        scenarios {
          rate
          apr
          monthlyPayment
          cashToClose
          loanAmount
          downPayment
          discountPoints
        }
      }
    }
  }
}

Required input fields

FieldTypeDescription
salesContractAmountNonNegativeInt!Purchase price of the property
outOfPocketMaxFloat!Maximum amount the borrower wants to spend out of pocket
monthlyIncomeFloat!Borrower’s total monthly income
monthlyDebtFloat!Borrower’s total monthly debt payments
fipsCountyCodeString!Five-digit FIPS county code (e.g., “06037” for Los Angeles County)
propertyUsageTypePropertyUsageType!PRIMARY_RESIDENCE, SECOND_HOME, or INVESTMENT
neighborhoodHousingTypeNeighborhoodHousingType!Property type (e.g., SINGLE_FAMILY, CONDOMINIUM)
isFirstTimeHomeBuyerBoolean!Whether the borrower is a first-time homebuyer

Optional input fields

FieldTypeDefaultDescription
qualifyingFicoScoreIntnullFICO score for rate qualification (if not provided, scenarios will show rates across score ranges)
loanTermYearsFloat!30Loan term in years
rateLockDaysFloat!30Number of days to lock the rate
concessionsNonNegativeInt!0Seller concessions in dollars
isBorrowerSelfEmployedBoolean!falseWhether the borrower is self-employed
objectiveIntentPricingObjectiveIntentMIN_PITIAOptimization 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:
1

Get traditional scenarios

Use purchasePricingNoRestructure with a specific down payment amount to see scenarios with unbounded cash to close:
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 {
        scenarios {
          rate
          apr
          cashToClose
          monthlyPayment
        }
      }
    }
  }
}
2

Extract cash to close

From the traditional scenario, note the cashToClose value for a specific rate the borrower likes.
3

Run optimized scenarios

Use purchasePricing with outOfPocketMax set to the cash to close from step 2:
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 {
        scenarios {
          rate
          apr
          cashToClose
          monthlyPayment
          loanAmount
          downPayment
        }
      }
    }
  }
}
4

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 (not necessarily 3%, 20%, etc.) - Better overall terms for the borrower

Understanding the response

The scenarios endpoint returns a structured response with products and their eligible scenarios:
{
  "data": {
    "scenario": {
      "purchasePricing": {
        "products": [
          {
            "product": {
              "name": "Conventional 30-Year Fixed",
              "type": "CONVENTIONAL"
            },
            "scenarios": [
              {
                "rate": 6.5,
                "apr": 6.713,
                "monthlyPayment": 2527.32,
                "cashToClose": 102500,
                "loanAmount": 397500,
                "downPayment": 102500,
                "discountPoints": 0.5
              }
            ]
          }
        ]
      }
    }
  }
}

Response fields

FieldDescription
rateInterest rate for this scenario
aprAnnual Percentage Rate (APR) (includes fees)
monthlyPaymentPrincipal, interest, taxes, and insurance (PITI)
cashToCloseTotal amount borrower needs at closing
loanAmountLoan principal amount
downPaymentDown payment amount
discountPointsPoints paid to buy down the rate

Optimization objectives

The objectiveIntent parameter controls how scenarios are optimized:

MIN_OUT_OF_POCKET

Minimizes the total cash required at closing. Best for borrowers with limited funds.

MIN_PITIA

Minimizes the monthly payment (Principal, Interest, Taxes, Insurance) (PITI). Best for borrowers focused on monthly affordability.

MIN_DOWN_PAYMENT

Minimizes the down payment amount. Useful for borrowers who want to preserve cash.

Best practices

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.
  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:
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 {
            product {
              name
              type
            }
            scenarios {
              rate
              apr
              monthlyPayment
              cashToClose
              loanAmount
              downPayment
              discountPoints
            }
          }
        }
      }
    }
  `;

  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;
}