Annuity present value calculator
Twenty-four monthly payments of 500, discounted at 1% a month, are worth 10,621.69 today. Use it to turn a lease, a loan installment or a pension's checks into one lump sum you can compare. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Payment
- 500
- Rate per period
- 0.01
- Periods
- 24
- Present value
- 10,621.69
Use it to price a loan from its installment, value a lease, compare a pension's monthly checks against a buyout offer, or sanity-check the principal behind a financing quote — one deterministic call, no spreadsheet, no signup.
What the present value of an annuity actually is
An annuity is a stream of equal payments at regular intervals, and its present value is what that stream is worth today, once every payment has been discounted back at the interest rate per period. Receive 500 a month from now at 1% per month and that first payment is worth 500 divided by 1.01 today; the second is discounted by 1.01 squared, and so on until the last one, discounted by 1.01 to the power of the period count.
The closed-form formula, present value = payment x ((1 - (1 + r)^-n) / r), is exactly that sum of discounted payments collapsed into one expression, and it is the same formula behind mortgage pricing, lease valuation and every finance textbook's time-value-of-money chapter. Because the rate is expressed per period, the calculation works for any cadence: a monthly rate with monthly payments, an annual rate with annual payments, or any other consistent pair. What matters is consistency — the rate and the period count must describe the same interval.
Send an annual rate with a monthly payment count and the valuation will be wrong by construction, and no calculator can rescue mismatched units. Keep the two aligned and the result is exact, deterministic and reproducible on any machine, which is why the same computation runs identically in your browser and on our edge.
How to use it well and what it does not do
Typical uses fall into three patterns. Finance and procurement teams value leases and subscription contracts with it: a fixed periodic fee over a fixed term becomes a single comparable lump sum. And product teams embed it behind their own pricing calculators so the discounting math is maintained in one place instead of being re-implemented — often incorrectly — in every frontend.
And it models a constant rate with no fees, taxes, inflation or payment changes. When your case fits the plain discounting model, this is the right tool; when it does not, compute the baseline here and layer the extras on top in your own code.
What you can do with it
Price a loan from its installment
Derive the principal a fixed monthly payment supports at a given periodic rate, before the borrower commits to the financing.
Value a lease or subscription
Turn a stream of equal periodic fees over a fixed term into one lump-sum value for comparison against an upfront price.
Compare a pension against a buyout
Discount a series of equal monthly checks to today's value and set it against a lump-sum buyout offer on equal terms.
FAQ
Is the rate a percentage or a decimal?
A decimal per period: 0.01 means 1% per period. Divide an annual percentage by 100 and then by the number of periods per year.
What happens with a 0% rate?
It is supported: the present value is simply the payment multiplied by the number of periods, which is the exact limit of the formula at zero interest.
Does it return the period-by-period amortization table?
No. It returns the discounted lump sum only; the per-period breakdown is a separate capability.
Is it an annuity due or an ordinary annuity?
An ordinary annuity: payments are assumed at the end of each period. For an annuity due, multiply the result by (1 + rate) on your side.
How do I compare a pension's monthly checks with a lump-sum buyout?
Enter the monthly check, a monthly rate and the number of checks; the result is what that stream is worth today. If the buyout offer is higher, the lump sum is worth more at that rate.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/fin/annuity-present-value \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"payment":500,"rate_per_period":0.01,"periods":24}'const res = await fetch("https://api.kit.forhosting.com/fin/annuity-present-value", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"payment": 500,
"rate_per_period": 0.01,
"periods": 24
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/fin/annuity-present-value",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"payment": 500,
"rate_per_period": 0.01,
"periods": 24
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/fin/annuity-present-value", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"payment":500,"rate_per_period":0.01,"periods":24}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"payment":500,"rate_per_period":0.01,"periods":24}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/fin/annuity-present-value", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"payment": 500,
"rate_per_period": 0.01,
"periods": 24
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "fin.annuity_present_value",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_periods | 1200 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
The annuity present value API answers the discounting question in finance: if you receive the same amount at the end of every period and money earns a fixed interest rate per period, what lump sum today is that stream worth? It applies the closed-form discounting formula and returns a single number, the present value, in the same currency unit as your payment.
Inputs, units and edge cases
The payment is the amount received at the end of each period — a loan installment, a lease payment, a pension check — and it must be positive. Two edge cases are handled deliberately. And the returned present value is rounded to two decimals — cents — so the response is byte-for-byte stable between runs and between machines. The endpoint takes three numbers. The rate per period is a decimal, so 1% per month is 0.01, not 1 and not 0.01% — and it must be non-negative; a negative rate is rejected with an invalid_input error and is never charged. The periods field is the number of payments and must be a positive integer up to 1200, which comfortably covers a hundred years of monthly payments; zero, a negative count or a non-integer is meaningless here and is rejected with invalid_input. A zero rate is legal and means no discounting at all: the present value is exactly the payment multiplied by the number of periods, which is the correct mathematical limit of the formula as the rate approaches zero, so the endpoint returns it directly rather than failing on a division by zero.
How to use it well and what it does not do
It is worth being clear about what the endpoint deliberately leaves out. It returns the present value only; it does not produce the period-by-period amortization table with the split between principal and interest. It assumes an ordinary annuity, meaning payments land at the end of each period; an annuity due, where payments come at the start, is worth one extra factor of (1 + r) more. Those omissions are what keep it fast, cheap at $0.002 per request, and exactly predictable.
Technical questions
What does it cost?
$0.002 per request via the API. It is also free to run in your browser on this page.
What if the number of periods is zero or negative?
The request fails with an invalid_input error and is not charged — a non-positive number of periods has no meaning in this model.