I kept seeing refinance calculators that only divide closing costs by the monthly payment drop. That is a fine first guess, but it skips how fast each loan pays down principal. Two loans with the same rate cut can look identical on a napkin and diverge by thousands once you track what is still owed.
So I started calling a single REST endpoint that returns both the simple break-even and a full-cost one, plus a year-by-year advantage table. While I was there I also pulled the monthly payment itself and a "how much house can I afford" check. Every request and response below was captured from https://api.freedailypro.com on 6 Nov 2026. Only the API key has been removed.
Why the napkin math lies
Take a $300k balance at 7% with 28 years left, refinanced to 6% over 30 years with $5,000 in closing costs paid in cash. The payment falls from $2,038.83 to $1,798.65 — a $240.17 monthly saving. Closing costs ÷ saving ≈ 20.8 months, so "month 21" sounds right.
What that skips: the new loan is longer, so early on you owe a different balance than you would have kept on the old one. The full-cost break-even folds that balance difference in. For this scenario both land on month 21, and by year 2 you are about $942 ahead. Stretch the new term far enough, or roll closing costs into the loan, and the two answers stop agreeing — which is exactly when you want structured JSON instead of a spreadsheet you rebuilt at midnight.
Step 1: Get a key
Sign in with Google on the developers page and create an API key. Put it in an X-API-Key header. A trial plan with 20,000 calls a month comes with it; the same key covers the REST endpoints and the MCP tools if you ever need those. Files and text are processed in memory and nothing you send is stored.
Step 2: Monthly payment (the building block)
Before refinance math, you need a payment you trust. Standard amortization:
M = P * i / (1 - (1+i)^(-n))
where P is the loan, i is the monthly rate, and n is the number of payments. For a $400,000 home with 20% down ($320,000 loan) at 6.5% for 30 years, that is $2,022.62 principal and interest.
curl -s https://api.freedailypro.com/v1/converters/mortgage \
-H "Content-Type: application/json" \
-H "X-API-Key: $FDP_API_KEY" \
-d '{
"homePrice": 400000,
"downPaymentPct": 20,
"ratePct": 6.5,
"years": 30
}'
Trimmed response:
{
"result": {
"loanAmount": 320000,
"downPaymentPct": 20,
"loanToValuePct": 80,
"monthly": {
"principalAndInterest": 2022.62,
"propertyTax": 0,
"homeInsurance": 0,
"hoa": 0,
"mortgageInsurance": 0,
"total": 2022.62
},
"payoff": {
"payments": 360,
"totalInterest": 408142.36,
"totalPaidToLender": 728142.36
},
"comparison": {
"shortYears": 15,
"short": { "payment": 2787.54, "totalInterest": 181757.84 },
"long": { "payment": 2022.62, "totalInterest": 408142.36 },
"interestDifference": 226384.52
}
}
}
I checked this by hand with the formula above: $2,022.62 and $408,142.36 of interest over the life of the loan. Match to the cent. The same endpoint accepts property tax, insurance, HOA, PMI, FHA/VA/USDA loan types, extra payments and a biweekly plan when you need the all-in housing number — not only P&I.
Step 3: Refinance break-even as one POST
Here is the scenario from the intro:
curl -s https://api.freedailypro.com/v1/converters/refinance \
-H "Content-Type: application/json" \
-H "X-API-Key: $FDP_API_KEY" \
-d '{
"currentBalance": 300000,
"currentRatePct": 7,
"remainingYears": 28,
"newRatePct": 6,
"newTermYears": 30,
"closingCosts": 5000,
"plannedYearsToKeep": 5
}'
Trimmed response:
{
"result": {
"current": {
"balance": 300000,
"ratePct": 7,
"payment": 2038.83,
"paymentsLeft": 336
},
"refinanced": {
"loanAmount": 300000,
"ratePct": 6,
"termMonths": 360,
"payment": 1798.65,
"closingCosts": 5000,
"closingCostsFinanced": false
},
"monthlySaving": 240.17,
"simpleBreakEvenMonths": 21,
"fullCostBreakEvenMonth": 21,
"interestDifferenceOverLife": 37530.92,
"horizonTable": [
{ "years": 1, "netAdvantage": -2013.17 },
{ "years": 2, "netAdvantage": 942.13 },
{ "years": 3, "netAdvantage": 3861.22 },
{ "years": 5, "netAdvantage": 9569.51 }
],
"atPlannedHorizon": {
"years": 5,
"netAdvantage": 9569.51,
"worthIt": true
},
"verdict": "Pays back after 21 months (1.75 years) counting payments, closing costs and what is still owed; worth it only if you keep the loan longer than that.",
"notes": [
"The new term (360 payments) is longer than what is left on the current loan (336), so part of the lower payment comes from stretching the loan. Compare total interest, not only the payment."
]
}
}
Two things I like here:
-
Simple vs full-cost break-even. Simple is
closingCosts / monthlySaving. Full-cost is the first month where payments saved − cash closing costs + (old remaining balance − new remaining balance) turns non-negative. Same month in this example; not always. - The horizon table. Year 1 you are still about $2,013 behind. Year 2 you flip to +$942. If you only plan to keep the house two more years, that table matters more than the monthly saving alone.
The response also flags when a lower payment is partly from stretching the term — a note I wish more consumer calculators printed in bold.
Step 4: Affordability with 28/36 (and the 31/43 stretch)
Payment math answers "what do I owe." Affordability answers "what can I buy" from income and other debts. The common guideline is 28% of gross income on housing and 36% on all debts; FHA's manual-underwriting benchmark stretches that to 31/43.
curl -s https://api.freedailypro.com/v1/converters/affordability \
-H "Content-Type: application/json" \
-H "X-API-Key: $FDP_API_KEY" \
-d '{
"annualIncome": 120000,
"otherMonthlyDebts": 500,
"downPayment": 60000,
"ratePct": 6.5
}'
Trimmed response:
{
"result": {
"grossMonthlyIncome": 10000,
"otherMonthlyDebts": 500,
"guideline": {
"frontLimitPct": 28,
"backLimitPct": 36,
"maxHousingPayment": 2800,
"binding": "housing ratio (front end)",
"maxHomePrice": 414772,
"loanAmount": 354772,
"monthly": {
"principalAndInterest": 2242.4,
"propertyTax": 380.21,
"mortgageInsurance": 177.39,
"total": 2799.99
},
"resultingBackEndPct": 33
},
"stretch": {
"frontLimitPct": 31,
"backLimitPct": 43,
"maxHousingPayment": 3100,
"maxHomePrice": 453545,
"loanAmount": 393545
}
}
}
Hand check: front-end cap is $2,800; back-end cap is $3,600 − $500 = $3,100, so the front end binds. Solving for the highest price whose P&I + default 1.1% property tax + default PMI fit $2,800 gives $414,772. The stretch case lands at $453,545. Both matched the live response.
Notice PMI shows up once loan-to-value is above 80%. Drop that out of a DIY sheet and you overstate the house someone can buy.
Drop-in JavaScript
Same refinance call with fetch. Swap in your key (or read it from an env var on the server — never ship it to the browser):
const res = await fetch("https://api.freedailypro.com/v1/converters/refinance", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.FDP_API_KEY, // YOUR_API_KEY
},
body: JSON.stringify({
currentBalance: 300000,
currentRatePct: 7,
remainingYears: 28,
newRatePct: 6,
newTermYears: 30,
closingCosts: 5000,
plannedYearsToKeep: 5,
}),
});
const { result } = await res.json();
console.log(
`Save $${result.monthlySaving}/mo; break-even month ${result.fullCostBreakEvenMonth};`,
`year-2 advantage $${result.horizonTable[1].netAdvantage}`
);
// Save $240.17/mo; break-even month 21; year-2 advantage $942.13
Rate-limit headers come back on every response (x-ratelimit-limit, x-ratelimit-remaining), so you can show quota without a second round-trip.
Where this fits
These three routes live on the same FreeDailyPro API as 200+ other endpoints — PDF, media, text utilities, more finance calculators. I am only covering the mortgage set here because that is what I verified live for this post. Docs, OpenAPI and a Postman collection are linked from the developers page; plan details are on pricing.
One disclaimer that belongs next to any housing number: these are estimates from the inputs you send. Lenders apply their own overlays, credit rules and fee quotes. Confirm with the lender or a qualified adviser before you refinance or make an offer.
Wrapping up
The pattern I wanted was boring on purpose: one POST, structured JSON, both the simple answer and the one that accounts for remaining balances. Once that exists, an agent or a backend can stop reinventing amortization every time a user asks "is this refinance worth it?"
What edge cases would you want covered next — ARMs, discount points, cash-out refinance, or a side-by-side of keeping the current loan vs. refinancing to a shorter term? Tell me in the comments; that feedback goes straight into what gets built next.
Top comments (0)