Features Pricing Use cases Compare Blog

Reading What Meta Actually Charged You - Unless Your Provider's Credit Line Blocks It

14 min read

The short answer

Meta's analytics endpoints return a COST field, but not for WhatsApp Business Accounts sharing a Solution Partner's credit line, where Meta's own documentation tells you to ask that partner instead. Every message status webhook also carries a pricing object with billable, pricing_model, type and category, so charges can be reconciled message by message without touching the endpoint at all.

A workspace billing screen showing the current plan's contact-quota slider, a monthly figure stated in rupees, a usage bar comparing contacts used against the allowance, and an invoice table listing each invoice's status beside a pay action, inside a seeded demo workspace rather than a real customer's account.

What does Meta's analytics endpoint return about money?

Meta's Business Management API publishes a family of analytics fields against a WhatsApp Business Account: analytics for sent and delivered counts, conversation_analytics for conversation counts and cost, pricing_analytics for a pricing breakdown by message type, and template_analytics for how a template performed. Cost is not an afterthought here - it is a first-class metric, queryable per WABA, per time window, per category.

That is genuinely useful. A business on its own Meta credit line can pull conversation_analytics or pricing_analytics and get back a COST figure for any slice of time and message category - marketing, utility, authentication, service - straight from Meta's own billing record, rather than waiting on an invoice.

The catch is one sentence, repeated across more than one of these endpoints rather than tucked away once: "COST will not be returned for WABAs that share a Solution Partner's credit line" (Meta - WhatsApp Business Analytics). The same qualifier appears under both the conversation analytics and pricing analytics metric descriptions - not a caveat on an obscure field, but a condition attached everywhere the API would otherwise hand back a number in currency.

Checked against Meta's documentation on 4 September 2026.

Why would your own cost data be withheld from you?

