Monthly Payment API

Build your own “estimated monthly payment” widget. One call returns loan payments (Upgrade + Thrive Financial) and SmartPay rent-to-own, using exactly the same rules as our live financing estimator.

Open the live test page → Developer kit ↓

How it works

  1. On page load, call GET /v1/{brand}/options to get the two customer questions (labels + dropdown values).
  2. With the customer’s answers plus the structure’s delivery ZIP and total price, call POST /v1/{brand}/estimate.
  3. Show what comes back. Eligibility, terms, payments, APRs, Apply links and disclosure text are all pre-computed.
Base URL: https://payment-estimate-api.pages.dev · Brand: stoltzfus (more brands coming)
JSON in, JSON out, no API key. Browser calls are allowed from mysheds.com (any subdomain) and localhost. Calls from your server (no Origin header) are always allowed. Need another domain allowed, e.g. a staging site? Ask Tim Brazil.
Always in sync with our estimator. The API reads its rates, limits, eligibility rules, Apply links and disclosures live from our published estimator (shedlender.com/estimator.html), so your widget can never disagree with it. If our estimator’s calculation logic changes, the API returns HTTP 503 estimates_unavailable until we confirm the change. Please handle that by hiding the payment section or showing a short “unavailable” note.

Your widget, your layout

You decide when to call the API and how to show the results. No button is required. The test page lets you try three styles:

For automatic updates, only call the API once the ZIP has 5 digits, price is above 0 and both questions are answered. Wait about 0.4 seconds after the last keystroke, and ignore any older response that comes back after a newer one. That keeps it fast and well under the limit of 120 rent-to-own quotes per visitor every 10 minutes. Switching terms needs no new call, because every term is already in the response.

Try A · Try B · Try C

1 · GET /v1/stoltzfus/options

Build your two <select>s from questions.creditScore.options and questions.ownProperty.options, then send the value back.

{
  "questions": {
    "creditScore": { "label": "What is your credit score?", "placeholder": "— Select credit score —",
      "options": [ { "value": "840", "label": "840 – 850" }, … { "value": "500", "label": "Below 550" } ] },
    "ownProperty": { "label": "Do you own the property where the project is located?",
      "options": [ { "value": "own", "label": "Yes, I own the property" },
                   { "value": "biz", "label": "Yes, my business owns the property" },
                   { "value": "no",  "label": "No, I do not own the property" } ] }
  },
  "lenders": { "upgrade": { "minCreditScore": 680, "minAmount": 2000, "maxAmount": 100000, … }, "thrive": { … }, "rto": { … } },
  "disclosures": { … }, "displayRules": [ … ]
}

2 · POST /v1/stoltzfus/estimate

FieldTypeExampleNotes
zipstring"19310"Delivery ZIP. Sets sales tax and state availability for rent-to-own.
pricenumber16820Total price of the structure with options, in dollars.
creditScorestring"720"A value from /options.
ownPropertystring"own"A value from /options (own · biz · no).

GET /v1/stoltzfus/estimate?zip=19310&price=16820&creditScore=720&ownProperty=own also works, which is handy for testing in a browser tab.

const res = await fetch('https://payment-estimate-api.pages.dev/v1/stoltzfus/estimate', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ zip: '19310', price: 16820, creditScore: '720', ownProperty: 'own' })
});
if (res.status === 503) { /* hide the payment section — estimates temporarily off */ }
const data = await res.json();

Response (shortened)

{
  "ok": true,
  "input": { "zip": "19310", "state": "PA", "price": 16820, "creditScore": "720", "ownProperty": "own" },
  "loans": {
    "available": true,
    "defaultTermYears": 20,                     // pre-select this term (the longest)
    "terms": [                                  // ONE payment per term — use these for your payment choices
      { "years": 5, "label": "5-Year", "monthlyPaymentDisplay": "$372", "aprDisplay": "7.99% APR*", "footnote": "†",
        "paymentNote": "Months 1–6 are interest-only; …", "bestLender": "thrive",
        "offers": [ { "lenderName": "Thrive Financial", "monthlyPaymentDisplay": "$372", "aprDisplay": "7.99% APR*", "applyLink": "…" },
                    { "lenderName": "Upgrade", "monthlyPaymentDisplay": "$349", "aprDisplay": "8.99% APR*", "applyLink": "…" } ] },
      …
      { "years": 20, "label": "20-Year", "monthlyPaymentDisplay": "$164", "aprDisplay": "9.99% APR*", "footnote": "†", "offers": [ … Thrive only … ] }
    ],
    "byLender": {                               // full per-lender detail, exactly as the estimator shows it
      "upgrade": { "eligible": true, "terms": [ 5, 7, 10, 12, 15-year … ] },
      "thrive":  { "eligible": true, "terms": [ … incl. interestOnlyPayments for months 1–6 … ] }
    },
    "message": null                             // text to show when available = false
  },
  "rentToOwn": {
    "available": true, "creditCheck": false, "defaultTermMonths": 48,
    "terms": [ { "months": 24, "monthlyPaymentDisplay": "$1,048.77", "upfrontPayment": 3364 }, … ],
    "overMaxText": null,                        // set when the price is over $25,000 (payments are for $25,000)
    "notes": [ "Rent-to-own is not available for 2-story structures or …" ],
    "applyLink": "https://payment-estimate-api.pages.dev/v1/stoltzfus/apply/rto",
    "reason": null, "reasonText": null          // why it’s unavailable, when available = false
  },
  "disclosures": {
    "forThisWidget": [                          // show ALL of these, in order — word-for-word from our estimator
      { "type": "paragraph", "paragraphs": [ { "text": "Stoltzfus Structures is not a lender…", "html": "…" } ] },
      { "type": "heading", "text": "Important Disclosures" },
      { "type": "section", "id": "disc-rto", "title": "Rent-to-Own (SmartPay)",
        "paragraphs": [ { "text": "You do not own the structure until…", "html": "… higher than the cash price …" } ] },
      …
    ],
    "all": [ … ],                               // the estimator's whole footer, incl. products this widget doesn't offer
    "representativeExample": "…", "rentToOwnStructures": "Structures that are 2 stories or … do not qualify for rent-to-own."
  },
  "displayRules": [ … ]
}

