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.

Base URL https://api.dharun.devNo key needed for most600 units a minute, 3000 with a free keyThis page as Markdown

SIP returns

GET/v1/calc/sip

What a monthly investment grows to, year by year, with an optional yearly step-up of the amount.

ParameterDescription
monthlyquery, requiredMonthly amount.
ratequery, requiredExpected return, percent a year.
yearsquery, required1 to 60.
stepupqueryYearly 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

ParameterDescription
amountquery, requiredAmount invested once.
ratequery, requiredExpected return, percent a year.
yearsquery, required1 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.

ParameterDescription
amountquery, requiredLoan amount.
ratequery, requiredInterest, percent a year.
yearsqueryTerm in years (or give months).
monthsqueryTerm in months, 1 to 600.
schedulequerytrue 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.

ParameterDescription
amountquery, requiredThe amount.
ratequery, requiredGST rate: 0, 0.1, 0.25, 1.5, 3, 5, 12, 18, 28 or 40.
inclusivequerytrue when the amount already includes GST.
interstatequerytrue 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.

ParameterDescription
incomequery, requiredGross total income for the year, before the standard deduction.
yearqueryFinancial year. Default the newest. One of: 2026-27, 2025-26.
regimequeryDefault both. One of: both, new, old.
agequeryChanges the old regime's exemption limit. Default below60. One of: below60, 60to80, 80plus.
salariedquerySalary or pension, so the standard deduction applies. Default true.
deductionsqueryOld 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).

ParameterDescription
basicquery, requiredBasic pay plus dearness allowance.
hraquery, requiredHRA received.
rentquery, requiredRent paid.
metroquerytrue 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

ParameterDescription
salaryquery, requiredLast monthly basic pay plus dearness allowance.
yearsquery, requiredYears of service; 10.6 is ten years and about seven months.
coveredqueryCovered 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

ParameterDescription
yearlyquery, requiredYearly deposit, 500 to 1,50,000.
yearsquery15, or 15 plus blocks of 5. Default 15.
ratequeryInterest, 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.

ParameterDescription
assetquery, requiredWhat was sold. One of: equity, equity-fund, debt-fund, property, gold, other.
boughtquery, requiredPurchase date, YYYY-MM-DD.
soldquery, requiredSale date, from 2024-07-23.
costquery, requiredPurchase cost with improvement costs.
pricequery, requiredSale price.
expensesqueryCosts 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."
  }
}

Share trade charges

GET/v1/calc/trade

Every charge on buying and selling an NSE share (STT, exchange charges, SEBI fee, stamp duty, GST), the net profit and the move needed to break even.

ParameterDescription
buyquery, requiredBuy price per share.
sellquery, requiredSell price per share.
quantityquery, requiredShares.
kindqueryDefault delivery. One of: delivery, intraday.
brokeragequeryYour broker's charge per order, in rupees.
dpqueryDepository charge on a delivery sale.

curl

curl "https://api.dharun.dev/v1/calc/trade?buy=1000&sell=1100&quantity=100&kind=delivery&brokerage=20&utm_medium=docs"

JavaScript

const response = await fetch("https://api.dharun.dev/v1/calc/trade?buy=1000&sell=1100&quantity=100&kind=delivery&brokerage=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/trade?buy=1000&sell=1100&quantity=100&kind=delivery&brokerage=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, with lists and long text shortened

{
  "data": {
    "turnover": 210000,
    "charges": {
      "brokerage": 40,
      "dp": 0,
      "exchange": 6.24,
      "gst": 8.36,
      "sebi": 0.21,
      "stampDuty": 15,
      "stt": 210
    },
    "totalCharges": 279.81,
    "grossProfit": 10000,
    "netProfit": 9720.19,
    "breakevenPoints": 2.8,
    "rule": "NSE equity charges from 1 October 2024: STT, NSE transaction charges 0.00297%, SEBI fee 10 rupees a crore, stamp duty on the buy, and 18% GST on brokerage and t…"
  },
  "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.