Consumer price index from basket calculator
This consumer price index calculator values the same basket of goods and services twice: once using base-year prices and once using current prices.
Run — free
It divides the current basket cost by the base basket cost and multiplies the ratio by one hundred. Enter each item’s fixed quantity and both prices to receive the two basket totals, the consumer price index, and the implied percentage price change. Because quantities stay fixed, the result isolates price movement rather than changes in what consumers buy.
Build a genuinely fixed basket
A consumer price index begins with a basket that represents a defined pattern of consumption. List each good or service once, give it a clear name, and enter the quantity purchased during the basket period. The identical quantity is used for both valuations. That detail matters: if the base calculation uses ten loaves of bread but the current calculation uses eight, the resulting difference mixes a price change with a quantity change and is no longer a fixed-basket index. Quantities may be fractional when the unit calls for it, such as kilowatt-hours, kilograms, or monthly service shares, but every quantity must be positive. Prices must use the same currency and the same unit definition in both periods. A base price per kilogram cannot be compared with a current price per package unless the package is converted to kilograms first. Include enough representative categories to serve the purpose of the analysis, and document what the basket covers. The calculator accepts up to one thousand items and performs one transparent valuation pass, without seasonal adjustment or substitutions.
Understand the index formula and result
For every row, the calculator multiplies the fixed quantity by the base-year unit price to obtain that item’s base value. It separately multiplies the same quantity by the current unit price. Adding each set of values produces the base basket cost and current basket cost. The consumer price index equals the current basket cost divided by the base basket cost, multiplied by one hundred. An index of one hundred means the valued basket costs exactly the same in both periods. A value above one hundred indicates an overall increase, while a value below one hundred indicates an overall decrease. The reported price change percentage is simply the index minus one hundred, so an index of 112.5 corresponds to a 12.5 percent increase from the base period. Items with larger quantities or prices contribute more to the totals and therefore have more influence on the index. The base basket total must be greater than zero because division by a zero-valued reference basket is undefined. Rounding is applied only to the returned values after full-precision totals are calculated.
Interpret comparisons carefully
The result is a price index for the basket you supplied, not automatically an official national CPI. Statistical agencies use carefully sampled prices, expenditure weights, quality adjustments, replacement rules, seasonal methods, and periodic basket updates. A personal, business, or classroom basket can still be highly useful when its scope is explicit and consistent. Use the same item definitions and quantities whenever you compare multiple current periods with one base year. If a product disappears, decide on a documented comparable replacement rather than silently switching size or quality. A rising index shows that the fixed basket costs more, but it does not explain which items caused the increase or whether a household changed its purchasing behavior. Review the underlying prices for that interpretation. This tool is especially suitable for reproducible examples, internal cost monitoring, and teaching the Laspeyres-style fixed-basket idea. Each API request costs $0.002, while the browser calculation can run locally. Preserve the basket specification alongside each result so another analyst can reproduce the calculation and understand the unit, currency, period, and coverage choices.
What you can do with it
Track a household basket
Compare the cost of a consistently defined set of groceries, transport, housing, and services against a chosen base period.
Monitor procurement prices
Value fixed input quantities at contract-year and current supplier prices to summarize broad purchasing-cost movement.
Teach index-number methods
Demonstrate how quantities act as weights and why a fixed basket separates price movement from quantity changes.
FAQ
What formula does the calculator use?
It divides the cost of the fixed basket at current prices by its cost at base-year prices, then multiplies by one hundred.
What does an index of 100 mean?
It means the basket has the same total cost at current prices as it did at base-year prices.
Can quantities change between periods?
No. The method intentionally applies one fixed quantity to both price sets so the result measures price movement rather than purchasing changes.
Can an item have a zero price?
Yes, individual base or current prices may be zero, but the total base-year basket cost must be greater than zero.
Is this the same as an official national CPI?
Not necessarily. It calculates the standard fixed-basket ratio for your data, while official indexes may also apply sampling, quality adjustments, substitutions, and other statistical procedures.
What does it cost to use?
The API price is $0.002 per request. The browser version can run the same deterministic calculation locally.
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/econ/cpi-from-basket \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"basket":[{"name":"Bread","quantity":10,"base_price":2,"current_price":2.5},{"name":"Milk","quantity":5,"base_price":3,"current_price":3.3},{"name":"Bus fares","quantity":20,"base_price":1.5,"current_price":1.8}]}'const res = await fetch("https://api.kit.forhosting.com/econ/cpi-from-basket", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"basket": [
{
"name": "Bread",
"quantity": 10,
"base_price": 2,
"current_price": 2.5
},
{
"name": "Milk",
"quantity": 5,
"base_price": 3,
"current_price": 3.3
},
{
"name": "Bus fares",
"quantity": 20,
"base_price": 1.5,
"current_price": 1.8
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/econ/cpi-from-basket",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"basket": [
{
"name": "Bread",
"quantity": 10,
"base_price": 2,
"current_price": 2.5
},
{
"name": "Milk",
"quantity": 5,
"base_price": 3,
"current_price": 3.3
},
{
"name": "Bus fares",
"quantity": 20,
"base_price": 1.5,
"current_price": 1.8
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/econ/cpi-from-basket", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"basket":[{"name":"Bread","quantity":10,"base_price":2,"current_price":2.5},{"name":"Milk","quantity":5,"base_price":3,"current_price":3.3},{"name":"Bus fares","quantity":20,"base_price":1.5,"current_price":1.8}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"basket":[{"name":"Bread","quantity":10,"base_price":2,"current_price":2.5},{"name":"Milk","quantity":5,"base_price":3,"current_price":3.3},{"name":"Bus fares","quantity":20,"base_price":1.5,"current_price":1.8}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/econ/cpi-from-basket", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"basket": [
{
"name": "Bread",
"quantity": 10,
"base_price": 2,
"current_price": 2.5
},
{
"name": "Milk",
"quantity": 5,
"base_price": 3,
"current_price": 3.3
},
{
"name": "Bus fares",
"quantity": 20,
"base_price": 1.5,
"current_price": 1.8
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "econ.cpi_from_basket",
"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. |