Read plainly, the sentence says Meta will not tell you what your own messages cost if the account that sent them shares its credit line with a partner. "Credit line" is not a loose metaphor for "your provider handles billing" - it names a specific Meta billing arrangement. A Solution Partner (Meta's tier above Tech Provider, formerly a BSP) can extend its own line of credit with Meta across multiple client WABAs, billed by Meta and billing its own customers however it likes. Meta's own guidance is direct about the alternative: "reach out to your Solution Partner to understand your charges" (Meta - WhatsApp Business Analytics).

Meta is not withholding this figure out of caution or a bug - in that billing shape, Meta itself is not who charged you. The Solution Partner is the counterparty on the invoice; Meta settles with the partner, not with you, so it will not show you a number it does not consider yours to see.

This is the distinction our guide on the difference between a BSP and a Tech Provider explains - the vocabulary shift from BSP to Solution Partner changed nothing about what the tier authorizes. A Tech Provider - the tier WabaCRM holds, verified 30 July 2026, and the reason its own pricing page charges for software rather than messages - has no such credit line with Meta. Every WhatsApp Business Account a Tech Provider connects bills Meta directly, on that business's own card - no shared credit line for Meta to invoke the exception against, so the COST field simply returns.

How does a credit line decide what you are allowed to see?

The credit line is not a setting a partner flips on or off in a dashboard - it is a property of how the WABA is billed at Meta's end, set at connection time and read by the analytics API automatically. A provider cannot "turn on" your COST field if the account shares their credit line; it stays unavailable at the API level regardless of which of the four questions below you ask.

Question Own credit line (Tech Provider model) Shared Solution Partner credit line
What did this message cost? COST returned by conversation_analytics / pricing_analytics Withheld; Meta directs you to the partner
Which volume tier am I in? Queryable via the pricing_analytics TIER dimension Same field, same access - tier data is not scoped by credit line
How far back can I look? 1 year (messaging/conversation/pricing), 90 days (templates) Same window - unaffected by credit line
Who answers when the figures disagree? Meta, with your own COST figure in hand Your Solution Partner, by Meta's own instruction
Two-column comparison of what a WhatsApp Business Account can see about its own charges depending on whether it holds its own Meta credit line or shares one with a Solution Partner, across four billing questions.
Same four questions, two different answerable sets

Three of those four rows are identical regardless of billing shape - volume tier, lookback window and endpoint access do not care who holds the credit line, only the money figure does. Meta drew the line at exactly the one field that would otherwise show you a number it is not, in that arrangement, the party who charged you.

What does the pricing object on a status webhook contain?

This is separate from the above: the pricing object attached to every outgoing message's status webhook arrives at your own server the moment Meta updates that message's delivery state. It is not an aggregate and it is not filtered by credit line - it rides on the webhook for that specific message, sent to whichever endpoint you configured, regardless of who bills whom upstream.

A billable message looks like this in the payload:

"pricing": {
  "billable": true,
  "pricing_model": "PMP",
  "type": "regular",
  "category": "<PRICING_CATEGORY>"
}

billable says whether the message was charged. pricing_model records which billing regime applied - "PMP" for per-message pricing, or "CBP" for the legacy conversation-based pricing Meta retired on 1 July 2025, still surfacing in one narrow edge case below. type distinguishes a charged send ("regular") from a free one, and category names which rate category applied - marketing, utility, authentication or service.

Checked against Meta's documentation on 4 September 2026.

This object is not subject to the Solution Partner exception: Meta withholds the aggregated COST metric, not the per-message pricing classification, so on a shared credit line the status webhook is still the one door Meta left fully open on your own server.

Which field values mean a message was free?

Two shapes both mean "you were not charged," and it is worth telling them apart - they arise from different rules. A non-template message sent inside an open 24-hour customer service window has been free since 1 November 2024, when Meta made service conversations free for all businesses. Its pricing object reads:

"pricing": {
  "billable": false,
  "pricing_model": "PMP",
  "type": "free_customer_service",
  "category": "service"
}

A free utility template - any one sent to a customer within an already-open customer service window - carries the same free_customer_service type but with category set to utility instead; this is the current PMP rule and holds until 1 October 2026. A narrower edge case sits alongside it: a utility conversation opened before 1 July 2025 that was still open when Meta switched to per-message pricing carries pricing_model: CBP rather than PMP for as long as that conversation stays open.

Meta documents the underlying rule for that second case precisely: "If you send a message to a WhatsApp user prior to July 1, 2025 ... a utility conversation is opened between you and a user that spans the switch to per-message pricing ... In this case, utility templates sent to the user after the switch while the conversation is open will be free, but attributed to the open conversation" (Meta - WhatsApp Pricing).

Read that precisely rather than generously - it is a closing-out rule for conversations already mid-flight on the day pricing changed, not a parallel legacy track a business can opt into, and it thins with time as those conversations close on their own. For how a template's category gets decided, and what happens when Meta reclassifies one, see a template's category changing from utility to marketing.

billable: false is the field to key any reconciliation logic on, rather than trying to infer "free" from category or type alone, since both free shapes above still carry a normal-looking category value.

How far back can you query, and when did that change?

This is a genuine shrink, and it is dated rather than gradual. Meta's WhatsApp Business Analytics documentation states it exactly: "Starting December 1, 2025, the maximum lookback window for messaging, conversation, and pricing analytics is changing from 10 years to 1 year. The lookback window for template and template group analytics will be unaffected and will continue to be 90 days." (Meta - WhatsApp Business Analytics).

Two different clocks, worth keeping straight:

Analytics type Lookback window Changed on
Messaging, conversation, pricing analytics 1 year 1 December 2025 (was 10 years)
Template and template group analytics 90 days Unchanged

Ten years meant, in practice, "keep whatever you need, query it whenever." One year is a real limit - a business reconciling a full financial year's spend against its own accounting records must now do so within that year. Template performance was never generous either - 90 days has applied all along, so its click and read history must be pulled and archived quarterly to survive past the quarter it ran in.

Checked against Meta's documentation on 4 September 2026.

Neither window depends on whether a WABA shares a Solution Partner's credit line - the shrink applies uniformly; only the COST field is conditional on billing shape.

Does the webhook tell you which volume tier you are in?

Meta's own documentation disagrees with itself across two of its own pages, and it is worth naming plainly rather than quoting the convenient half. The pricing updates page states: "Starting October 1, 2025, an account_update webhook with event set to VOLUME_BASED_PRICING_TIER_UPDATE will be triggered when your WhatsApp Business account reaches a new volume tier, in any market, in a given month" (Meta - Pricing Updates). The WhatsApp Business Analytics page carries an older sentence that has not been updated to match: "tiering information is not included in any webhooks. Use the pricing_analytics field to get tiering information for delivered messages." (Meta - WhatsApp Business Analytics).

Both sentences are Meta's own words, and they say opposite things. The honest reading is that the second is stale - written before the October 2025 event existed, never removed once it shipped - not that the first is wrong. A live, dated, named webhook event is a stronger signal than an undated disclaimer on a different page, and a reader relying on either sentence alone would come away only half right.

In practice: the account_update event tells you that your tier changed and to what, the moment it happens, for any market. The pricing_analytics TIER dimension tells you tier information for delivered messages only - useful for reconstructing which rate applied to a batch of sends, not a general lookup. Neither is affected by credit-line sharing; tier visibility, unlike cost visibility, is not gated by who bills whom.

How do you reconcile Meta's figures against your own send records?

The most reliable source is not the analytics endpoint - it is the pricing object on every status webhook: not subject to the Solution Partner exception, arriving at message granularity rather than a monthly aggregate. A shared credit line can take your COST metric; it cannot take the pricing object Meta is already sending you.

Store billable, pricing_model, type and category alongside your own record of every send, keyed on the message id. Sum the messages where billable is true, grouped by category, for a cost breakdown built from the same field values Meta's own billing runs on, not from a provider's summary.

Message log filters for date range, number, status and direction sitting above a dense table of individual messages, each row showing a timestamp, recipient, delivery status and a failure-reason column, with an export control nearby.
Per-message records, the level a webhook-built reconciliation actually needs

This is the level message logs exist at for this reason - a per-message record with status and a reason, exportable, rather than a total with no way back to the messages behind it. If a provider's monthly total and your own billable count disagree, the discrepancy is findable there: a message sent but not billable, a status update that never arrived, or a category mismatch. None of that requires Meta's COST field to be visible - which is why the withholding above costs less than it sounds like it should.

How would you measure the October change before it lands?

Meta's non-template pricing documentation is specific about what changes on 1 October 2026: "Meta will charge on a per-message basis for service messages" and "Meta will charge on a per-message basis for utility messages sent in response to users within an open 24-hour customer service window," adding that "these messages have not been charged since July 1, 2025." Service messages have been free in that window since 1 November 2024; utility templates in that window have been free since the 1 July 2025 per-message pricing switch. Both stop being free on 1 October 2026. The same page states plainly that there are no volume tiers for this: "Volume tiers: None. Meta does not offer volume tiers for service messages."

The measurement is straightforward with per-message reconciliation already in place, and difficult without it. Before 1 October 2026, filter your webhook-derived records for messages where type is free_customer_service - both the service-window replies and the free utility templates - and count them by week. That count, multiplied against whatever category rate applies once the free period ends, is your own estimate of the change's cost, built from your own traffic rather than a guess. Meta's pricing tables carry the actual rate figures, which is why WabaCRM's own guide to per-message rates in India is the page to check them against, not this one - a rupee figure quoted here would go stale by the date it describes.

A business tracking billable: false counts has a real forecast weeks before the invoice arrives; one that only saw a provider's monthly total cannot isolate this line item until it shows up - the same gap that makes the INR billing migration deadline worth tracking early too.

What should you ask a provider before signing, about billing visibility?

Three questions, each answerable in one sentence:

Does my WhatsApp Business Account bill directly on my own card at Meta, or does it share your credit line? This one answer decides whether Meta's COST field will ever be visible to you, and it is fair to ask outright - it is a matter of Meta account structure, not a trade secret.

Do you forward the status webhook's pricing object to me, unfiltered, at message granularity? A provider giving only a monthly total is choosing not to pass through data Meta already gives them on every send - nothing stops a billable/pricing_model/category breakdown reaching your own systems.

If your figures and Meta's disagree, who resolves it? Under a shared credit line, Meta's own documentation already answers this - your partner does, not Meta. Anyone claiming otherwise should be able to point at Meta's dashboard producing a COST figure in your name - which, per the documentation above, it will not.

This is not an argument that a Tech Provider is more trustworthy than a Solution Partner - the tiers serve different scales of operation, and the guide on that distinction covers what each is built for. It is an argument that the billing shape you sign up under has a checkable consequence for reading your own WhatsApp costs back from Meta - worth asking before the account is connected, not after the first invoice you cannot reconcile. For what actually costs money on the platform to begin with, see our guide on that question; for moving a WABA off the wrong side of this credit-line question, see the piece on switching providers.

Every Meta quotation on this page was read from Meta's own documentation on 4 September 2026. Meta changes that documentation without notice; the linked pages are authoritative and this one is not.

Questions people also ask

Can I get per-message cost data if I am on a reseller's plan?

Meta's documentation is direct: "COST will not be returned for WABAs that share a Solution Partner's credit line." If your account bills through a partner's shared credit line rather than your own, the field returns empty and Meta points you elsewhere instead, telling you to "reach out to your Solution Partner to understand your charges." This has nothing to do with whether you can see message volume or the pricing object on individual status webhooks - those still arrive normally. It is specifically the aggregated COST metric that Meta withholds, because Meta does not hold the billing relationship with you; your partner does. A WABA billing directly on its own card never triggers this.

Does the analytics API count messages my provider sent on my behalf?

Yes. The analytics endpoints report on the WhatsApp Business Account, not on which piece of software issued the send call. Every message sent through your number - whether triggered from your own dashboard or dispatched by automation your provider runs for you - is billed to whichever WABA it ran on, and counted in that account's messaging, conversation and pricing analytics the same way. What changes under a shared credit line is not which messages get counted, but whether the COST figure attached to them is shown to you or reserved for the partner who holds the actual billing relationship with Meta.

How long does Meta keep template performance data?

Ninety days. Meta's WhatsApp Business Analytics documentation states that the lookback window for messaging, conversation and pricing analytics shortened from ten years to one year, effective 1 December 2025, but adds that "the lookback window for template and template group analytics will be unaffected and will continue to be 90 days." So sent, delivered, read and click figures for a specific template are only ever queryable for the trailing three months. If you want a longer performance history than that, you need to export and store the numbers yourself before the window closes, because Meta will not hold them for you.

Do free-tier messages appear in the analytics response at all?

Yes - they appear, they just carry a zero cost and a label explaining why. On a status webhook, a free service-window reply reports `"billable": false, "pricing_model": "PMP", "type": "free_customer_service", "category": "service"`, and a free utility template sent inside an already-open conversation carries the same free_customer_service type with category set to utility instead. The analytics endpoints preserve the same distinction through their own pricing-type values. A month with no billable traffic still produces a complete, auditable record; being unbilled does not remove a message from the count.

Why do my provider's totals differ from Meta's?

A few honest possibilities before assuming an error: your provider may count from the moment it queued a message rather than from Meta's own delivery timestamp, apply its own currency conversion or rounding, or fold in software fees Meta never charged in the first place. If your WABA shares that provider's credit line, you cannot pull Meta's own COST figure yourself to settle the disagreement independently - the documentation routes that question back to the provider by design. The one number you can always check yourself, regardless of credit line, is the pricing object attached to each status webhook, because that arrives at your own server.

What access does the analytics endpoint need?

A valid access token for the business that owns the WhatsApp Business Account, with permission to read that account's business analytics, plus the WABA ID itself in the request path. This is separate from message-sending permission - reading analytics does not require the ability to send messages or manage templates, and Meta scopes the read to whichever business token is calling it. On a WABA sharing a Solution Partner's credit line, the token still authenticates the request normally; it is only the COST field in the response that Meta withholds, not access to the endpoint itself.

Keep reading

Your customers are already on WhatsApp

Free for your first 1,000 contacts, with no time limit and no card. Setting up the workspace takes minutes; connecting a number takes as long as Meta's own review of it.

Sign up with your company email address. No sales call, no onboarding fee, nothing to schedule.

Why this is safe to point your customer list at

Payments are processed by Razorpay on their own checkout — your card details are never entered on, or stored by, WabaCRM. Every inbound WhatsApp webhook is checked against its signature before it is trusted.

Tech Provider is a Meta platform access tier — not a partnership, a reseller agreement or an endorsement.