An Amazon referral fee calculator needs the current price to be right: the fee is a percentage of the total price the buyer pays - item plus shipping plus gift wrap, VAT included on EU stores - or a stated minimum, whichever is greater. One /api/amazon-product-offers call per ASIN returns that live Buy Box total price; the script below applies your rate and minimum to it, subtracts your fulfilment fee, and compares the result with your landed cost so you see the margin before you price a unit.
Key Takeaways
- Amazon's referral fee is a percentage of the total price (item + shipping + gift wrap, VAT included on EU stores) or a stated minimum, whichever is greater.
- The offers API returns no fees - your rate, minimum and fulfilment fee are inputs the script applies to a live price.
- Net proceeds = selling price - referral fee - fulfilment fee; margin = net proceeds - your landed cost.
- A suppressed or empty Buy Box has no price to calculate from - the row is flagged, not guessed at 0.
- One offers call per ASIN per check, so re-pricing 100 ASINs four times a day costs about 12,000 credits a month.
How is the Amazon referral fee calculated?
As a percentage of the total price, or a flat minimum, whichever is greater. Amazon's own pricing page states the referral fee is "a percentage of the total price or a minimum amount, whichever is greater", where total price is the full amount the buyer pays: item price, shipping and gift wrap, with VAT included on EU stores. The minimum is $0.30 / EUR 0.30 in most categories; many mainstream categories charge 15%. Your rate and minimum depend on the category, so they are inputs here, not something the API can look up for you.
| ASIN | Live price | Referral fee | Fulfilment | Margin | Margin % | Status |
|---|---|---|---|---|---|---|
| B0EXAMPLE1 | 49.99 | 7.50 | 3.50 | +29.99 | 60.0% | ok |
| B0EXAMPLE2 | 9.99 | 2.00 | 1.00 | +2.99 | 29.9% | ok (minimum fee) |
| B0EXAMPLE3 | 21.50 | 3.23 | 3.50 | -5.23 | -24.3% | below break-even |
| B0EXAMPLE4 | - | - | - | - | - | no buy box |
How do I get the live price to calculate the fee from?
Read the Buy Box total price from the offer listing for each ASIN: buyBox.totalPrice already adds item price and shipping. price_one() makes one call per ASIN, applies the referral rate and minimum to that price plus your gift wrap input, subtracts the fulfilment fee, and compares the net proceeds with your landed cost. get_with_retry() comes from retry.py, new_session() and ApiError from sellermagnet.py in the Python quickstart; the offer fields come from the product offers page.
fee_calc.py - referral fee and margin from a live Buy Box price
"""Referral fee + landed price calculator: live Buy Box price in, margin after fees out.
Amazon charges the referral fee on the total price the buyer pays (item + shipping + gift
wrap, VAT included on EU stores) or a stated minimum, whichever is greater - the offers API
returns no fees, so the rate, minimum and fulfilment fee come from the input file.
"""
import csv
import sys
from pathlib import Path
import requests
from retry import get_with_retry
from sellermagnet import ApiError, new_session
ROWS_FILE = Path("fee_rows.csv")
OUT_FILE = Path("landed_price_report.csv")
FIELDS = ["asin", "marketplace_id", "selling_price", "referral_fee", "fulfilment_fee",
"net_proceeds", "landed_cost", "margin", "margin_pct", "status"]
def read_rows(path: Path) -> list[dict]:
"""Validate before paying for a call: a malformed rate or a duplicate ASIN is caught here."""
rows, seen = [], set()
with path.open(newline="") as f:
for i, r in enumerate(csv.DictReader(f), start=1):
asin, mkt = r["asin"].strip(), r["marketplace_id"].strip()
if (asin, mkt) in seen:
print(f"row {i}: duplicate {asin}/{mkt}, skipping", file=sys.stderr)
continue
seen.add((asin, mkt))
try:
rate = float(r["referral_rate"])
minimum = float(r["referral_minimum"])
fulfilment = float(r["fulfilment_fee"])
gift_wrap = float(r.get("gift_wrap") or 0)
landed_cost = float(r["landed_cost"])
assert 0 <= rate <= 1 and minimum >= 0 and fulfilment >= 0 and gift_wrap >= 0 and landed_cost >= 0
except (KeyError, ValueError, AssertionError):
print(f"row {i}: bad numeric input for {asin}, skipping", file=sys.stderr)
continue
rows.append({"asin": asin, "marketplace_id": mkt, "rate": rate, "minimum": minimum,
"fulfilment": fulfilment, "gift_wrap": gift_wrap, "landed_cost": landed_cost})
return rows
def price_one(session, row: dict) -> dict:
out = {"asin": row["asin"], "marketplace_id": row["marketplace_id"]}
try:
offers = get_with_retry(session, "amazon-product-offers", asin=row["asin"],
marketplaceId=row["marketplace_id"])
except ApiError as err:
out["status"] = "not on this marketplace" if err.status == 404 else f"error {err.status}"
return out
except (requests.ConnectionError, requests.Timeout) as err:
out["status"] = type(err).__name__
return out
buy_box = offers.get("buyBox") or {}
if offers.get("buyBoxSuppressed") or "totalPrice" not in buy_box:
out["status"] = "no buy box" # stock-out or every offer hidden: nothing to price against
return out
selling_price = buy_box["totalPrice"] # item + shipping, VAT included on EU stores (facts.md)
fee_basis = selling_price + row["gift_wrap"]
referral_fee = round(max(fee_basis * row["rate"], row["minimum"]), 2)
net_proceeds = round(selling_price - referral_fee - row["fulfilment"], 2)
margin = round(net_proceeds - row["landed_cost"], 2)
out.update({
"selling_price": selling_price, "referral_fee": referral_fee,
"fulfilment_fee": row["fulfilment"], "net_proceeds": net_proceeds,
"landed_cost": row["landed_cost"], "margin": margin,
"margin_pct": round(margin / selling_price * 100, 1) if selling_price else None,
"status": "below break-even" if margin < 0 else "ok",
})
return out
if __name__ == "__main__":
session = new_session()
results = [price_one(session, row) for row in read_rows(ROWS_FILE)]
new_file = not OUT_FILE.exists()
with OUT_FILE.open("a", newline="") as f:
w = csv.DictWriter(f, fieldnames=FIELDS, extrasaction="ignore")
if new_file:
w.writeheader()
w.writerows(results)
for r in results:
if r["status"] in ("ok", "below break-even"):
print(f"{r['asin']} price {r['selling_price']:.2f} fee {r['referral_fee']:.2f} "
f"margin {r['margin']:+.2f} ({r['margin_pct']}%) {r['status']}")
else:
print(f"{r['asin']} {r['status']}")
The offer fields the calculator reads (trimmed, illustrative values)
{
"success": true,
"data": {
"asin": "B0EXAMPLE1",
"currency": {"symbol": "$", "code": "USD"},
"buyBoxSuppressed": false,
"buyBox": {"sellerId": "Amazon", "sellerName": "Amazon",
"priceWithoutShipping": 49.99, "shippingPrice": 0.0, "totalPrice": 49.99},
"offers": [
{"sellerId": "Amazon", "totalPrice": 49.99, "fulfillmentType": "FBA", "condition": "New"}
]
}
}
Four ASINs through the calculator (illustrative input and live-offer values)
B0EXAMPLE1 price 49.99 fee 7.50 margin +29.99 (60.0%) ok
B0EXAMPLE2 price 9.99 fee 2.00 margin +2.99 (29.9%) ok
B0EXAMPLE3 price 21.50 fee 3.23 margin -5.23 (-24.3%) below break-even
B0EXAMPLE4 no buy box

