Buy one get one effective price calculator
A buy-one-get-one or buy-X-get-Y promotion can look generous without revealing what every item effectively costs in the cart you actually plan to buy.
Run — free
This calculator applies the offer to a specific quantity, separates paid items from free items, and reports the regular total, promotional total, total savings, and effective per-item price. It supports classic buy one get one free as well as offers such as buy two get one free, using one regular unit price for every item. The result makes promotions easier to compare with ordinary sale prices and percentage discounts.
Enter the promotion exactly as advertised
Begin with the regular unit price before any promotion, then enter the total quantity you intend to take home. The purchase quantity matters because a BOGO deal does not always apply evenly to every cart. Six items may complete three buy-one-get-one groups, while five items complete two groups and leave one item at full price. Use buy quantity for the X in buy X get Y free and free quantity for Y. A classic buy-one-get-one-free promotion therefore uses one for both fields. A buy-two-get-one-free offer uses two as the buy quantity and one as the free quantity. All quantity fields represent whole items and must be positive integers. The unit price may be zero, but it cannot be negative or non-finite. Every item is assumed to have the same regular price, and the deal is assumed to grant the stated free items whenever the corresponding paid requirement is met within a promotion group. Enter the number of items actually purchased, not the number of promotion groups, so the calculator can correctly handle leftovers that do not complete a full cycle.
Understand the effective price and savings calculation
The calculator treats one promotion group as the buy quantity plus the free quantity. It counts every complete group in the purchase, then examines the remaining items. Within a partial group, the first X items are paid; any items after that paid requirement become free until the group limit is reached. Paid items equal the full purchase quantity minus free items. The regular total is the unit price multiplied by every item, while the promotional total is the same unit price multiplied only by paid items. Total savings is the difference between those totals. Finally, effective price per item divides the promotional total by the complete number of items received, including free items. That last value is often the most useful comparison figure. For example, a nominally free second item lowers the effective unit cost only when the cart contains a qualifying pair. An unmatched item remains fully paid and raises the average. Results are rounded consistently to twelve decimal places, avoiding noisy floating-point tails while preserving useful precision for inexpensive goods, wholesale pricing, and automated calculations. No tax, shipping, coupon, membership fee, or currency conversion is added.
Compare the promotion with realistic alternatives
Use the effective per-item result beside the actual per-item price of competing offers. This avoids comparing a dramatic promotion label with a smaller discount that may cost less for your chosen quantity. A BOGO offer can be excellent when you need every qualifying item, but buying extra products merely to unlock free units may increase total spending and create waste. Check both promotional total and effective price: the average can be attractive while the checkout total still exceeds your budget. Retail teams can use the same outputs to review shelf labels, promotion previews, and checkout tests. Educators can demonstrate why incomplete promotion groups change averages. Procurement teams can compare case quantities when suppliers use buy-X-get-Y language instead of a direct unit discount. The calculation is deterministic and uses no network, current date, random value, or external price source, so identical inputs always return identical results. API calls use the published base price of $0.002; the browser experience can perform the same arithmetic locally. This tool models identical items at one unit price. Promotions that select the cheapest mixed item, cap the number of redemptions, discount Y rather than making it free, or stack with other offers require separate calculations under the retailer’s precise terms.
What you can do with it
Compare grocery promotions
Convert a BOGO shelf offer into the effective cost of each item for the exact quantity on a shopping list.
Check an online cart
Confirm how many products should be free and compare the expected promotional total with checkout.
Evaluate supplier deals
Turn buy-X-get-Y case offers into a consistent per-unit figure for purchasing comparisons.
FAQ
What is effective price per item?
It is the promotional total divided by all items received, including items made free by the offer.
Does the calculator support buy two get one free?
Yes. Set buy_quantity to 2 and free_quantity to 1, then enter the total number of items purchased.
What happens to an incomplete promotion group?
The paid requirement is filled first. Only remaining items beyond that requirement qualify as free within the partial group.
Can items have different prices?
No. This calculation assumes identical items with one regular unit price and does not apply a cheapest-item-free rule.
What does an API calculation cost?
Each API request uses the published base price of $0.002.
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/life/bogo-effective-price \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"unit_price":12.5,"quantity":7,"buy_quantity":2,"free_quantity":1}'const res = await fetch("https://api.kit.forhosting.com/life/bogo-effective-price", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"unit_price": 12.5,
"quantity": 7,
"buy_quantity": 2,
"free_quantity": 1
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/life/bogo-effective-price",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"unit_price": 12.5,
"quantity": 7,
"buy_quantity": 2,
"free_quantity": 1
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/life/bogo-effective-price", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"unit_price":12.5,"quantity":7,"buy_quantity":2,"free_quantity":1}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"unit_price":12.5,"quantity":7,"buy_quantity":2,"free_quantity":1}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/life/bogo-effective-price", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"unit_price": 12.5,
"quantity": 7,
"buy_quantity": 2,
"free_quantity": 1
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "life.bogo_effective_price",
"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. |