---
name: amazon-profitability-calculator
description: >-
  Calculate Amazon per-unit margin, break-even or target-margin price,
  affordable ad spend, and period P&L waterfalls. Use for ASIN profitability,
  unit economics, contribution or channel margin, landed cost, COGS, TACoS,
  fee and return impact, settlement reconciliation, or period-over-period
  margin movement. Excludes live repricing, return-reason diagnosis, and ad
  campaign reporting.
compatibility: Amazon SP-API MCP (meta-tool pattern) for live fee estimates, returns, storage and settlement data; Amazon Ads MCP for the advertising line. Both optional - without them the skill runs in manual mode on seller-supplied fees and labels the output as such. Scripts need Python 3 only, no dependencies.
license: PolyForm-Shield-1.0.0 (see LICENSE.txt)
metadata:
  version: "0.1.0"
---

# Amazon Profitability

Two calculations that people routinely conflate. Work out which one is being asked for
before doing anything else.

| | **Per-unit cascade** | **Period P&L** |
| --- | --- | --- |
| Question | Should I sell this, at what price? | What did the business actually make? |
| Scope | One hypothetical unit | A brand or account over a period |
| Script | `scripts/margin.py` | `scripts/pnl.py` |
| Reference | `references/formulas.md` | `references/period-pnl.md` |
| Has | Break-even and target-price solvers | Cancellations, claims, chargebacks, reimbursements, overheads |
| Lacks | Everything in the column to the right | Any notion of price solving |

The period model is **not** the per-unit model summed up. It has revenue lines the
per-unit model has no concept of, and the per-unit model solves for prices the period
model cannot. Signals: "this ASIN", "should I price at", "can I afford" → per-unit.
"last quarter", "our margin", "why did it drop", "net margin" → period.

If genuinely ambiguous, ask. Running the wrong one produces a confident answer to a
question nobody asked.

## Per-unit cascade

The insight that shapes this half of the skill: **when an ASIN exists, do not model
Amazon's fee schedules.** `fees_getMyFeesEstimateForASIN` accepts an arbitrary
hypothetical price and returns Amazon's own itemised referral and FBA fee at that price.
That eliminates referral-category mapping, size-tier derivation, and ten marketplaces of
rate cards that would otherwise go stale within months.

### Modes

| Mode | When | Fees come from |
| --- | --- | --- |
| **Live estimate** | An ASIN or SKU exists. The default. | `fees_getMyFeesEstimates`, probed across a price sweep |
| **Manual** | Pre-launch, no ASIN | A comparable ASIN's fee probe, or embedded referral bands plus a supplied FBA fee |
| **Reconciled** | User wants actuals, or asks why the model disagrees with their books | Settlement and fee reports — what Amazon actually charged |

Reconciled work at any scale beyond one SKU usually belongs in the period P&L instead.

### Workflow

1. **Context.** Confirm marketplace and, where there is more than one, the account,
   identity and Ads profile. Present the options rather than picking silently — a wrong
   profile gives a plausible number attached to the wrong business.

2. **Amazon's side.** Probe `fees_getMyFeesEstimates` across roughly 0.5x to 2x the
   current price at unit intervals. Batch it; the single-ASIN endpoint runs near 0.5 rps
   and a sweep of individual calls will crawl. The estimate excludes storage, inbound
   placement, low-inventory, utilisation and aged surcharges, and returns processing —
   source those separately or leave them at zero and say so.

3. **The seller's side.** Five inputs no API can supply: **COGS, inbound freight, VAT
   rate, other per-unit costs, target margin.** For COGS, ask where it lives before
   asking for the number — it may be in Openbridge, in agent-flow, or in a cost table
   they can paste. Check what's available and offer that first.

   Never proceed on a guessed COGS. A cascade built on an invented landed cost is worse
   than no answer because it looks authoritative. If they truly don't know it, run the
   model backwards and report the break-even COGS.

4. **Returns and advertising.** Take the sellable share from the per-unit disposition
   column rather than estimating it. If `amazon-sp-refund-return-monitor` is available,
   delegate. For advertising, default to spend ÷ **total** units (the TACoS-style ad
   load), show the ad-attributed figure alongside, and pin the attribution window.

