Calculate macronutrient split from calories and percentages
This macronutrient split calculator converts a daily calorie goal and three percentage targets into practical gram targets for protein, carbohydrates, and fat.
Run — free
It uses the standard energy factors of four calories per gram for protein, four for carbohydrates, and nine for fat. The calculator checks every value before calculating and rejects a split unless its percentages total 100. That makes it useful when a nutrition plan, coaching workflow, meal-planning sheet, or fitness application needs a clear and repeatable result instead of a silently adjusted ratio.
Enter a complete calorie-based macro target
Start with the total number of calories intended for one day, then provide the share of those calories assigned to protein, carbohydrates, and fat. Each share is a percentage of energy, not a percentage of food weight and not a number of grams. For example, a 30 percent protein target means that 30 percent of the daily calorie budget comes from protein. All four inputs are required so the calculation remains explicit and reproducible. Calories must be a finite number greater than zero. Each percentage must be a finite number from zero through 100, so a plan can intentionally assign zero percent to a macro while still rejecting negative or impossible shares. Use numbers without percent signs or calorie units in the fields. The response echoes the accepted calorie amount and returns the full split alongside the calculated grams, which makes it easy to record exactly which assumptions produced a result. This capability does not decide which calorie goal or ratio is suitable for a person; it performs the arithmetic for targets that the caller has already selected.
Understand the calorie-to-gram conversion
The calculation first allocates the daily calories to each macronutrient. It multiplies total calories by the macro percentage and divides by 100. It then converts the allocated energy into grams using four kilocalories per gram for protein, four kilocalories per gram for carbohydrates, and nine kilocalories per gram for fat. Consider 2,000 calories with a 30 percent protein, 40 percent carbohydrate, and 30 percent fat split. Protein receives 600 calories, which becomes 150 grams. Carbohydrates receive 800 calories, which becomes 200 grams. Fat receives 600 calories, which becomes approximately 66.666667 grams because fat supplies more energy per gram. Results are rounded to no more than six decimal places to avoid distracting floating-point artifacts while retaining useful precision. The algorithm contains no network calls, randomness, stored state, or current-time dependency. Identical JSON input therefore produces identical JSON output, making this calculator appropriate for automated meal-planning systems, test fixtures, spreadsheets, and services that need consistent values across repeated runs.
Correct percentage totals before calculating
Protein, carbohydrate, and fat percentages must sum to 100 because together they describe the complete calorie budget. If they total 95, the missing five percent has no declared destination; if they total 110, the plan allocates more energy than the stated calorie target. Rather than normalize or silently rewrite those values, the capability returns an invalid input error explaining that the percentages must sum to 100. This strict behavior exposes data-entry mistakes and prevents a result that looks authoritative while using assumptions the caller never approved. A tiny tolerance is used only to accommodate ordinary floating-point representation, not to accept materially incomplete ratios. When an error occurs, review all three percentage fields instead of changing the calorie total, since the sum rule concerns the ratio itself. A successful response groups the original percentages and the resulting grams, letting downstream code show the ratio and calculated targets together. Treat these gram values as planning targets rather than nutritional measurements: food labels, recipes, rounding conventions, fiber accounting, alcohol, and individual dietary needs can affect real-world tracking and should be handled by the surrounding nutrition workflow.
What you can do with it
Build a daily meal-planning target
Convert an established calorie goal and macro ratio into gram targets that can guide recipes and meal portions.
Validate coaching-plan arithmetic
Check that a proposed protein, carbohydrate, and fat split is complete before saving calculated targets for a client.
Power a fitness application
Generate deterministic macro grams in an application without duplicating conversion rules across clients and services.
FAQ
Do the percentages have to sum to 100?
Yes. The calculation returns an invalid input error when protein, carbohydrate, and fat percentages do not total 100.
How are calories converted into grams?
Allocated protein and carbohydrate calories are divided by four, while allocated fat calories are divided by nine.
Can one macronutrient be set to zero percent?
Yes. Every percentage may range from zero through 100, provided all three percentages still sum to 100.
Does this calculator recommend a macro ratio?
No. It calculates grams from the calorie target and percentages you provide; it does not offer medical or dietary advice.
What does an API request cost?
The published base price is $0.002 per request. The browser experience can use the same deterministic calculation.
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/calc2/macro-split-calculate \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"calories":2000,"protein_percent":30,"carb_percent":40,"fat_percent":30}'const res = await fetch("https://api.kit.forhosting.com/calc2/macro-split-calculate", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"calories": 2000,
"protein_percent": 30,
"carb_percent": 40,
"fat_percent": 30
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/calc2/macro-split-calculate",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"calories": 2000,
"protein_percent": 30,
"carb_percent": 40,
"fat_percent": 30
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/calc2/macro-split-calculate", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"calories":2000,"protein_percent":30,"carb_percent":40,"fat_percent":30}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"calories":2000,"protein_percent":30,"carb_percent":40,"fat_percent":30}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/calc2/macro-split-calculate", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"calories": 2000,
"protein_percent": 30,
"carb_percent": 40,
"fat_percent": 30
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "calc2.macro_split_calculate",
"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. |