ROI calculator
Enter what you invested and what came back: 1000 invested and 1200 returned is a net profit of 200.00 and an ROI of 20.00 %. Amounts are handled in exact cents, so no rounding drift creeps in. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Investment amount
- 1000
- Return amount
- 1200
- Investment amount
- 1000.00
- Return amount
- 1200.00
- Net profit
- 200.00
- Return on investment (%)
- 20.00
Enter the capital invested and the total amount returned to get net profit and ROI percent, computed in exact integer cents with half-up away-from-zero rounding to two decimals.
What ROI measures
Return on investment compares what an investment brought back with what it cost. Subtract the capital invested from the total amount returned to get the net profit, divide that profit by the capital invested and multiply by 100. Investing 1000 and getting back 1200 gives a net profit of 200.00 and an ROI of 20.00 %. A positive figure means the money grew, a negative one means part of it was lost, and getting nothing back is −100 %. Showing the percentage next to the net profit is a quick way to screen a deal.
Exact cents, predictable rounding
Amounts are converted to whole cents before any arithmetic, so money never picks up the tiny errors of binary fractions: 1000 and 1200 become 100000 and 120000 cents. The percentage is then rounded to two decimals, half up and away from zero, so a loss that falls exactly on a half rounds further from zero rather than toward it. That makes it easy to check a two-decimal, half-up ROI column in your own spreadsheet, line by line.
What you can do with it
Deal screening
Show ROI percent and net profit next to a simple capital outlay.
Spreadsheet validation
Check a two-decimal, half-up ROI column against your own sheet, server-side.
FAQ
Are floating-point numbers allowed?
No. Use a non-negative integer or a money string with at most two decimals.
How is the percent rounded?
Half-up away from zero to two decimals, computed entirely in integer cents.
What if I got back less than I invested?
Both the net profit and the ROI turn negative. Getting nothing back at all, a return of zero, gives an ROI of −100 %, which means the whole investment was lost.
Can the amount invested be zero?
No. The investment has to be more than zero, because the ROI is divided by it. The amount returned, on the other hand, may be zero to represent a total loss.
How many decimals can I enter?
Up to two, as in 1200.5 or 1200.50. A leading plus sign, padded zeros such as 01000, scientific notation or more than one decimal point are rejected as a wrong format.
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/roi \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"investment":"1000","return_amount":"1200"}'const res = await fetch("https://api.kit.forhosting.com/dev/roi", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"investment": "1000",
"return_amount": "1200"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/roi",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"investment": "1000",
"return_amount": "1200"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/roi", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"investment":"1000","return_amount":"1200"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"investment":"1000","return_amount":"1200"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/roi", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"investment": "1000",
"return_amount": "1200"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.roi",
"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
Formula and money parsing
dev.roi computes return on investment as (return_amount − investment) ÷ investment × 100, alongside the net_profit that drives it. To avoid binary floating-point drift on money, both inputs are parsed into integer cents with BigInt before any arithmetic: the example 1000 and 1200 become 100000 and 120000 cents, giving net_profit 200.00 and roi_percent 20.00. Each field accepts either a non-negative safe integer or a canonical decimal string with at most two fractional digits — "1200", "1200.5" and "1200.50" are all valid, but a leading plus sign, padded zeros like "01000", scientific notation, more than one decimal point, or a JavaScript float literal are all rejected as a bad format. investment must parse to more than zero cents so the division is defined; return_amount may be zero, which represents a total loss and yields a −100.00 percent.
Integer cents and half-up away from zero
The two hundredths that remain become the two decimal places of the percent string. roi_percent is never computed in floating point. Working entirely in BigInt, the engine forms profit_cents × 10000, then divides by investment_cents with an explicit half-up, away-from-zero step — it adds half the divisor before the integer division and mirrors the sign for losses, so a value at exactly −0.5 rounds to −1 rather than toward zero. When return_amount is below investment, both net_profit and roi_percent carry a leading minus: invest 1000, get back 800, and you see net_profit −200.00 with roi_percent −20.00.
Outputs, errors and where to run it
The design stays deliberately narrow — version one does not annualize, weight a portfolio, or convert currencies — so the signed surface is short and auditable. Every successful response echoes four two-decimal strings: investment and return_amount normalized to canonical form, net_profit with its sign, and roi_percent. Error paths use stable, matchable messages, each thrown as a typed invalid_input: a missing investment or return_amount, a zero investment, a negative value flagged as negativo ahead of the field name, and malformed money reported as an invalid format. Failed tasks are never billed against prepaid balance.
Integration use cases
CI golden tests
Pin exact net_profit and roi_percent strings that never drift across platforms.
Technical questions
Can investment be zero?
No. It must parse to more than zero cents, otherwise you get a typed invalid_input error.
Can ROI be negative?
Yes, when return_amount is below investment; both net_profit and the percent carry a minus.
Is it free in the browser?
Yes. The API costs $0.002 per call, billed only on successful tasks.