Skip to content

This term

Billing Reconciliation

Matching every billable WhatsApp message in your logs and Meta's pricing data to the invoice, so each charge is explained and each gap is investigated.

Also called: WhatsApp invoice reconciliation · Cost reconciliation · Message billing audit

Often confused with

WhatsApp Invoice

The periodic bill for WhatsApp Business Platform usage, from Meta or a partner, listing delivered messages by account, category and market, plus tax.

Read the WhatsApp Invoice entry

Make a reconciliation export safe to share

Masking hides personal data before it reaches logs and dashboards, while keeping enough to recognise it.

Try

Text with email addresses or phone numbers.

Safe to send to finance or an auditor
2026-10-14 · IN · utility · regular · ••••••••5678 · wamid.HBgMOTE5ODEyMzQ1Njc4FQIAEhgg
Emails
0
Numbers
1
  • Masked 1 phone or long number.
  • Numbers keep their last 4 digits — enough to confirm with a customer, useless to a fraudster.
  • Masking is one-way: do it before text reaches logs, analytics or exports.
Pick a ledger line or an ops note: phone numbers and emails are masked down to their last digits, while the date, country, category and wamid that reconciliation needs stay readable.

What is billing reconciliation?

Billing reconciliation is the process of proving that a WhatsApp invoice is right. Engineering and finance line up three sources — your own send log, the per-message pricing data Meta reports, and the invoice from Meta or your partner — and explain every difference between them. The invoice is the document; reconciliation is the check performed on it, usually monthly and per WhatsApp Business Account, and more often during large campaigns.

The raw material is the status webhook. Each sent, delivered and read status carries the webhook pricing object, whose type (regular, free_entry_point or free_customer_service) and category (marketing, utility, authentication, authentication-international, service and so on) say whether and how that message was charged. Stored once per wamid, these become a ledger with one row per billable message, by category, country and day. The account's pricing_analytics field gives Meta's own aggregate of the same thing: delivered VOLUME and approximate COST in the account's currency, broken down by PRICING_CATEGORY, PRICING_TYPE, COUNTRY and volume TIER.

Reconciling means comparing those layers and giving every variance a reason: template recategorisation that moved a template from utility to marketing, deliveries that landed in a free entry point window, service replies that fell inside a number's monthly free tier of 1,000, a volume tier that lowered the rate mid-month, an authentication-international charge, late or duplicate webhooks, a rate change on the first day of a quarter, or a partner's markup, platform fee and GST on top of Meta's charges. When a partner's credit line pays for the account, Meta does not return COST in pricing analytics, so the partner's invoice and your own ledger carry the money side.

Key takeaways

  • Billing reconciliation proves a WhatsApp invoice right by matching your send log, Meta's pricing data and the invoice line by line.
  • Book one ledger line per wamid, from the delivered or read status, only when pricing.type is regular.
  • pricing_analytics gives Meta's delivered volume and approximate cost by category, pricing type, country and tier.
  • Typical variances: recategorised templates, free entry point deliveries, the 1,000-a-month service tier, volume tiers, rate changes and partner fees.
  • Accounts on a partner's credit line get no COST in pricing analytics, so the partner's invoice carries the money side.

How does billing reconciliation work?

  1. Step 1

    Log intent at send time

    For every send, store the wamid, template name, the category you expected, the recipient's country as its own column and a cost centre or campaign tag. This is the baseline everything else is compared with.

  2. Step 2

    Book delivered pricing lines once

    From status webhooks, record pricing.type and pricing.category when a message is delivered or read, whichever arrives first, keyed by wamid. Apply webhook deduplication — Meta retries webhooks and sends pricing on several statuses.

  3. Step 3

    Aggregate in the invoice's terms

    Group billable lines by category, country and day, in the same time zone and currency as the invoice. Volume tiers reset at 00:00 in the account's time zone, so month boundaries must match it.

  4. Step 4

    Compare with pricing analytics

    Pull pricing_analytics for the same period with DAILY granularity and the same dimensions. Volumes should agree closely once deduplication and time zones are right; costs are Meta's approximation.

  5. Step 5

    Tie out to the invoice

    Apply the rate card to the billable counts — plus your partner's fees and GST if a partner bills you — and compare with the invoice total, category by category.

  6. Step 6

    Explain and act on every variance

    Give each difference a reason code, fix what is yours (recategorised templates, booking bugs, missing webhooks) and raise what is not with your partner or Meta, with the wamid list as evidence.