5. **Compute** with `scripts/margin.py`. The solvers recompute every fee at each
   candidate price, because referral bands, FBA price bands and VAT all move with price
   — a fixed-fee assumption gives a wrong break-even.

   Report `break_even_price`, which is the **safe floor**: the lowest price that stays
   profitable all the way up. It is not always the first price where profit turns
   positive. Where a whole-price referral band or an FBA price band sits above that
   first crossing, the unit loses money again in between, and the script returns those
   ranges in `loss_zones` with a warning. Quote the safe floor and name the dead zone —
   `lowest_break_even` is the number that puts someone in it.

6. **Report:** summary metrics, waterfall, then assumptions naming where each number
   came from. Name the denominator on the first margin figure rather than leaving it
   implied — every margin here is against net revenue, and a reader comparing a bare
   "24% margin" against a benchmark computed on gross sales will reach the wrong
   conclusion without ever seeing the mismatch.

## Period P&L

Eight steps from gross ordered revenue to net operating profit, through four
checkpoints: **Net Revenue → Product Margin → Channel Margin → Growth Margin → Net
Operating Profit**. Read `references/period-pnl.md` before running it.

Three things to get right, because they are where this calculation usually goes wrong:

**Establish the date basis first.** Order date for decisions, shipment date for the
accounts, settlement date for cash. All three are legitimate; mixing them in one
calculation is how spreadsheets quietly break.

**Report the checkpoints, not just the bottom line.** The final number says how much was
made; the checkpoints say why. The gap between Product Margin and Channel Margin is
literally what Amazon costs as a channel, in points of net revenue. Supply a prior
period and the script reports each checkpoint's movement.

**Do not stop at fees and call it net margin.** Revenue − COGS − fees is Channel
Margin. Advertising and overheads still have to come out. This is the single most
common overstatement in the category.

`pnl.py` warns when the date basis is unstated and when claims, chargebacks,
reimbursements or overheads are missing. Surface those warnings; do not suppress them.

## Guardrails

**Never invent a fee number.** If a rate is not in the embedded tables, not returned by
the API, and not supplied by the user, say so and leave it out with a note. An FBA fee
recalled from a rate card will be wrong, and the error lands straight in the profit line.

**Fee tables carry verification dates.** The embedded US referral schedule is dated. If
it is more than a few months stale, flag it and prefer a live probe.

**VAT is never revenue and never cost.** Per-unit: divide it out to reach net revenue.
Period: keep it as a memo outside the waterfall. Either way it stays out of the profit
math, while remaining visible as a cash figure.

**Distinguish estimate from actual.** Live mode gives Amazon's estimate of its own fees;
settlement gives what was charged. They diverge, and the divergence is often the most
interesting finding. Do not present one as the other.

**Report type identifiers change.** Validate against Amazon's current Report Type Values
documentation rather than trusting a name from memory.

**Name the denominator.** Margin percentages, ACoS and TACoS all depend on it. Net
revenue is the default here; gross sales flatters. Say which was used. `margin.py`
reports `amazon_take` against net revenue and carries the gross-price version alongside
as `amazon_take_of_gross_price` — in a VAT market the two differ by the VAT rate, and
quoting the gross one understates what Amazon costs.

## Validating a change

Both worked examples ship as fixtures. After any change to a script or a fee model:

```bash
python scripts/validate_fixtures.py
```

It re-runs the per-unit and period examples against the numbers quoted in the
references, plus a regression case for the whole-price band discontinuity. Exit 0 means
the documented figures still hold.

## References

- `references/period-pnl.md` — the eight steps, date bases, VAT treatment, failure patterns
- `references/sourcing.md` — which SP-API and Ads call supplies each attribute
- `references/formulas.md` — per-unit input schema, fee models, line definitions
- `references/inputs.md` — full attribute matrix with source tiers and known gaps
- `references/us-referral-fees.md` — US referral schedule for manual mode
