Docs / Money and business
Money calculators API
SIP, EMI, GST, income tax, HRA, gratuity, PPF, capital gains and trade charges.
Indian money sums with the rules written in: each answer names the rule and the year it used. Income tax knows the financial years 2026-27 and 2025-26, both regimes. For planning: not tax or financial advice. Amounts are in rupees; commas are allowed.
https://api.dharun.devNo key needed for most600 units a minute, 3000 with a free keyThis page as MarkdownSIP returns
GET/v1/calc/sip
What a monthly investment grows to, year by year, with an optional yearly step-up of the amount.
| Parameter | Description |
|---|---|
monthlyquery, required | Monthly amount. |
ratequery, required | Expected return, percent a year. |
yearsquery, required | 1 to 60. |
stepupquery | Yearly increase of the monthly amount, percent. |
curl
curl "https://api.dharun.dev/v1/calc/sip?monthly=10000&rate=12&years=10&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/calc/sip?monthly=10000&rate=12&years=10&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/calc/sip?monthly=10000&rate=12&years=10&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response, with lists and long text shortened
{
"data": {
"invested": 1200000,
"value": 2323390.76,
"gain": 1123390.76,
"years": [
{
"year": 1,
"monthly": 10000,
"invested": 120000,
"value": 128093.28
},
{
"year": 2,
"monthly": 10000,
"invested": 240000,
"value": 272432
},
{
"year": 3,
"monthly": 10000,
"invested": 360000,
"value": 435076.47
}
],
"rule": "Each instalment is invested at the start of the month and grows at the yearly return divided by 12, compounded monthly.",
"inputs": {
"monthly": 10000,
"returnPercent": 12,
"years": 10,
"stepUpPercent": 0
}
},
"meta": {
"note": "A calculation from the rules named in rule, for planning. It is not tax or financial advice; check figures that matter with the source or an adviser."
}
}Lump sum growth
GET/v1/calc/lumpsum
| Parameter | Description |
|---|---|
amountquery, required | Amount invested once. |
ratequery, required | Expected return, percent a year. |
yearsquery, required | 1 to 60. |
curl
curl "https://api.dharun.dev/v1/calc/lumpsum?amount=100000&rate=10&years=10&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/calc/lumpsum?amount=100000&rate=10&years=10&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/calc/lumpsum?amount=100000&rate=10&years=10&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response
{
"data": {
"invested": 100000,
"value": 259374.25,
"gain": 159374.25,
"rule": "Compounded once a year."
},
"meta": {
"note": "A calculation from the rules named in rule, for planning. It is not tax or financial advice; check figures that matter with the source or an adviser."
}
}Loan EMI and schedule
GET/v1/calc/emi
The monthly instalment of a reducing-balance loan, the total interest and, with schedule=true, every month's split of interest and principal.
| Parameter | Description |
|---|---|
amountquery, required | Loan amount. |
ratequery, required | Interest, percent a year. |
yearsquery | Term in years (or give months). |
monthsquery | Term in months, 1 to 600. |
schedulequery | true adds the month-by-month schedule. |
curl
curl "https://api.dharun.dev/v1/calc/emi?amount=1000000&rate=8.5&years=20&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/calc/emi?amount=1000000&rate=8.5&years=20&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/calc/emi?amount=1000000&rate=8.5&years=20&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response
{
"data": {
"emi": 8678.23,
"totalInterest": 1082775.76,
"totalPaid": 2082775.76,
"rule": "Reducing balance, interest charged monthly at the yearly rate divided by 12."
},
"meta": {
"note": "A calculation from the rules named in rule, for planning. It is not tax or financial advice; check figures that matter with the source or an adviser."
}
}GST split
GET/v1/calc/gst
Adds GST to an amount, or takes it out of one that includes it, split into CGST and SGST within a state or IGST between states.
| Parameter | Description |
|---|---|
amountquery, required | The amount. |
ratequery, required | GST rate: 0, 0.1, 0.25, 1.5, 3, 5, 12, 18, 28 or 40. |
inclusivequery | true when the amount already includes GST. |
interstatequery | true for a supply between states (IGST). |
curl
curl "https://api.dharun.dev/v1/calc/gst?amount=1180&rate=18&inclusive=true&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/calc/gst?amount=1180&rate=18&inclusive=true&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/calc/gst?amount=1180&rate=18&inclusive=true&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response
{
"data": {
"taxable": 1000,
"rate": 18,
"tax": 180,
"cgst": 90,
"sgst": 90,
"total": 1180,
"interstate": false,
"rule": "Within a state the tax is charged as CGST and SGST, half each; between states, or on imports, as IGST."
},
"meta": {
"note": "A calculation from the rules named in rule, for planning. It is not tax or financial advice; check figures that matter with the source or an adviser."
}
}Income tax, old and new regime
GET/v1/calc/income-tax
Tax on a year's income under the new regime (section 115BAC) and the old one, with the section 87A rebate, surcharge, marginal relief and 4% cess, slab by slab, and which regime costs less. Special-rate income such as capital gains is not included.
| Parameter | Description |
|---|---|
incomequery, required | Gross total income for the year, before the standard deduction. |
yearquery | Financial year. Default the newest. One of: 2026-27, 2025-26. |
regimequery | Default both. One of: both, new, old. |
agequery | Changes the old regime's exemption limit. Default below60. One of: below60, 60to80, 80plus. |
salariedquery | Salary or pension, so the standard deduction applies. Default true. |
deductionsquery | Old regime deductions and exemptions in all (80C, 80D, HRA, home loan interest...). |
curl
curl "https://api.dharun.dev/v1/calc/income-tax?income=1500000&year=2025-26&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/calc/income-tax?income=1500000&year=2025-26&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/calc/income-tax?income=1500000&year=2025-26&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response, with lists and long text shortened
{
"data": {
"year": "2025-26",
"new": {
"regime": "new",
"taxableIncome": 1425000,
"standardDeduction": 75000,
"deductions": 0,
"slabs": [
{
"from": 0,
"to": 400000,
"rate": 0,
"amount": 400000,
"tax": 0
},
{
"from": 400000,
"to": 800000,
"rate": 5,
"amount": 400000,
"tax": 20000
},
{
"from": 800000,
"to": 1200000,
"rate": 10,
"amount": 400000,
"tax": 40000
}
],
"taxOnIncome": 93750,
"rebate87A": 0,
"surcharge": 0,
"cess": 3750,
"total": 97500,
"perMonth": 8125,
"effectiveRatePercent": 6.5,
"marginalRelief": false
},
"old": {
"regime": "old",
"taxableIncome": 1450000,
"standardDeduction": 50000,
"deductions": 0,
"slabs": [
{
"from": 0,
"to": 250000,
"rate": 0,
"amount": 250000,
"tax": 0
},
{
"from": 250000,
"to": 500000,
"rate": 5,
"amount": 250000,
"tax": 12500
},
{
"from": 500000,
"to": 1000000,
"rate": 20,
"amount": 500000,
"tax": 100000
}
],
"taxOnIncome": 247500,
"rebate87A": 0,
"surcharge": 0,
"cess": 9900,
"total": 257400,
"perMonth": 21450,
"effectiveRatePercent": 17.16,
"marginalRelief": false
},
"better": "new",
"saves": 159900,
"rule": "Section 115BAC (new regime) and the slabs of the Finance Act (old regime) for the financial year 2025-26; rebate under section 87A with marginal relief; surchar…",
"inputs": {
"income": 1500000,
"year": "2025-26",
"age": "below60",
"salaried": true,
"deductions": 0
}
},
"meta": {
"note": "A calculation from the rules named in rule, for planning. It is not tax or financial advice; check figures that matter with the source or an adviser."
}
}HRA exemption
GET/v1/calc/hra
The tax-free part of house rent allowance under section 10(13A). Give every amount for the same period (a month or a year).
| Parameter | Description |
|---|---|
basicquery, required | Basic pay plus dearness allowance. |
hraquery, required | HRA received. |
rentquery, required | Rent paid. |
metroquery | true in Delhi, Mumbai, Kolkata or Chennai. |
curl
curl "https://api.dharun.dev/v1/calc/hra?basic=50000&hra=25000&rent=20000&metro=true&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/calc/hra?basic=50000&hra=25000&rent=20000&metro=true&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/calc/hra?basic=50000&hra=25000&rent=20000&metro=true&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response, with lists and long text shortened
{
"data": {
"exempt": 15000,
"taxable": 10000,
"limits": [
25000,
15000,
25000
],
"rule": "Section 10(13A) and rule 2A: the least of the HRA received, rent paid less 10% of salary, and 50% of salary in Delhi, Mumbai, Kolkata or Chennai (40% elsewhere)…"
},
"meta": {
"note": "A calculation from the rules named in rule, for planning. It is not tax or financial advice; check figures that matter with the source or an adviser."
}
}Gratuity
GET/v1/calc/gratuity
| Parameter | Description |
|---|---|
salaryquery, required | Last monthly basic pay plus dearness allowance. |
yearsquery, required | Years of service; 10.6 is ten years and about seven months. |
coveredquery | Covered by the Payment of Gratuity Act. Default true. |
curl
curl "https://api.dharun.dev/v1/calc/gratuity?salary=52000&years=10.6&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/calc/gratuity?salary=52000&years=10.6&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/calc/gratuity?salary=52000&years=10.6&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response, with lists and long text shortened
{
"data": {
"amount": 330000,
"yearsCounted": 11,
"taxFree": 330000,
"taxable": 0,
"eligible": true,
"rule": "Payment of Gratuity Act, section 4: 15 days' wages (basic pay and dearness allowance, the month taken as 26 days) for each completed year of service; more than …"
},
"meta": {
"note": "A calculation from the rules named in rule, for planning. It is not tax or financial advice; check figures that matter with the source or an adviser."
}
}PPF maturity
GET/v1/calc/ppf
| Parameter | Description |
|---|---|
yearlyquery, required | Yearly deposit, 500 to 1,50,000. |
yearsquery | 15, or 15 plus blocks of 5. Default 15. |
ratequery | Interest, percent a year. Default the current rate. |
curl
curl "https://api.dharun.dev/v1/calc/ppf?yearly=150000&years=15&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/calc/ppf?yearly=150000&years=15&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/calc/ppf?yearly=150000&years=15&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response, with lists and long text shortened
{
"data": {
"deposited": 2250000,
"interest": 1818209,
"maturity": 4068209,
"years": [
{
"year": 1,
"interest": 10650,
"balance": 160650
},
{
"year": 2,
"interest": 22056,
"balance": 332706
},
{
"year": 3,
"interest": 34272,
"balance": 516978
}
],
"rule": "Deposits made by 5 April each year earn interest for the whole year, compounded yearly at 7.1%. The rate is set every quarter; 7.1% is the current one."
},
"meta": {
"note": "A calculation from the rules named in rule, for planning. It is not tax or financial advice; check figures that matter with the source or an adviser."
}
}Capital gains tax
GET/v1/calc/capital-gains
Short or long term, and the tax at the rates for sales from 23 July 2024: shares and equity funds, debt funds, property (with the indexation choice for land and buildings bought before that date), gold and other assets.
| Parameter | Description |
|---|---|
assetquery, required | What was sold. One of: equity, equity-fund, debt-fund, property, gold, other. |
boughtquery, required | Purchase date, YYYY-MM-DD. |
soldquery, required | Sale date, from 2024-07-23. |
costquery, required | Purchase cost with improvement costs. |
pricequery, required | Sale price. |
expensesquery | Costs of the sale. |
curl
curl "https://api.dharun.dev/v1/calc/capital-gains?asset=equity&bought=2023-01-10&sold=2025-01-10&cost=100000&price=400000&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/calc/capital-gains?asset=equity&bought=2023-01-10&sold=2025-01-10&cost=100000&price=400000&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/calc/capital-gains?asset=equity&bought=2023-01-10&sold=2025-01-10&cost=100000&price=400000&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response, with lists and long text shortened
{
"data": {
"term": "long",
"gain": 300000,
"ratePercent": 12.5,
"exemption": 125000,
"tax": 21875,
"cess": 875,
"total": 22750,
"rule": "Section 112A: listed shares and equity funds held over 12 months, with securities transaction tax paid. 12.5% on gains above 1.25 lakh a year (the exemption is …"
},
"meta": {
"note": "A calculation from the rules named in rule, for planning. It is not tax or financial advice; check figures that matter with the source or an adviser."
}
}Using an AI assistant? Connect the MCP server and it can call this API by itself. Want every endpoint on one bench? Open the playground.