Errors return HTTP 400 with {"ok":false,"error":"invalid_input","fields":{"zip":"Enter a valid 5-digit US ZIP code"}}. The messages are written for customers, so you can show them as-is.

Display rules (please follow)

Do / don’t (what compliant looks like)

✓ Do

20-Year †
$164/mo
9.99% APR*

Payment always with its APR and term, markers kept.

✗ Don’t

Only $164/mo!

A payment on its own (no APR, no term) breaks federal advertising rules.

✓ Do

Rent-to-own · 48 months
$742.88/mo
$3,364.00 due upfront · no credit check

Rent-to-own shows cost only. It’s a lease, not a loan.

✗ Don’t

Rent-to-own · 48 months
$742.88/mo
XX% APR

Never show an APR or interest rate for rent-to-own.

✓ Do

Tiles: 5-Year · 10-Year · 20-Year
Apply step: Thrive Financial — $164/mo · Start application →

Lender names appear only at the Apply step.

✗ Don’t

Tiles
“Thrive 20-Year $164” · “Upgrade 15-Year $181”

Don’t brand the payment choices with lender names.

✓ Do

⚠ Over the $200,000 max — payments shown are for $200,000
$1,689/mo · 7.99% APR*

Show loans.notice / overMaxText next to capped payments.

✗ Don’t

$300,000 garage
$1,689/mo · 7.99% APR*

Hiding the cap makes the payment look like it covers the full price.

✓ Do

Every block of disclosures.forThisWidget, word-for-word, in order

They update automatically when our estimator changes.

✗ Don’t

“Financing available, terms apply.”

Don’t paraphrase, shorten or hard-code the disclosures.

Errors and “not available” reasons

What comes backWhenWhat the customer should seeTry it
HTTP 503 estimates_unavailableSafety switch: our estimator’s calculation logic changed and we haven’t confirmed it yetHide the payment section, or “Payment estimates are temporarily unavailable.”?simulate=unavailable
HTTP 400 invalid_input + fieldsBad ZIP, price, or answer valueEach field message under its input (written for customers)?simulate=invalid
HTTP 403 origin_not_allowedCalled from a website not on our listCustomers never see this on mysheds.com. Ask Tim to add a new staging address. (The browser shows it as a CORS error.)?simulate=origin_blocked
rentToOwn.reason: quote_unavailableSmartPay’s quote service didn’t answerrentToOwn.reasonText, and keep the SmartPay Apply button?simulate=rto_unavailable
Slow answerNetwork or SmartPay slowA loading state. Never block the page?simulate=slow (4 s)
loans.available: false + loans.messageNo loan fits (e.g. credit below 550)loans.message (rent-to-own may still show)credit 500
loans.noticePrice is over every lender’s max; payments are for the capped amountThe notice, right beside the paymentsprice 300000
byLender.*.reasoncredit_score · amount_below_minimum · state · property_ownership · coming_soonOptional: reasonText if you show why a lender isn’t offeredown no, credit 640
rentToOwn.reasonstate (AK HI MN MS WA WI WY) · amount_below_minimum (<$1,000) · zip_not_supportedrentToOwn.reasonText, or hide rent-to-ownZIP 53703

Every error is JSON {"ok":false,"error":…}. The simulator values work on /estimate as a query parameter or a "simulate" field in the POST body, and are never counted in usage stats.

Developer kit

Everything is ready to use. Copy the three widget files into the Next.js project, or build your own UI from the types.

MonthlyPaymentEstimate.tsxDrop-in React widget ('use client'). Styles: auto, dropdown, button. Follows every display rule. Tested on React 18 and 19. payment-estimate-api.tsTypeScript types for every response, plus getOptions() and getEstimate() helpers. Type-checked against live responses. monthly-payment-estimate.css.pme-* classes and --pme-* variables (mysheds colors and Rubik). Restyle freely. README.mdInstall, props, examples for each style, error handling. openapi.jsonOpenAPI 3.0 description of the whole API. Import into Swagger, Postman or a code generator. Postman collection22 ready-made requests including every error simulation, with tests. Download everything (.zip)All of the above in one file.

