Zero-Based Budget Calculator
A zero-based budget gives every dollar of monthly take-home income a specific job before the month begins.
Run — free
Enter your income and planned category amounts to see whether the plan reaches exactly zero, leaves money unassigned, or allocates more than you earn. The calculator totals the plan with currency-safe arithmetic, reports the precise difference, and shows each category as a percentage of income so you can review the balance at a glance.
Start with income you can actually allocate
Use monthly take-home income: the money that reaches your accounts after taxes, payroll deductions, and other amounts you cannot direct. If income changes from month to month, choose a conservative amount you reasonably expect to receive, or create a separate plan for each likely scenario. Then list every destination for that money. Categories can include housing, utilities, groceries, transport, insurance, debt payments, savings, investing, charitable giving, entertainment, and a small buffer for irregular expenses. A zero-based plan does not mean spending everything on immediate consumption. Savings, emergency funds, sinking funds, and extra debt payments are valid jobs for money. The goal is simply to make the full income intentional. Enter each amount with no more than two decimal places. Category names must be unique, which prevents an accidental duplicate from hiding in a long plan. Once entered, the calculator compares the category total directly with income and identifies the remaining direction and amount.
Read the balance and correct the plan
A balanced result means total allocations equal monthly income exactly, so the difference is zero and the plan satisfies the zero-based rule. An unassigned result means income is greater than the amounts given to categories. That difference is still available and needs a job: you might add it to emergency savings, increase a sinking fund, accelerate debt repayment, or deliberately expand another category. An over-budgeted result means planned allocations exceed income. The reported difference is negative, clearly showing how far the plan must be reduced. Review flexible categories first, but do not mistake the calculator for a recommendation to cut necessities. The category breakdown also reports each amount as a percentage of income. Percentages help reveal the structure of the plan, while the currency difference remains the decisive balancing figure. When income is zero, percentages are reported as zero rather than producing an undefined value. Adjust entries and calculate again until the status is balanced and the difference is exactly zero.
Use the result as a monthly planning checkpoint
Run the calculator when building a new monthly budget, after income changes, and whenever a major bill alters the plan. The result is a planning snapshot, not a transaction ledger: it checks the amounts you intend to allocate but does not track bank balances or actual spending during the month. Keep planned categories aligned with the system you use to monitor real expenses, and revisit the plan when circumstances change. Irregular costs are easier to manage when converted into monthly sinking-fund contributions. For example, divide an annual insurance bill or expected repair cost across the months remaining and assign that contribution as its own category. Couples or households can agree on the income figure and category list before using the result as a shared checkpoint. Because the algorithm is deterministic and uses integer cents internally, the same input always produces the same total and avoids common binary floating-point surprises. It uses no network connection, random values, or current date, making it suitable for repeatable browser and API workflows.
What you can do with it
Build a first zero-based plan
Assign take-home pay across bills, daily needs, goals, and savings, then confirm that the remaining balance is exactly zero.
Rebalance after an income change
Update monthly income and see precisely how much must be assigned or removed from the existing category plan.
Check a household budget
Review category percentages together and catch a missing allocation or an overcommitted plan before the month starts.
FAQ
What does the calculator cost?
It is free to run in your browser on this page, or $0.002 per API request.
Does zero-based budgeting mean I must spend all my income?
No. Savings, investments, sinking funds, and extra debt payments are categories, so money assigned to them is not unplanned spending.
What does an unassigned status mean?
Your category total is below income. The positive difference is money that still needs a category before the budget reaches zero.
What does an over-budgeted status mean?
Your planned categories total more than monthly income. The negative difference shows the exact amount that must be removed or covered.
Which income figure should I enter?
Use the monthly take-home income available for you to allocate, after taxes and deductions that never reach your accounts.
Can category amounts include cents?
Yes. Enter up to two decimal places; the calculation converts values to integer cents before totaling them.
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/finance/budget-zero-based \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"monthly_income":5000,"categories":[{"name":"Housing","amount":1800},{"name":"Food","amount":700},{"name":"Transportation","amount":500},{"name":"Savings","amount":1000},{"name":"Other","amount":1000}]}'const res = await fetch("https://api.kit.forhosting.com/finance/budget-zero-based", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"monthly_income": 5000,
"categories": [
{
"name": "Housing",
"amount": 1800
},
{
"name": "Food",
"amount": 700
},
{
"name": "Transportation",
"amount": 500
},
{
"name": "Savings",
"amount": 1000
},
{
"name": "Other",
"amount": 1000
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/finance/budget-zero-based",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"monthly_income": 5000,
"categories": [
{
"name": "Housing",
"amount": 1800
},
{
"name": "Food",
"amount": 700
},
{
"name": "Transportation",
"amount": 500
},
{
"name": "Savings",
"amount": 1000
},
{
"name": "Other",
"amount": 1000
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/finance/budget-zero-based", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"monthly_income":5000,"categories":[{"name":"Housing","amount":1800},{"name":"Food","amount":700},{"name":"Transportation","amount":500},{"name":"Savings","amount":1000},{"name":"Other","amount":1000}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"monthly_income":5000,"categories":[{"name":"Housing","amount":1800},{"name":"Food","amount":700},{"name":"Transportation","amount":500},{"name":"Savings","amount":1000},{"name":"Other","amount":1000}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/finance/budget-zero-based", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"monthly_income": 5000,
"categories": [
{
"name": "Housing",
"amount": 1800
},
{
"name": "Food",
"amount": 700
},
{
"name": "Transportation",
"amount": 500
},
{
"name": "Savings",
"amount": 1000
},
{
"name": "Other",
"amount": 1000
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "finance.budget_zero_based",
"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. |