VAT calculator
100 at 21% becomes 121, with 21 of tax, and 121 at 21% goes back to 100: add tax to a net price or extract it from a total that already includes it, and always get net, tax and gross. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Calculation mode
- Add tax
- Amount
- 100
- Tax rate
- 21
- Net amount
- 100
- Tax amount
- 21
- Gross amount
- 121
Returns net, tax and gross.
Adding tax and taking it back out
Adding tax treats the amount you enter as the net price. The tax is the net times the rate, and the gross is the net plus the tax, so 100 at 21% gives 21 of tax and 121 in total. The rate is written as a plain percentage: 21 means 21%. Extracting works the other way round. It treats the amount as a tax-inclusive gross, divides it by one plus the rate to find the net, and takes the difference as the tax, so 121 at 21% recovers 100 and 21. That is what you need to back out the tax from a receipt total or a gross invoice line. A rate of zero is allowed and simply gives zero tax.
Rounding and the classic mistake
The most common error is subtracting the rate from the gross total. Because the rate applies to the net price, that removes too much; dividing by one plus the rate is the correct inverse. Rounding is the second trap. Here the three figures are rounded separately: when adding, the tax is computed from the rounded net and the gross is rounded afterwards, so every line stays self-consistent for accounting instead of being derived from a hidden fraction. Without that, net plus tax can disagree with gross by a cent at unusual rates. You can choose from 0 to 8 decimals, more for currencies or unit prices that need them, or 0 for whole units.
Add versus extract
The rate field is a percentage (21 means 21%) converted internally to r = rate / 100. Extract is the inverse of add and is what you use to back out the tax portion of a receipt total or a gross invoice line. Every branch returns the full triple of net, tax and gross plus the mode and rate you supplied.
Rounding each component independently
Because the three components are rounded separately, add computes tax from the rounded net and then rounds gross, which keeps each line self-consistent for accounting rather than derived from an unrounded intermediate. This matters at higher precision or unusual rates where a single hidden fraction could otherwise make net plus tax appear to disagree with gross by a cent. Choose more decimals for currencies or unit prices that need them, or 0 for whole-unit display.
FAQ
What is the difference between add and extract?
add treats amount as net and puts tax on top (gross = net + tax). extract treats amount as tax-inclusive gross and backs out net = gross / (1 + rate/100) and the contained tax.
How is the rate given?
As a percentage number, so 21 means 21%. It must be finite and not negative; zero is allowed and yields zero tax.
How are amounts rounded?
net, tax and gross are each rounded half-up independently to the decimals you set (0 to 8, default 2), so lines stay self-consistent.
How do I add 21% VAT to a price?
Choose to add tax and enter the net price and the rate as a percentage, 21 for 21%. A net price of 100 gives 21 of tax and a gross total of 121.
Why can't I just subtract 21% from a total that includes VAT?
Because the rate applies to the net price, not to the total. Taking 21% of 121 removes more than the 21 of tax it actually contains; dividing 121 by 1.21 gives the correct net of 100.
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/dev/vat-calculator \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"mode":"add","amount":100,"rate":21}'const res = await fetch("https://api.kit.forhosting.com/dev/vat-calculator", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"mode": "add",
"amount": 100,
"rate": 21
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/vat-calculator",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"mode": "add",
"amount": 100,
"rate": 21
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/vat-calculator", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"mode":"add","amount":100,"rate":21}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"mode":"add","amount":100,"rate":21}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/vat-calculator", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"mode": "add",
"amount": 100,
"rate": 21
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.vat_calculator",
"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.
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
Computes value-added or sales tax two ways. mode=add treats the amount as net and adds a percentage rate on top; mode=extract treats the amount as tax-inclusive gross and works out the net and the tax already contained.
Add versus extract
In mode=add the amount is the net price: net equals amount, tax equals net times r, and gross equals net plus tax, so 100 at 21% returns net 100, tax 21, gross 121. In mode=extract the amount is the tax-inclusive gross: net equals gross divided by (1 + r), and tax equals gross minus net, so 121 at 21% recovers net 100 and tax 21.
Ranges, validation and typed errors
mode, amount and rate are all required. mode must be exactly add or extract. amount and rate must each be a finite number that is not negative, and their magnitudes are capped at 1e12 to keep results meaningful; a zero rate is allowed and simply yields zero tax. decimals must be an integer within 0..8. Any violation, or a non-object input, throws a typed invalid_input error naming the problem instead of an untyped crash, and extract guards against a rate of -100% that would make 1 + r zero.
Integration use cases
Pricing with tax on top
Use mode=add to turn a net catalog price into a customer-facing gross price at your local VAT or sales-tax rate.
Reconciling receipts and invoices
Use mode=extract to split a tax-inclusive total into its net and tax parts for bookkeeping and returns.
Checkout and invoicing systems
Call the API to compute net, tax and gross consistently across an e-commerce cart or billing pipeline at any rate.
Technical questions
What triggers an error?
A typed invalid_input error for a bad mode, a negative or non-finite amount or rate, magnitudes over 1e12, decimals outside 0..8, or a -100% rate in extract.
Is it free and what does the API cost?
The browser widget is free; the API uses prepaid KIT balance from $0.002, and failed tasks are not charged.