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

# Choosing an option in code

> Option ids are predictable, so a house rule like "25% down over 10 months" is a lookup. Here's the lookup that never misses.

Many agencies have a default: "we always offer 25% down over 10 months". You can encode that without any setting on our side, because option ids are deterministic:

```
opt_<down payment percent>_<term months>
```

`opt_25_10` is 25% down over 10 months, on every quote that offers it. The catch is in the last four words: **not every quote offers it.** This page explains why, and gives you a lookup that always lands on a sensible option.

## Why an exact id can be missing

### The down payments follow the minimum earned premium

Each quote offers five down payments. They start 10 points below the deal's **premium-weighted minimum earned rate**, never below 10%, and step up by 5 points:

```
floor = max(round(weighted minimum earned %) − 10, 10)
down payments = floor, floor + 5, floor + 10, floor + 15, floor + 20
```

The weighted rate is `totals.weighted_minimum_earned_rate` on the quote, weighted by each policy's premium. So the rungs move with the deal:

| Weighted minimum earned | Down payments offered | Has 25%? |
| - | - | - |
| 0% to 20% | 10, 15, 20, 25, 30 | Yes |
| 22% | 12, 17, 22, 27, 32 | No |
| 25% | 15, 20, 25, 30, 35 | Yes |
| 26% | 16, 21, 26, 31, 36 | No |
| 27% | 17, 22, 27, 32, 37 | No |
| 30% | 20, 25, 30, 35, 40 | Yes |
| 35% | 25, 30, 35, 40, 45 | Yes |
| 40% | 30, 35, 40, 45, 50 | No |

A 25% minimum earned, the most common case, does give you a 25% row. But an exact 25% rung exists only when the weighted minimum earned rounds to 20% or less, or to 25%, 30% or 35%. A deal whose weighted minimum earned comes to 27% has no 25% row at all.

### The terms follow the policy dates

The longest term always ends before the policies do. A 12-month policy typically gets terms of 6 to 11 months; a shorter policy gets fewer and shorter terms. A policy shorter than 3 months can't be financed at all.

### Some cells are dropped

An option whose APR would exceed the state's limit (17.9% in Texas) is left out, so the grid can be ragged: a term can exist at one down payment and be missing at another. An ineligible quote has no options at all, and neither does an eligible one where every option was dropped (see [eligible, but no options](/concepts/eligibility#eligible-but-no-options)). In both cases `options` is empty and `recommended_option_id` is `null`.

## The lookup

Try the exact id. If it's missing, take the same term at the nearest down payment **at or above** your target, so the client never puts down less than your rule intends. If that term isn't offered either, fall back to `recommended_option_id`.

<CodeGroup>
  ```javascript Node theme={null}
  /**
   * Pick the option closest to a house rule.
   * downPayment is a whole percent (25 means 25%).
   * Returns null only when the quote has no options (ineligible, or no option fits).
   */
  function chooseOption(quote, { downPayment, termMonths }) {
    const exact = quote.options.find((o) => o.id === `opt_${downPayment}_${termMonths}`)
    if (exact) return exact

    const sameTermAtOrAbove = quote.options
      .filter((o) => o.term_months === termMonths && Math.round(o.down_payment_rate * 100) >= downPayment)
      .sort((a, b) => a.down_payment_rate - b.down_payment_rate)
    if (sameTermAtOrAbove.length > 0) return sameTermAtOrAbove[0]

    return quote.options.find((o) => o.id === quote.recommended_option_id) ?? null
  }

  const option = chooseOption(quote, { downPayment: 25, termMonths: 10 })
  ```

  ```python Python theme={null}
  def choose_option(quote, down_payment, term_months):
      """Pick the option closest to a house rule.

      down_payment is a whole percent (25 means 25%).
      Returns None only when the quote has no options (ineligible, or no option fits).
      """
      options = quote["options"]
      exact = next((o for o in options if o["id"] == f"opt_{down_payment}_{term_months}"), None)
      if exact:
          return exact

      same_term_at_or_above = sorted(
          (o for o in options
           if o["term_months"] == term_months and round(o["down_payment_rate"] * 100) >= down_payment),
          key=lambda o: o["down_payment_rate"],
      )
      if same_term_at_or_above:
          return same_term_at_or_above[0]

      return next((o for o in options if o["id"] == quote["recommended_option_id"]), None)


  option = choose_option(quote, down_payment=25, term_months=10)
  ```
</CodeGroup>

Match on `term_months` and `down_payment_rate`, as above, rather than by taking an id apart. The id format is stable, but the fields are what we document as the values.

## A worked example

A single ocean marine policy with a 27% minimum earned, financed over its 12-month term (illustrative figures):

| | 6 mo | 7 mo | 8 mo | 9 mo | 10 mo | 11 mo |
| - | - | - | - | - | - | - |
| **17%** | `opt_17_6` | `opt_17_7` | `opt_17_8` | `opt_17_9` | `opt_17_10` | `opt_17_11` |
| **22%** | `opt_22_6` | `opt_22_7` | `opt_22_8` | `opt_22_9` | `opt_22_10` | `opt_22_11` |
| **27%** | `opt_27_6` | `opt_27_7` | `opt_27_8` | `opt_27_9` | **`opt_27_10`** | `opt_27_11` |
| **32%** | `opt_32_6` | `opt_32_7` | `opt_32_8` | `opt_32_9` | `opt_32_10` | `opt_32_11` |
| **37%** | `opt_37_6` | `opt_37_7` | `opt_37_8` | `opt_37_9` | `opt_37_10` | `opt_37_11` |

* **25% over 10 months:** `opt_25_10` doesn't exist. The nearest down payment at or above 25% for 10 months is 27%, so the lookup returns `opt_27_10`.
* **40% over 10 months:** nothing at or above 40%. The lookup returns `recommended_option_id`, which here is `opt_27_10`.
* **25% over 12 months:** no 12-month term (the loan has to end before the policy does), so the lookup returns `recommended_option_id`.

The recommended option is the down payment closest to the weighted minimum earned, at the term we'd suggest for it.

## When your client has already chosen

If your client picked an option on the [interactive quote](/guides/hosted-quote-page), use theirs: `selected_option_id` on the quote. A house rule is for the default you show first, not for overriding a choice.

<Note>
  **The ladder may change.** We're considering a fixed 5% grid of down payments (10, 15, 20, 25 and so on) instead of one that follows the minimum earned. The lookup above is correct either way: exact id first, then the nearest down payment at or above your target for the same term, then the recommended option. Write it once and it keeps working.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.