Launch checklist

  1. Open the test page, press Run all scenarios, and confirm all pass.
  2. Add the widget to a garage page on staging or localhost (localhost is already allowed). Send Tim any other staging address to allow.
  3. Feed it the total price from your price calculator, including options. Don’t call the API for custom-quote structures (Build On-Site, Attached); show “request a quote”.
  4. Check each widget style you use with the test page’s Error simulator: 503, 400 and rent-to-own down.
  5. Confirm Apply buttons use applyLink and open in a new tab only when applyOpensNewTab is true.
  6. Confirm the disclosures from disclosures.forThisWidget appear on the page, word for word.
  7. Phone check: the widget fits a 360-pixel-wide screen.
  8. Send Tim the staging link for a compliance look before going live.
  9. Go live. Tim gets an automatic email if our rules change or estimates switch off, and so do you once you’re on the alert list.

Usage stats and alerts

The API keeps anonymous counts only (estimates shown, Apply clicks per lender, per day). It never stores customer answers, ZIPs or prices. Apply clicks are counted when buttons use applyLink, which forwards the customer to the lender. A monitor checks every hour and emails if our estimator’s rates, rules or disclosures change (the API already follows them, so your widget needs no change) or if estimates switch off.

Field reference

Show every response field (generated from openapi.json)
Field (POST /estimate response)TypeWhat it means
okbooleanAlways `true` on a successful response.
apiVersionstringAPI version (a date).
brandstringBrand slug.
rulesFromobjectWhere and when the API read the rules it used for this response.
rulesFrom.estimatorstringThe published estimator page the rules were read from.
rulesFrom.estimatorVersionstringShort hash of the estimator version the rules came from. Changes whenever the estimator page changes.
rulesFrom.readAtstringWhen the rules were read from the estimator (UTC, ISO 8601).
rulesFrom.sourcestringHow the rules were obtained for this response, e.g. `live` (just read from the estimator page) or `cache` (a recent read is being reused).
inputobjectThe inputs the estimate was calculated for.
input.zipstringZIP as received (5 digits).
input.statestring or nullTwo-letter state for the ZIP, or null when the ZIP is not in one of the 50 states or DC (e.g. Puerto Rico).
input.pricenumberPrice as received (USD).
input.creditScorestringCredit-score value as received.
input.creditScoreLabelstringIts label.
input.ownPropertystringOwnership value as received.
input.ownPropertyLabelstringIts label.
loansobjectLoan payments (Upgrade and Thrive Financial).
loans.availablebooleanTrue when at least one loan term is offered.
loans.defaultTermYearsinteger or nullTerm (years) to pre-select — the longest offered. Null when no loans.
loans.termslist of objectONE payment choice per term, shortest first. Use these for your payment choices. Empty when `available` is false.
loans.terms[].lenderstringLoan lender key.
loans.terms[].yearsintegerTerm in years.
loans.terms[].monthsintegerTerm in months.
loans.terms[].labelstringTerm label for your UI, e.g. `5-Year`, or `12-Year Offer` for a Thrive counter-offer term.
loans.terms[].amountnumberAmount (USD) the payment is calculated on. Lower than the price when the price is over this lender's maximum.
loans.terms[].aprnumberAPR as a percent number (7.99 = 7.99%).
loans.terms[].aprDisplaystringAPR ready to show, including the `*` marker — keep it exactly as given.
loans.terms[].monthlyPaymentnumberMonthly payment (USD, unrounded to the cent).
loans.terms[].monthlyPaymentDisplaystringMonthly payment ready to show. Always show it together with `aprDisplay` and the term.
loans.terms[].interestOnlybooleanTrue when the first months are interest-only (Thrive Building Loan).
loans.terms[].footnotestring`†` on interest-only terms, otherwise an empty string. Keep it next to the payment.
loans.terms[].paymentNotestringOne-line explanation of the payment to show near it.
loans.terms[].estimatorLabelstringThrive rows only: the label the estimator itself uses, e.g. `5-Year Term`, `12-Year Offer`.
loans.terms[].counterOfferbooleanThrive rows only: true for a counter-offer term (offered to some credit tiers instead of the standard term).
loans.terms[].interestOnlyMonthsintegerThrive rows only: number of interest-only months at the start.
loans.terms[].interestOnlyPaymentsobjectThrive Building Loan: what months 1–6 (interest-only) cost.
loans.terms[].interestOnlyPayments.halfReleasednumberInterest-only payment (USD) while half of the loan has been released.
loans.terms[].interestOnlyPayments.halfReleasedDisplaystringFormatted, e.g. `$56/mo`.
loans.terms[].interestOnlyPayments.fullReleasednumberInterest-only payment (USD) once the full loan has been released.
loans.terms[].interestOnlyPayments.fullReleasedDisplaystringFormatted, e.g. `$112/mo`.
loans.terms[].bestLenderstringKey of the lender whose numbers this row shows (observed: the lowest APR for the term). Do not show the lender name on this row.
loans.terms[].offerslist of objectEvery lender offering this term (1 or more) — show these, with lender names, at the Apply step.
loans.terms[].offers[].lenderstringLoan lender key.
loans.terms[].offers[].yearsintegerTerm in years.
loans.terms[].offers[].monthsintegerTerm in months.
loans.terms[].offers[].labelstringTerm label for your UI, e.g. `5-Year`, or `12-Year Offer` for a Thrive counter-offer term.
loans.terms[].offers[].amountnumberAmount (USD) the payment is calculated on. Lower than the price when the price is over this lender's maximum.
loans.terms[].offers[].aprnumberAPR as a percent number (7.99 = 7.99%).
loans.terms[].offers[].aprDisplaystringAPR ready to show, including the `*` marker — keep it exactly as given.
loans.terms[].offers[].monthlyPaymentnumberMonthly payment (USD, unrounded to the cent).
loans.terms[].offers[].monthlyPaymentDisplaystringMonthly payment ready to show. Always show it together with `aprDisplay` and the term.
loans.terms[].offers[].interestOnlybooleanTrue when the first months are interest-only (Thrive Building Loan).
loans.terms[].offers[].footnotestring`†` on interest-only terms, otherwise an empty string. Keep it next to the payment.
loans.terms[].offers[].paymentNotestringOne-line explanation of the payment to show near it.
loans.terms[].offers[].estimatorLabelstringThrive rows only: the label the estimator itself uses, e.g. `5-Year Term`, `12-Year Offer`.
loans.terms[].offers[].counterOfferbooleanThrive rows only: true for a counter-offer term (offered to some credit tiers instead of the standard term).
loans.terms[].offers[].interestOnlyMonthsintegerThrive rows only: number of interest-only months at the start.
loans.terms[].offers[].interestOnlyPaymentsobjectThrive Building Loan: what months 1–6 (interest-only) cost.
loans.terms[].offers[].interestOnlyPayments.halfReleasednumberInterest-only payment (USD) while half of the loan has been released.
loans.terms[].offers[].interestOnlyPayments.halfReleasedDisplaystringFormatted, e.g. `$56/mo`.
loans.terms[].offers[].interestOnlyPayments.fullReleasednumberInterest-only payment (USD) once the full loan has been released.
loans.terms[].offers[].interestOnlyPayments.fullReleasedDisplaystringFormatted, e.g. `$112/mo`.
loans.terms[].offers[].lenderNamestringLender display name — show it here, at the Apply step.
loans.terms[].offers[].productstringProduct name.
loans.terms[].offers[].applyUrlstringThe lender's own application page (reference only).
loans.terms[].offers[].applyLinkstringPoint the Apply button here. It counts the click anonymously, then redirects to the lender. Carries `?term=<months>`.
loans.terms[].offers[].applyOpensNewTabbooleanOpen `applyLink` in a new tab when true.
loans.terms[].offers[].applyHintobjectThe small print the estimator shows under this lender's Apply button. Show it next to your Apply button.
loans.terms[].offers[].applyHint.textstringPlain-text small print (footnote markers printed as ¹ etc.).
loans.terms[].offers[].applyHint.htmlstringSame text as HTML. Sanitized server-side: only `<strong>`, `<b>`, `<em>`, `<sup>` tags and HTML entities, so it is safe to insert as HTML.
loans.byLenderobjectPer-lender detail (eligibility, reasons, every term).
loans.byLender.upgradeobjectFull detail for one loan lender.
loans.byLender.upgrade.lenderstringLender display name.
loans.byLender.upgrade.productstringProduct name.
loans.byLender.upgrade.eligiblebooleanWhether this lender can offer these answers.
loans.byLender.upgrade.comingSoonbooleanTrue when the program is announced but not yet open.
loans.byLender.upgrade.reasonstring or nullWhy not eligible, as a code — e.g. `credit_score`, `property_ownership`, `amount_below_minimum`, `state`. Null when eligible.
loans.byLender.upgrade.reasonTextstring or nullWhy not eligible, in customer-ready words. Null when eligible.
loans.byLender.upgrade.applyUrlstringThe lender's own application page (reference only).
loans.byLender.upgrade.applyLinkstringApply link (counts the click anonymously, then redirects).
loans.byLender.upgrade.applyOpensNewTabbooleanOpen `applyLink` in a new tab when true.
loans.byLender.upgrade.applyHintobjectThe small print the estimator shows under this lender's Apply button. Show it next to your Apply button.
loans.byLender.upgrade.applyHint.textstringPlain-text small print (footnote markers printed as ¹ etc.).
loans.byLender.upgrade.applyHint.htmlstringSame text as HTML. Sanitized server-side: only `<strong>`, `<b>`, `<em>`, `<sup>` tags and HTML entities, so it is safe to insert as HTML.
loans.byLender.upgrade.termslist of objectThis lender's own term rows, exactly as the estimator shows them. Empty when not eligible.
loans.byLender.upgrade.terms[].lenderstringLoan lender key.
loans.byLender.upgrade.terms[].yearsintegerTerm in years.
loans.byLender.upgrade.terms[].monthsintegerTerm in months.
loans.byLender.upgrade.terms[].labelstringTerm label for your UI, e.g. `5-Year`, or `12-Year Offer` for a Thrive counter-offer term.
loans.byLender.upgrade.terms[].amountnumberAmount (USD) the payment is calculated on. Lower than the price when the price is over this lender's maximum.
loans.byLender.upgrade.terms[].aprnumberAPR as a percent number (7.99 = 7.99%).
loans.byLender.upgrade.terms[].aprDisplaystringAPR ready to show, including the `*` marker — keep it exactly as given.
loans.byLender.upgrade.terms[].monthlyPaymentnumberMonthly payment (USD, unrounded to the cent).
loans.byLender.upgrade.terms[].monthlyPaymentDisplaystringMonthly payment ready to show. Always show it together with `aprDisplay` and the term.
loans.byLender.upgrade.terms[].interestOnlybooleanTrue when the first months are interest-only (Thrive Building Loan).
loans.byLender.upgrade.terms[].footnotestring`†` on interest-only terms, otherwise an empty string. Keep it next to the payment.
loans.byLender.upgrade.terms[].paymentNotestringOne-line explanation of the payment to show near it.
loans.byLender.upgrade.terms[].estimatorLabelstringThrive rows only: the label the estimator itself uses, e.g. `5-Year Term`, `12-Year Offer`.
loans.byLender.upgrade.terms[].counterOfferbooleanThrive rows only: true for a counter-offer term (offered to some credit tiers instead of the standard term).
loans.byLender.upgrade.terms[].interestOnlyMonthsintegerThrive rows only: number of interest-only months at the start.
loans.byLender.upgrade.terms[].interestOnlyPaymentsobjectThrive Building Loan: what months 1–6 (interest-only) cost.
loans.byLender.upgrade.terms[].interestOnlyPayments.halfReleasednumberInterest-only payment (USD) while half of the loan has been released.
loans.byLender.upgrade.terms[].interestOnlyPayments.halfReleasedDisplaystringFormatted, e.g. `$56/mo`.
loans.byLender.upgrade.terms[].interestOnlyPayments.fullReleasednumberInterest-only payment (USD) once the full loan has been released.
loans.byLender.upgrade.terms[].interestOnlyPayments.fullReleasedDisplaystringFormatted, e.g. `$112/mo`.
loans.byLender.upgrade.overMaxbooleanTrue when the price is over this lender's maximum (payments are for the maximum).
loans.byLender.upgrade.overMaxTextstring or nullCustomer-ready note to show beside this lender's payments when `overMax` is true; otherwise null.
loans.byLender.thriveobjectFull detail for one loan lender.
loans.byLender.thrive.lenderstringLender display name.
loans.byLender.thrive.productstringProduct name.
loans.byLender.thrive.eligiblebooleanWhether this lender can offer these answers.
loans.byLender.thrive.comingSoonbooleanTrue when the program is announced but not yet open.
loans.byLender.thrive.reasonstring or nullWhy not eligible, as a code — e.g. `credit_score`, `property_ownership`, `amount_below_minimum`, `state`. Null when eligible.
loans.byLender.thrive.reasonTextstring or nullWhy not eligible, in customer-ready words. Null when eligible.
loans.byLender.thrive.applyUrlstringThe lender's own application page (reference only).
loans.byLender.thrive.applyLinkstringApply link (counts the click anonymously, then redirects).
loans.byLender.thrive.applyOpensNewTabbooleanOpen `applyLink` in a new tab when true.
loans.byLender.thrive.applyHintobjectThe small print the estimator shows under this lender's Apply button. Show it next to your Apply button.
loans.byLender.thrive.applyHint.textstringPlain-text small print (footnote markers printed as ¹ etc.).
loans.byLender.thrive.applyHint.htmlstringSame text as HTML. Sanitized server-side: only `<strong>`, `<b>`, `<em>`, `<sup>` tags and HTML entities, so it is safe to insert as HTML.
loans.byLender.thrive.termslist of objectThis lender's own term rows, exactly as the estimator shows them. Empty when not eligible.
loans.byLender.thrive.terms[].lenderstringLoan lender key.
loans.byLender.thrive.terms[].yearsintegerTerm in years.
loans.byLender.thrive.terms[].monthsintegerTerm in months.
loans.byLender.thrive.terms[].labelstringTerm label for your UI, e.g. `5-Year`, or `12-Year Offer` for a Thrive counter-offer term.
loans.byLender.thrive.terms[].amountnumberAmount (USD) the payment is calculated on. Lower than the price when the price is over this lender's maximum.
loans.byLender.thrive.terms[].aprnumberAPR as a percent number (7.99 = 7.99%).
loans.byLender.thrive.terms[].aprDisplaystringAPR ready to show, including the `*` marker — keep it exactly as given.
loans.byLender.thrive.terms[].monthlyPaymentnumberMonthly payment (USD, unrounded to the cent).
loans.byLender.thrive.terms[].monthlyPaymentDisplaystringMonthly payment ready to show. Always show it together with `aprDisplay` and the term.
loans.byLender.thrive.terms[].interestOnlybooleanTrue when the first months are interest-only (Thrive Building Loan).
loans.byLender.thrive.terms[].footnotestring`†` on interest-only terms, otherwise an empty string. Keep it next to the payment.
loans.byLender.thrive.terms[].paymentNotestringOne-line explanation of the payment to show near it.
loans.byLender.thrive.terms[].estimatorLabelstringThrive rows only: the label the estimator itself uses, e.g. `5-Year Term`, `12-Year Offer`.
loans.byLender.thrive.terms[].counterOfferbooleanThrive rows only: true for a counter-offer term (offered to some credit tiers instead of the standard term).
loans.byLender.thrive.terms[].interestOnlyMonthsintegerThrive rows only: number of interest-only months at the start.
loans.byLender.thrive.terms[].interestOnlyPaymentsobjectThrive Building Loan: what months 1–6 (interest-only) cost.
loans.byLender.thrive.terms[].interestOnlyPayments.halfReleasednumberInterest-only payment (USD) while half of the loan has been released.
loans.byLender.thrive.terms[].interestOnlyPayments.halfReleasedDisplaystringFormatted, e.g. `$56/mo`.
loans.byLender.thrive.terms[].interestOnlyPayments.fullReleasednumberInterest-only payment (USD) once the full loan has been released.
loans.byLender.thrive.terms[].interestOnlyPayments.fullReleasedDisplaystringFormatted, e.g. `$112/mo`.
loans.byLender.thrive.overMaxbooleanTrue when the price is over this lender's maximum (payments are for the maximum).
loans.byLender.thrive.overMaxTextstring or nullCustomer-ready note to show beside this lender's payments when `overMax` is true; otherwise null.
loans.messagestring or nullText to show instead of loan payments when `available` is false; null otherwise.
loans.noticestring or nullNote to show beside the loan payments (e.g. the price is over the maximum of the lender whose numbers are shown). Null when there is nothing to say.
rentToOwnobjectRent-to-own (SmartPay). A lease, not a loan: never show an APR or interest rate for it.
rentToOwn.availablebooleanTrue when rent-to-own payments are shown (`terms` is filled).
rentToOwn.eligiblebooleanWhether these answers qualify for rent-to-own. Can be true while `available` is false (e.g. the live quote failed — the customer can still apply).
rentToOwn.providerstringProvider name — show only at the Apply step.
rentToOwn.productstringProduct name.
rentToOwn.creditCheckbooleanFalse: rent-to-own uses no credit check.
rentToOwn.amountnumber or nullAmount (USD) the payments are for (capped at the rent-to-own maximum). Null when not eligible.
rentToOwn.defaultTermMonthsinteger or nullTerm (months) to pre-select. Null when unavailable.
rentToOwn.termslist of objectLease terms. Empty when `available` is false.
rentToOwn.terms[].monthsintegerLease term in months.
rentToOwn.terms[].labelstringTerm label.
rentToOwn.terms[].monthlyPaymentnumberMonthly lease payment (USD), tax included.
rentToOwn.terms[].monthlyPaymentDisplaystringMonthly payment ready to show (to the cent). Never pair it with an APR or rate — it is a lease.
rentToOwn.terms[].upfrontPaymentnumberAmount due upfront (USD).
rentToOwn.terms[].upfrontPaymentDisplaystringUpfront amount ready to show.
rentToOwn.terms[].securityDepositnumberSecurity-deposit part of the upfront amount (USD).
rentToOwn.terms[].customerReserveAccountnumberCustomer reserve account amount (USD).
rentToOwn.terms[].deliveryFeenumberDelivery fee (USD).
rentToOwn.terms[].taxIncludedbooleanTrue when sales tax (from the ZIP) is included in the payments.
rentToOwn.overMaxbooleanTrue when the price is over the rent-to-own maximum.
rentToOwn.overMaxTextstring or nullCustomer-ready note to show beside the rent-to-own payments when `overMax` is true; otherwise null.
rentToOwn.noteslist of stringNotes to show with rent-to-own.
rentToOwn.applyUrlstringSmartPay's own application page (reference only).
rentToOwn.applyLinkstringApply link (counts the click anonymously, then redirects).
rentToOwn.applyOpensNewTabbooleanOpen `applyLink` in a new tab when true.
rentToOwn.applyHintobjectThe small print the estimator shows under this lender's Apply button. Show it next to your Apply button.
rentToOwn.applyHint.textstringPlain-text small print (footnote markers printed as ¹ etc.).
rentToOwn.applyHint.htmlstringSame text as HTML. Sanitized server-side: only `<strong>`, `<b>`, `<em>`, `<sup>` tags and HTML entities, so it is safe to insert as HTML.
rentToOwn.reasonstring or nullWhy unavailable, as a code — e.g. `state`, `zip_not_supported`, `amount_below_minimum`, `quote_unavailable`. Null when available.
rentToOwn.reasonTextstring or nullWhy unavailable, in customer-ready words. Null when available.
rentToOwn.quoteErrorstringPresent only when the live rent-to-own quote failed (`reason` = `quote_unavailable`); short technical code, not for customers.
disclosuresobjectDisclosure text for the page, read live from the estimator.
disclosures.sourcestringWhere the disclosure text was copied from.
disclosures.forThisWidgetlist of blocksThe disclosures your page must show, in this order. Copied word-for-word from the estimator and updated automatically — never edit or retype them.
disclosures.forThisWidget[].typestringBlock type.
disclosures.forThisWidget[].idstring or nullAnchor id of the block on the estimator page (e.g. `disc-credit`), or null.
disclosures.forThisWidget[].titlestring or nullOptional title (plain text), or null.
disclosures.forThisWidget[].titleHtmlstring or nullOptional title as sanitized HTML, or null.
disclosures.forThisWidget[].paragraphslist of objectParagraphs to show, in order.
disclosures.forThisWidget[].paragraphs[].textstringPlain-text paragraph, word-for-word from the estimator page.
disclosures.forThisWidget[].paragraphs[].htmlstringSame paragraph as sanitized HTML (only `<strong>`, `<b>`, `<em>`, `<sup>` and entities). Prefer this to keep the bold text and superscript markers.
disclosures.forThisWidget[].textstringHeading text.
disclosures.alllist of blocksThe estimator's complete disclosure footer (reference only).
disclosures.footnoteslist of objectEvery footnote marker and which disclosure explains it.
disclosures.footnotes[].markerstringFootnote marker as a plain character: `1`, `*`, `2`, `3`, `†` …
disclosures.footnotes[].displaystringHow the marker is printed: `¹`, `*`, `²`, `³`, `†` …
disclosures.footnotes[].disclosureIdstringId of the disclosure block that explains this marker.
disclosures.footnotes[].titlestring or nullTitle of that disclosure block, or null when it has none.
disclosures.footnotes[].appliesToThisWidgetbooleanTrue when the explaining block is part of `forThisWidget` (so it will be on your page).
disclosures.footnotes[].notestringExtra explanation. Present only on the `†` (interest-only) marker, which has no block of its own — it is explained inside the `disc-payments` section and in each term's `paymentNote`.
disclosures.notALenderstringThe "not a lender" statement on its own, for tight layouts.
disclosures.representativeExamplestringThe representative-example sentence on its own.
disclosures.rentToOwnStructuresstringWhich structures do not qualify for rent-to-own.
displayRuleslist of stringThe display rules, in plain English. Please follow them.
simulatedstringEcho of the `simulate` value, present only when one was sent (testing only).
Field (GET /options response)TypeWhat it means
okbooleanAlways `true` on a successful response.
apiVersionstringAPI version (a date).
brandstringBrand slug.
brandNamestringBrand display name.
rulesFromobjectWhere and when the API read the rules it used for this response.
rulesFrom.estimatorstringThe published estimator page the rules were read from.
rulesFrom.estimatorVersionstringShort hash of the estimator version the rules came from. Changes whenever the estimator page changes.
rulesFrom.readAtstringWhen the rules were read from the estimator (UTC, ISO 8601).
rulesFrom.sourcestringHow the rules were obtained for this response, e.g. `live` (just read from the estimator page) or `cache` (a recent read is being reused).
questionsobjectThe two customer questions.
questions.creditScoreobjectOne customer question, ready to render as a `<select>`.
questions.creditScore.fieldstringName of the /estimate input this question fills.
questions.creditScore.labelstringQuestion text.
questions.creditScore.placeholderstringText for the empty first dropdown option.
questions.creditScore.helpTextstringHelp text to show under the question.
questions.creditScore.optionslist of objectDropdown choices, in display order. Values are read live from the estimator — do not hard-code them.
questions.creditScore.options[].valuestringSend this value back to /estimate.
questions.creditScore.options[].labelstringShow this text in the dropdown.
questions.ownPropertyobjectOne customer question, ready to render as a `<select>`.
questions.ownProperty.fieldstringName of the /estimate input this question fills.
questions.ownProperty.labelstringQuestion text.
questions.ownProperty.placeholderstringText for the empty first dropdown option.
questions.ownProperty.helpTextstringHelp text to show under the question.
questions.ownProperty.optionslist of objectDropdown choices, in display order. Values are read live from the estimator — do not hard-code them.
questions.ownProperty.options[].valuestringSend this value back to /estimate.
questions.ownProperty.options[].labelstringShow this text in the dropdown.
inputsobjectPlain-English description of each /estimate input.
inputs.zipstring
inputs.pricestring
inputs.creditScorestring
inputs.ownPropertystring
lendersobjectProgram limits per lender key: `upgrade` (Upgrade loan), `thrive` (Thrive Financial Building Loan), `rto` (SmartPay rent-to-own).
lenders.upgradeobjectA lender program's limits, as read live from the estimator.
lenders.upgrade.lenderstringLender display name — show it only at the Apply step.
lenders.upgrade.productstringProduct name.
lenders.upgrade.minCreditScoreintegerLowest credit-score value accepted (0 = no credit check).
lenders.upgrade.minAmountnumberSmallest amount (USD) this program finances.
lenders.upgrade.maxAmountnumberLargest amount (USD) this program finances. Higher prices get payments for this amount plus an `overMaxText`.
lenders.upgrade.requiresPropertyOwnershipbooleanTrue when the customer (or their business) must own the property.
lenders.upgrade.notOfferedInStateslist of stringTwo-letter states where the program is not offered.
lenders.upgrade.comingSoonbooleanTrue when the program is announced but not yet open.
lenders.upgrade.applyUrlstringThe lender's own application page. For reference — point buttons at the estimate's `applyLink` instead.
lenders.upgrade.applyHintobjectThe small print the estimator shows under this lender's Apply button. Show it next to your Apply button.
lenders.upgrade.applyHint.textstringPlain-text small print (footnote markers printed as ¹ etc.).
lenders.upgrade.applyHint.htmlstringSame text as HTML. Sanitized server-side: only `<strong>`, `<b>`, `<em>`, `<sup>` tags and HTML entities, so it is safe to insert as HTML.
lenders.thriveobjectA lender program's limits, as read live from the estimator.
lenders.thrive.lenderstringLender display name — show it only at the Apply step.
lenders.thrive.productstringProduct name.
lenders.thrive.minCreditScoreintegerLowest credit-score value accepted (0 = no credit check).
lenders.thrive.minAmountnumberSmallest amount (USD) this program finances.
lenders.thrive.maxAmountnumberLargest amount (USD) this program finances. Higher prices get payments for this amount plus an `overMaxText`.
lenders.thrive.requiresPropertyOwnershipbooleanTrue when the customer (or their business) must own the property.
lenders.thrive.notOfferedInStateslist of stringTwo-letter states where the program is not offered.
lenders.thrive.comingSoonbooleanTrue when the program is announced but not yet open.
lenders.thrive.applyUrlstringThe lender's own application page. For reference — point buttons at the estimate's `applyLink` instead.
lenders.thrive.applyHintobjectThe small print the estimator shows under this lender's Apply button. Show it next to your Apply button.
lenders.thrive.applyHint.textstringPlain-text small print (footnote markers printed as ¹ etc.).
lenders.thrive.applyHint.htmlstringSame text as HTML. Sanitized server-side: only `<strong>`, `<b>`, `<em>`, `<sup>` tags and HTML entities, so it is safe to insert as HTML.
lenders.rtoobjectA lender program's limits, as read live from the estimator.
lenders.rto.lenderstringLender display name — show it only at the Apply step.
lenders.rto.productstringProduct name.
lenders.rto.minCreditScoreintegerLowest credit-score value accepted (0 = no credit check).
lenders.rto.minAmountnumberSmallest amount (USD) this program finances.
lenders.rto.maxAmountnumberLargest amount (USD) this program finances. Higher prices get payments for this amount plus an `overMaxText`.
lenders.rto.requiresPropertyOwnershipbooleanTrue when the customer (or their business) must own the property.
lenders.rto.notOfferedInStateslist of stringTwo-letter states where the program is not offered.
lenders.rto.comingSoonbooleanTrue when the program is announced but not yet open.
lenders.rto.applyUrlstringThe lender's own application page. For reference — point buttons at the estimate's `applyLink` instead.
lenders.rto.applyHintobjectThe small print the estimator shows under this lender's Apply button. Show it next to your Apply button.
lenders.rto.applyHint.textstringPlain-text small print (footnote markers printed as ¹ etc.).
lenders.rto.applyHint.htmlstringSame text as HTML. Sanitized server-side: only `<strong>`, `<b>`, `<em>`, `<sup>` tags and HTML entities, so it is safe to insert as HTML.
disclosuresobjectDisclosure text for the page, read live from the estimator.
disclosures.sourcestringWhere the disclosure text was copied from.
disclosures.forThisWidgetlist of blocksThe disclosures your page must show, in this order. Copied word-for-word from the estimator and updated automatically — never edit or retype them.
disclosures.forThisWidget[].typestringBlock type.
disclosures.forThisWidget[].idstring or nullAnchor id of the block on the estimator page (e.g. `disc-credit`), or null.
disclosures.forThisWidget[].titlestring or nullOptional title (plain text), or null.
disclosures.forThisWidget[].titleHtmlstring or nullOptional title as sanitized HTML, or null.
disclosures.forThisWidget[].paragraphslist of objectParagraphs to show, in order.
disclosures.forThisWidget[].paragraphs[].textstringPlain-text paragraph, word-for-word from the estimator page.
disclosures.forThisWidget[].paragraphs[].htmlstringSame paragraph as sanitized HTML (only `<strong>`, `<b>`, `<em>`, `<sup>` and entities). Prefer this to keep the bold text and superscript markers.
disclosures.forThisWidget[].textstringHeading text.
disclosures.alllist of blocksThe estimator's complete disclosure footer (reference only).
disclosures.footnoteslist of objectEvery footnote marker and which disclosure explains it.
disclosures.footnotes[].markerstringFootnote marker as a plain character: `1`, `*`, `2`, `3`, `†` …
disclosures.footnotes[].displaystringHow the marker is printed: `¹`, `*`, `²`, `³`, `†` …
disclosures.footnotes[].disclosureIdstringId of the disclosure block that explains this marker.
disclosures.footnotes[].titlestring or nullTitle of that disclosure block, or null when it has none.
disclosures.footnotes[].appliesToThisWidgetbooleanTrue when the explaining block is part of `forThisWidget` (so it will be on your page).
disclosures.footnotes[].notestringExtra explanation. Present only on the `†` (interest-only) marker, which has no block of its own — it is explained inside the `disc-payments` section and in each term's `paymentNote`.
disclosures.notALenderstringThe "not a lender" statement on its own, for tight layouts.
disclosures.representativeExamplestringThe representative-example sentence on its own.
disclosures.rentToOwnStructuresstringWhich structures do not qualify for rent-to-own.
displayRuleslist of stringThe display rules, in plain English. Please follow them.

Questions

Tim Brazil, Lending Manager. Rates and rules are maintained on our side. When a lender changes terms, our estimator is updated, and this API and your widget pick up the change automatically.