Billing reconciliation in code

-- One row per billable delivery, booked once per wamid from status webhooks.
SELECT
category, -- pricing.category, not the template's requested category
country, -- stored separately from the phone number
COUNT(*) AS billable_messages
FROM wa_billing_ledger
WHERE pricing_type = 'regular'
AND delivered_at >= TIMESTAMPTZ '2026-10-01 00:00+05:30' -- the account's time zone
AND delivered_at < TIMESTAMPTZ '2026-11-01 00:00+05:30'
GROUP BY category, country
ORDER BY category, country;

Your side of the comparison: billable deliveries for October 2026, by category and country.

Common mix-ups

Common mistakes with billing reconciliation

  • Summing every webhook that carries pricing

    The pricing object rides on sent, delivered and read, and Meta retries webhooks. Book one line per wamid or your ledger will run well above the invoice.

  • Mixing time zones at month end

    Webhook timestamps are UNIX seconds, while invoices and volume tiers follow the account's time zone. Messages sent near midnight on the last day land in the wrong month unless you convert.

  • Reconciling against the requested category

    Meta can approve a template in a different category or recategorise it later. Compare with pricing.category from the webhook, which is what billing used.

  • Treating analytics cost as exact — or expecting it at all

    Meta describes COST as approximate, and it is not returned for accounts on a partner's credit line. Use it as a cross-check; the invoice is the authority.

  • Shipping raw phone numbers to finance

    Reconciliation exports need dates, countries, categories and wamids, not full numbers. Apply PII masking before the file leaves engineering and keep country as its own column.

Example: A 12,000-message gap at a Gurugram brand

A Gurugram D2C brand's October invoice shows 412,000 marketing and 96,000 utility messages, while its campaign log expected 400,000 and 110,000. Reconciliation explains both lines. Two order-update templates had been recategorised to marketing after Meta's review, so about 12,000 sends moved from the utility column to marketing — the ledger's pricing.category showed it, the requested category did not. Another 2,000 utility messages expected by the log were never delivered, so they were never charged. The team rewrites the two templates as pure order updates and starts alerting on template category updates.

Why the difference matters

Why does billing reconciliation matter?

WhatsApp spend scales with every campaign, and small errors compound: a mis-categorised template, a webhook handler that books reads as new deliveries, or a missed rate change can move a monthly bill by lakhs without anyone noticing. Reconciliation turns the invoice from something you pay into something you can explain — and it is the evidence you need to raise a billing dispute, charge costs back to teams or clients, and trust the cost-per-message figures marketing plans with.

Billing reconciliation: key facts and limits

Join key
wamid
Billable test
pricing.type = regular on delivered or read
Meta's aggregate
pricing_analytics field on the WABA
Granularity options
HALF_HOUR, DAILY, MONTHLY
Analytics cost
Approximate, in the account's currency
Partner credit line
COST not returned — use the partner invoice
Rate changes
Only on the 1st of a quarter

Rules of thumb

Best practices for billing reconciliation

  • Store the raw pricing object with each wamid so any report can be rebuilt later.
  • Reconcile weekly during big campaigns, not only at month end.
  • Keep a variance log with a reason code for every difference you explain.
  • Alert when marketing's share of billable messages jumps — recategorisation is the usual cause.

Billing Reconciliation FAQs

How close should my ledger be to Meta's numbers?+
Delivered volumes should agree closely once you deduplicate by wamid and align time zones. Costs in pricing analytics are approximate, so small money differences are normal; the invoice is the final word.
Why does pricing analytics show volume but no cost for my account?+
Meta does not return COST for WhatsApp Business Accounts that use a Solution Partner's credit line. Reconcile money against the partner's invoice instead.
How is this different from reading the invoice?+
The invoice states what you owe. Reconciliation checks it against message-level evidence — your send log and Meta's pricing data — and explains every difference.
Do inbound messages need to be reconciled?+
No, they are never billed. They matter indirectly: each one opens a 24-hour window, and your free-form replies inside it are billable service messages once the number has used its monthly free tier of 1,000.

See InfiQ pricing

Try it on the official WhatsApp Business API

InfiQ is an official Meta Business Partner. Start a 7-day free trial — no card needed — and see this running on your own number.