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

# Marketing rates

> Display competitive mortgage rates on your website alongside APOR (Average Prime Offer Rate) to demonstrate your competitive advantage for creditworthy borrowers.

The marketing rates endpoint allows you to display real-time mortgage rates on your website or application. By showing your rates alongside the Average Prime Offer Rate (APOR), you can demonstrate that for creditworthy borrowers, your rates are materially more competitive than market averages.

## Why use marketing rates?

<CardGroup cols={2}>
  <Card title="Build trust" icon="shield-check">
    Show borrowers real rates upfront, not estimates or ranges, building
    confidence in your offerings.
  </Card>

  <Card title="Competitive positioning" icon="trending-up">
    Compare your rates against APOR to highlight your competitive advantage.
  </Card>

  <Card title="Lead generation" icon="users">
    Attract qualified borrowers by showcasing competitive rates before they
    apply.
  </Card>

  <Card title="Real-time accuracy" icon="clock">
    Rates update with market conditions, ensuring your displayed rates are
    current and accurate.
  </Card>
</CardGroup>

## Understanding APOR

The **Average Prime Offer Rate (APOR)** is a benchmark rate published by the Federal Reserve that represents the average rate offered to prime borrowers. By comparing your rates to APOR, you can:

* Demonstrate competitive pricing
* Show value to creditworthy borrowers
* Build trust through transparency
* Differentiate from competitors

<Info>
  APOR is updated weekly by the Federal Reserve. Pylon's marketing rates use
  live, real-time rates that may be more competitive than APOR for qualified
  borrowers.
</Info>

## Basic usage

The marketing rates endpoint is a public GraphQL query that doesn't require authentication, making it perfect for public-facing rate displays:

```graphql theme={null}
query {
  marketingRates {
    conforming(
      inputs: [
        {
          ltv: 0.8
          fipsCountyCode: "06037"
          loanAmount: 400000
          loanTermYears: 30
          qualifyingFicoScore: 750
          rateLockDays: 30
        }
      ]
    ) {
      rate
      apr
      discountPointsTotal
      discountPointsTotalAmount
    }
    warehousingCosts {
      products {
        product
        points
      }
    }
  }
}
```

### Required input fields

| Field            | Type              | Description                                                                                                       |
| ---------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------- |
| `ltv`            | `Float!`          | [Loan-to-value ratio](/entity-models/key-concepts/ltv) (e.g., 0.8 for 80% [LTV](/entity-models/key-concepts/ltv)) |
| `fipsCountyCode` | `String!`         | Five-digit FIPS county code for the property location                                                             |
| `loanAmount`     | `NonNegativeInt!` | Loan amount in dollars                                                                                            |

### Optional input fields

| Field                    | Type     | Default | Description                       |
| ------------------------ | -------- | ------- | --------------------------------- |
| `loanTermYears`          | `Float!` | `30`    | Loan term in years                |
| `qualifyingFicoScore`    | `Int`    | `null`  | FICO score for rate qualification |
| `rateLockDays`           | `Float!` | `30`    | Number of days to lock the rate   |
| `maxDiscountPointsTotal` | `Float`  | `0`     | Maximum discount points (up to 3) |

### Response

```json theme={null}
{
  "data": {
    "marketingRates": {
      "conforming": [
        {
          "rate": 6.5,
          "apr": 6.713,
          "discountPointsTotal": 0,
          "discountPointsTotalAmount": 0
        }
      ],
      "warehousingCosts": {
        "products": [
          {
            "product": "Conforming 30-Year Fixed",
            "points": 0.25
          }
        ]
      }
    }
  }
}
```

## Product types

Marketing rates are available for multiple product types:

### Conforming loans

Standard conforming loans eligible for Fannie Mae and Freddie Mac:

```graphql theme={null}
query {
  marketingRates {
    conforming(
      inputs: [
        {
          ltv: 0.8
          fipsCountyCode: "06037"
          loanAmount: 400000
          qualifyingFicoScore: 750
        }
      ]
    ) {
      rate
      apr
    }
  }
}
```

### Jumbo loans

Jumbo loans that exceed conforming loan limits:

```graphql theme={null}
query {
  marketingRates {
    jumbo(
      inputs: [
        {
          ltv: 0.75
          fipsCountyCode: "06037"
          loanAmount: 800000
          qualifyingFicoScore: 760
        }
      ]
    ) {
      rate
      apr
    }
  }
}
```

### FHA loans

FHA-insured loans:

```graphql theme={null}
query {
  marketingRates {
    fha(
      inputs: [
        {
          ltv: 0.965
          fipsCountyCode: "06037"
          loanAmount: 300000
          qualifyingFicoScore: 680
        }
      ]
    ) {
      rate
      apr
    }
  }
}
```

### Custom products

Query rates for custom product configurations:

```graphql theme={null}
query {
  marketingRates {
    custom(
      inputs: [
        {
          ltv: 0.8
          fipsCountyCode: "06037"
          loanAmount: 400000
          qualifyingFicoScore: 750
        }
      ]
    ) {
      rate
      apr
    }
  }
}
```

## Multiple scenarios

You can query rates for multiple scenarios in a single request:

```graphql theme={null}
query {
  marketingRates {
    conforming(
      inputs: [
        {
          ltv: 0.8
          fipsCountyCode: "06037"
          loanAmount: 400000
          qualifyingFicoScore: 750
        }
        {
          ltv: 0.9
          fipsCountyCode: "06037"
          loanAmount: 400000
          qualifyingFicoScore: 750
        }
        {
          ltv: 0.95
          fipsCountyCode: "06037"
          loanAmount: 400000
          qualifyingFicoScore: 750
        }
      ]
    ) {
      ltv
      rate
      apr
    }
  }
}
```