Referral fee basis: what counts and what does not
- Counts: item price, shipping charged to the buyer, and gift wrap - on EU stores the total already includes VAT, so do not add it again.
- Does not count on its own: your fulfilment fee and your landed cost are yours to subtract after the referral fee, not part of its basis.
- Not visible in the offer data: coupons and checkout discounts are not returned, so a coupon-adjusted checkout price is not what this calculator sees.
When the minimum beats the percentage
Because the percentage came out lower than the stated minimum for that category. EXAMPLE2 above sells for $9.99: 15% of that is $1.50, below the $2.00 minimum used in the example, so the calculator charges the minimum. Low-priced items are where the minimum usually decides the fee, so checking both numbers on cheap SKUs matters more than on expensive ones.
What does the landed price / landed cost comparison actually show?
Whether today's live price still covers what the unit cost you to get into stock. "Landed cost" here is your own number - product cost plus inbound freight and any duty to get one unit to Amazon - entered per ASIN; the calculator does not estimate it. Net proceeds (live price minus referral fee minus fulfilment fee) below your landed cost means the current price does not clear your cost, not that the ASIN is unprofitable forever - a repriced listing or a different offer can change the answer on the next run. The FBA vs FBM landed price guide compares landed prices across fulfilment types, and the wholesale price list guide covers landed cost across a supplier's full catalogue.
Re-pricing a catalogue: the credit cost
One credit per ASIN per check - the same call the calculator already makes. The table shows 30-day months for three catalogue sizes at one, four and twelve checks a day; pricing lists the plans. Four checks a day catches most same-day repricing; twelve is for fast-moving Buy Box fights.

Frequently Asked Questions
How is the Amazon referral fee calculated?
As a percentage of the total price (item + shipping + gift wrap, VAT included on EU stores) or a stated minimum, whichever is greater.
Does the API return the referral fee for me?
No. The offers API returns the live price only; the rate, minimum and fulfilment fee are inputs you supply per category.
What is "landed price" in this calculator?
The live selling price minus the referral fee and fulfilment fee, compared with your own landed cost (product plus inbound freight and duty) for that ASIN.
Does the calculator see coupons or checkout discounts?
No. The offer data carries the listed item price, shipping and gift wrap only; coupon-adjusted checkout prices are not in it.
What happens when a listing has no Buy Box?
The row is flagged "no buy box" and skipped - a suppressed or stock-out listing has no price to calculate a fee or margin from.
How much does re-pricing a catalogue cost?
One credit per ASIN per check. 100 ASINs checked four times a day use about 12,000 credits in a 30-day month.
Bottom line: pull the live Buy Box total price, apply your category's referral rate or minimum - whichever is greater - subtract your fulfilment fee, and compare what is left with your landed cost per ASIN. A free account includes 150 credits to run it on your own catalogue.