WhatsApp metering — independent re-verification
WhatsApp metering — independent re-verification
Card t_c2f6df57 is the board-mirror of the WhatsApp metering card. The
ruling was landed mid-flight by the twin card t_1d1257c3 (commit 0b6fdc7,
22:30), inside this run. So this card's job was not to write the ruling
— it was to independently verify it against primary sources, and correct
what is wrong.
Verdict: the ruling stands. Two defects found and corrected, plus one gap closed. The A$49 line, the 150-message allowance, the hybrid model and the Tech-Provider default all survive. The corrections are to how the overage rate is computed and controlled, not to the model.
1. What I verified, and how
Every load-bearing claim re-fetched from the primary source in this run, not from the twin card's text.
| # | Claim | Method | Result |
|---|---|---|---|
| 1 | AU is in the Rest of Asia Pacific region, not a standalone market | Meta pricing page, "Pricing regions on the rate card" — full 16-market list read | ✅ confirmed (AF, AU, KH, CN, JP, LA, MN, NZ, PG, PH, TW, TJ, TH, TM, UZ, VN) |
| 2 | RoAP marketing = A$0.1095, utility/auth/service = A$0.0148 | Re-downloaded Meta's AUD list-rate card (HTTP 200) → sha256 d874292c… → parsed the xlsx directly | ✅ confirmed — sha256 matches the twin card's recorded upstream file exactly; 47 market rows, RoAP row identical to the committed CSV |
| 3 | Marketing has no volume tier at any volume | Re-downloaded Meta's AUD volume-tier card (HTTP 200) → sha256 1d809ad7… → parsed | ✅ confirmed — the card's own header: "Volume tiers apply only to utility and authentication messages" |
| 4 | RoAP marketing increased 1 Oct 2026 | Meta's Oct-2026 change table on the pricing page | ✅ confirmed — "Rest of Asia Pacific · Marketing · Increase" |
| 5 | 1 month notice for a rate-card update; 4×/yr | Meta's "Minimum advanced notice" table | ✅ confirmed — rate card update = 1 month; model change = 6 months; pricing model add-on = 3 months |
| 6 | Service messages became chargeable 1 Oct 2026; 1,000 free/phone number/mo | Meta's "Charging for messages that were previously free" | ✅ confirmed — and the utility-in-CSW pricing.type changed free_customer_service → regular on 1 Oct 2026 |
| 7 | Meta charges only on delivery | Meta pricing page | ✅ confirmed — "Businesses are only charged when a message is delivered" |
| 8 | Bill To Party liability (Solution Partner) | Meta — Managing credit lines, live | ✅ confirmed verbatim — "You are liable for and will pay Meta for all WhatsApp Business Platform spend made by these businesses." |
| 9 | No reselling of the platform | Meta — Meta Terms for the WhatsApp Business Platform §4.1(c) | ✅ confirmed — "distribute, sell, resell, or rent the WhatsApp Business Platform to third parties" |
| 10 | FIXED credit partition with an amount | Graph API — Extended Credit Allocation Config | ✅ confirmed — partition_type enum {FIXED, AUTH, FIXED_WITHOUT_PARTITION}; amount set only when type is FIXED |
| 11 | Messaging limit tiers TIER_250 → 2,000 → 10,000 → 100,000 → Unlimited | Meta — Messaging Limits, live | ✅ confirmed — and per business portfolio, shared by all numbers in it |
| 12 | AI-Provider clause: AU is not on the charged list | Meta — New pricing policy for AI Providers (updated 15 Oct 2026) | ✅ confirmed — charged markets are Italy, Brazil, Türkiye + the EU-27 list (charged to 12 May 2026, not charged since) |
| 13 | EVE is a business-CS agent, not a general-purpose assistant | WhatsApp Business Solution Terms + TechCrunch (Meta's own confirmation) | ✅ supported — Meta: "this move doesn't affect businesses that are using AI to serve customers on WhatsApp". A reading, not a legal opinion — twin card's open item 4 stands |
Re-derived independently: 49 ÷ 0.1095 = 447 break-even ·
49 × 0.4 ÷ 0.1095 = 179 for 60% margin · 150 × 0.1095 = A$16.43 →
66.5% margin on the A$49 line. All three match the twin card's numbers
exactly. I also re-ran wa_metering_model_2026-10-20.py — it executes, exit 0,
and reproduces its own table.
2. 🔴 Defect 1 — the bid_amount figure was wrong by 100×
The landed ruling (§5.4, control 2) said:
set
bid_amountto our own billed rate (A$0.1314 →bid_amount131 per 1,000 deliveries in the account currency's smallest unit)
Meta's own unit definition (from Set a max price for marketing messages (BETA), "Calculating max price amounts"):
To set a max price of $0.05 USD per delivery: Set
bid_amountto 5000.
i.e. bid_amount = per-delivery price × 1000 × 100 — the account currency's
smallest unit, which for AUD is cents.
0.1314 × 1000 × 100 = 13140 <- correct
0.1314 × 1000 = 131 <- what the ruling said
Why it matters: bid_amount 131 buys A$0.00131 per delivery — a cap
100× below the A$0.1314 we bill. Control 2 exists to make the spread
non-negative; as written it would have capped our deliveries at a hundredth of
cost, i.e. it protects nothing. A control that reads as protection in the
design of record and is not is worse than no control.
The metering script carried the identical error (§9 printed
round(MKT*MARKUP*1000) = 131). Both are fixed; the script now prints
13140 and shows the derivation.
Also confirmed while I was there: bid_strategy must be
LOWEST_COST_WITH_BID_CAP whenever bid_amount is set, and a bid cap is a
price cap, not a budget — it does not stop volume. So controls 1 (HIL gate)
and 3 (FIXED partition) are load-bearing, not decorative.
3. 🔴 Defect 2 — A$0.1314 is the AU overage rate, and the ruling never said so
This is the more consequential of the two, and it is a gap, not a typo.
Meta charges by the recipient's country calling code. A$0.1314 is
A$0.1095 (RoAP) × 1.20 — correct for Australian recipients. The ruling
quoted it as the overage rate in §5.2, in §5.3's worked example, and in the
tenant contract terms (§5.5 clause 2). A tenant's audience is not
necessarily Australian. From the rate card I re-parsed live:
| Recipient market | Meta marketing cost | We bill (AU rate) | Effect on us |
|---|---|---|---|
| Netherlands | A$0.2077 | A$0.1314 | 🔴 we lose A$0.0763/msg — A$76.30 per 1,000 |
| Germany | A$0.1775 | A$0.1314 | 🔴 we lose A$0.0461/msg — A$46.10 per 1,000 |
| Chile | A$0.1156 | A$0.1314 | ok (+A$0.0158) |
| Rest of Asia Pacific (AU) | A$0.1095 | A$0.1314 | ✅ our designed 20% markup |
| Colombia | A$0.0163 | A$0.1314 | 🟠 overcharge A$0.1151/msg (706%) |
| India | A$0.0153 | A$0.1314 | 🟠 overcharge A$0.1161/msg (759%) |
| Turkey | A$0.0142 | A$0.1314 | 🟠 overcharge A$0.1172/msg (825%) |
Two failure modes, both real. (a) A blast to Netherlands recipients costs us A$76.30 per 1,000 messages more than we bill — the exact loss control 2 was supposed to prevent, and control 2 only helps if the cap is set to the recipient's market rate. (b) A tenant with an Indian or Turkish audience is overcharged up to 8× on the overage line — a pricing-dispute and reputational risk, not a margin.
The good news: the meter already has the field. Meta's pricing_analytics
edge breaks charges down by COUNTRY × PRICING_CATEGORY × PRICING_TYPE
(dimensions COUNTRY, PHONE, PRICING_CATEGORY, PRICING_TYPE, TIER),
and the status-message webhook gives pricing.category per delivery. The
market is knowable per delivery — we simply were not pricing on it.
What changed: the billing rule is now
overage_rate(recipient_country) = Meta marketing rate(country) × 1.20.
For AU tenants that is A$0.1314, unchanged. The A$49 line, the 150 allowance
and the hybrid model are untouched. §5.5 clause 2 now says "for Australian
recipients" and a new clause 6 puts the recipient-market rule in front of the
tenant. Two open items added (per-country bid_amount via
bid_country_multiplier_overrides; and the product decision on whether we
bill per-market or a single blended rate).
4. What I did not change, and why
- The A$49 line price — set by the sibling card
t_b2496986; the twin card's ruling kept it, and nothing I verified argues against it. - The 150-message allowance — inside the ≤179 envelope; still a judgment (twin card's open item 6: re-baseline from pilot data).
- The hybrid model — the reasoning survives: a pure pass-through makes the A$49 line meaningless; a pure allowance at ≤179 is "less than one campaign".
- The Tech-Provider default — reinforced, if anything, by §4.1 below.
5. 🟡 One structural gap I found that the twin card did not name
Under the twin card's Shape A (tenant owns the WABA, tenant pays Meta), our allowance is enforced in our product, not in Meta's billing — the twin card says this and is right. But it understates one consequence:
Meta's messaging limit is set at the business portfolio level and is shared by all phone numbers in it (Meta — Messaging Limits, live: "Messaging limits are calculated and set at the business portfolio level and are shared by all business phone numbers within a portfolio"). New portfolios start at 250 unique users per 24h outside a customer-service window.
So:
- Under Shape A the tenant's own portfolio carries the limit — our commercial allowance (150) is below Meta's (250), so our cap is the binding one. Fine.
- Under Shape B, if tenants' WABAs are attached to our credit line, the portfolio that carries the messaging limit is the one that owns the numbers. If that portfolio is ours, one tenant's blast can consume the portfolio's limit and starve every other tenant — Meta's own words: "it is possible for one number to consume all of the portfolio's messaging capability within a given period."
This is a capacity-planning constraint on Shape B that the twin card did not name, and it sits alongside its (correct) FIXED-partition caveat: a credit partition caps spend; the messaging limit caps reach; they are different ceilings and both are needed. Added to the open-items list.
Also recorded: Meta's pricing_analytics does not return COST for Messaging
accounts that share a Solution Partner's credit line ("If your Messaging
account shares a Solution Partner's credit line, reach out to your Solution
Partner to understand your charges"). Under Shape B we would therefore be
billing from our own credit line rather than from a tenant-side analytics
read — a real operational difference between the two shapes, and another
reason Shape A is the default.
6. Corrections applied (files)
| File | Change |
|---|---|
whatsapp-cost-metering-model-2026-10-20.md | §5.2 table: overage rate marked AU-only; §5.4 control 2: bid_amount 131 → 13140; two dated correction notes (defect 1, defect 2); §5.5 clauses 2 and 6 (recipient-market rule); §7 open items 8 and 9 added |
wa_metering_model_2026-10-20.py | §9 bid_amount fix + unit derivation + "a bid cap is not a budget"; new §10 market-aware overage table; §10 verdict logic corrected (it compared market rates to each other instead of to the single billed rate) |
Both re-probed after the edit: the script runs, exit 0, and its §10 numbers match an independent cross-check against the committed rate card (Netherlands −A$0.0763, Germany −A$0.0461, AU +A$0.0219, India +A$0.1161, Turkey +A$0.1172 — identical to the table in §3 above).
7. Honest limits of this verification
- Nothing was tested against a live Meta account. Every rate is from Meta's published rate cards and terms, downloaded and parsed in this run. The rates are evidence; the behaviour is not.
- I did not obtain our own credit line, so Shape B's terms are unknown.
- GST treatment of Meta's fees is unresolved (twin card's open item 3) — a ~10% swing on the largest variable cost.
- The AI-Provider clause remains a reading, not a legal opinion (twin card's open item 4). TechCrunch corroborates Meta's own statement that business-CS bots are unaffected, but that is a press statement, not the operative clause read by a lawyer.
- The
marketing_literate card is still unverified (twin card's open item 5) — and note the AUD list-rate card I re-parsed has nomarketing_litecolumn at all, which is direct evidence that the Cloud-API marketing rate and the MM-API marketing rate are not the same published figure. The Cloud API marketing sunset is 13 Oct 2027; new Messaging accounts cannot use Cloud API marketing from 13 Apr 2027. - I did not verify the FIXED-partition exhaustion behaviour — the twin card's open item 1, still Sol's, still blocking Shape B.
- The 150-message allowance remains a judgment, not a derived optimum.
8. Net effect on the card's mandate
The card asked for the allowance-vs-passthrough ruling before the Social add-on GA quote. That ruling exists and stands: hybrid — A$49 WhatsApp platform line including 150 delivered marketing messages/tenant/month, then metered overage at cost + 20%, sold separately from the Social add-on, with the Tech-Provider shape as the default because we cannot be the Bill To Party for tenants' Meta spend without carrying their liability.
The GA quote is unblocked — with two corrections applied first, and with the overage rate now correctly specified as recipient-market + 20%.
But the quote should not go out before: the market-aware overage rate is built (open item 8), the tenant-facing rate presentation is decided (open item 9), and Young's accountant has answered the GST question (open item 3). A rate we cannot invoice correctly is not a quote.
— mira