This is useful for displaying rate tables showing how rates vary by [LTV](/entity-models/key-concepts/ltv) or loan amount.

## Polling frequency

<Warning>
  **Update rates regularly**: Interest rates can change throughout the day,
  especially during market hours, news events, policy changes, and rate
  movements. Poll the marketing rates endpoint at least twice daily to keep
  displayed rates current.
</Warning>

Recommended polling strategy:

* **Minimum**: Twice daily (morning and afternoon)
* **Optimal**: Every 2-4 hours during market hours (9 AM - 4 PM ET)
* **Maximum**: Every 15-30 minutes (for high-traffic sites)

<Note>
  While rates can change frequently, avoid polling more than once every 15
  minutes to minimize API load. Cache results and update your display on a
  reasonable schedule.
</Note>

## Complete example

Here's a complete example of fetching and displaying marketing rates:

```typescript theme={null}
interface MarketingRateInput {
  ltv: number;
  fipsCountyCode: string;
  loanAmount: number;
  loanTermYears?: number;
  qualifyingFicoScore?: number;
  rateLockDays?: number;
  maxDiscountPointsTotal?: number;
}

async function getMarketingRates(inputs: MarketingRateInput[]) {
  const query = `
    query GetMarketingRates($inputs: [ConformingMarketingRateInput!]!) {
      marketingRates {
        conforming(inputs: $inputs) {
          rate
          apr
          discountPointsTotal
          discountPointsTotalAmount
        }
        warehousingCosts {
          products {
            product
            points
          }
        }
      }
    }
  `;

  const response = await fetch("https://pylon.mortgage/graphql", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query,
      variables: {
        inputs: inputs.map((input) => ({
          ...input,
          loanTermYears: input.loanTermYears || 30,
          rateLockDays: input.rateLockDays || 30,
          maxDiscountPointsTotal: input.maxDiscountPointsTotal || 0,
        })),
      },
    }),
  });

  const { data } = await response.json();
  return data.marketingRates;
}

// Example: Display rates for different LTV scenarios
async function displayRateTable() {
  const scenarios = [
    { ltv: 0.8, loanAmount: 400000, label: "20% Down" },
    { ltv: 0.9, loanAmount: 400000, label: "10% Down" },
    { ltv: 0.95, loanAmount: 400000, label: "5% Down" },
  ];

  const rates = await getMarketingRates(
    scenarios.map((s) => ({
      ltv: s.ltv,
      fipsCountyCode: "06037", // Los Angeles County
      loanAmount: s.loanAmount,
      qualifyingFicoScore: 750,
    }))
  );

  // Display rates in your UI
  rates.conforming.forEach((rate, index) => {
    console.log(`${scenarios[index].label}: ${rate.rate}% APR: ${rate.apr}%`);
  });
}
```

## Displaying rates with APOR

To demonstrate competitive advantage, fetch APOR data and compare it with your rates:

```typescript theme={null}
async function displayRatesWithAPOR() {
  // Fetch your rates
  const yourRates = await getMarketingRates([
    {
      ltv: 0.8,
      fipsCountyCode: "06037",
      loanAmount: 400000,
      qualifyingFicoScore: 750,
    },
  ]);

  // Fetch APOR (you'll need to integrate with Federal Reserve API or use a data provider)
  const apor = await fetchAPOR(); // Your APOR fetching function

  const yourRate = yourRates.conforming[0].rate;
  const savings = apor - yourRate;

  console.log(`Your Rate: ${yourRate}%`);
  console.log(`APOR: ${apor}%`);
  console.log(
    `Savings: ${savings}% (${savings * 4000} per year on a \$400k loan)`
  );
}
```

## Best practices

1. **Cache results**: Store fetched rates in cache and update on a schedule (e.g., every 2-4 hours) rather than fetching on every page load.

2. **Handle errors gracefully**: If the API is unavailable, show cached rates with a timestamp or a message indicating rates may be outdated.

3. **Show disclaimers**: Include appropriate disclaimers that rates are estimates and actual rates may vary based on complete application.

4. **Display qualifications**: Clearly indicate the credit score and other assumptions used (e.g., "Rates shown for 750 FICO score, 80% [LTV](/entity-models/key-concepts/ltv)").

5. **Update during market hours**: Prioritize rate updates during market hours (9 AM - 4 PM ET) when rates are most likely to change.

6. **Compare to APOR**: When possible, show APOR alongside your rates to demonstrate competitive advantage.

7. **Use appropriate scenarios**: Display rates for common scenarios (e.g., 20% down, 10% down) that match your target borrower profile.

## Error handling

Common scenarios and how to handle them:

| Scenario               | Handling                                                           |
| ---------------------- | ------------------------------------------------------------------ |
| No rate available      | Show "Rate unavailable" or use cached rate with disclaimer         |
| API timeout            | Fall back to cached rates                                          |
| Invalid county code    | Validate FIPS codes before making requests                         |
| Rate not found for LTV | Adjust LTV or show message that rate unavailable for that scenario |

## Related resources

* [Pricing scenarios](/recipes/scenarios) - Get detailed pricing for specific borrower scenarios
* [Prequalification](/recipes/prequalification) - Determine maximum affordability
* [FIPS County Codes](https://transition.fcc.gov/oet/info/maps/census/fips/fips.txt) - Look up county codes from the FCC
