What Max-Price Is
The max-price feature on Marketing Messages API for WhatsApp lets you set the maximum price you are willing to pay per marketing message delivery. Meta charges that max-price or lower for each delivered message — never higher. The bid is encoded as a bid_spec object on the template.
There is no change to Meta's per-message pricing model. Max-price is an opt-in optimization knob — you can set it equal to, lower than, or higher than the published rate card to shape your delivery and cost trade-offs.
Rollout Status
| Phase | Window | Who can use |
|---|---|---|
| Limited Beta | Mid-May 2026 onward | Any partner or directly-integrated business — limited number of clients per partner |
| Open Beta | October 2026 onward | Any partner can enable for all clients |
| GA | Q2 2027 | Required in eligible geographies. Fixed published rates only apply on Cloud API thereafter |
The per-message multiplier (see below) is subject to change during beta.
Prerequisites
- WABA onboarded to MM API (see MM API Onboarding)
- WABA in a country eligible for MM API
- Sending through
/marketing_messages(Cloud API rejects templates withbid_spec— error 131061)
How Bidding Works
bid_amount represents your max price per 1,000 deliveries, expressed in your WABA currency's smallest unit (cents for USD, paise for INR, centavos for MXN, and so on).
Three positioning strategies:
| Bid relative to rate card | Likely outcome |
|---|---|
| Equal to published rate | Similar delivery volumes, lower realized cost on optimizable inventory |
| Lower than published rate | Reach broader, less-engaged user cohorts at lower cost per delivery |
| Higher than published rate | Higher delivery rates during peak periods (holidays, sales) at higher cost |
Meta's recommendation: set the bid at the template level, then use the per-message multiplier sparingly. Optimization performs better against the original template-level bid than against multiplier-adjusted bids on every send.
Create a Template with bid_spec
curl 'https://graph.facebook.com/<GRAPH_VERSION>/<WABA_ID>/message_templates' \
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"name": "seasonal_sale_promo",
"category": "MARKETING",
"language": "en",
"components": [
{ "type": "BODY", "text": "Shop our seasonal sale! Up to 50% off selected items." }
],
"bid_spec": {
"bid_amount": "87000",
"bid_strategy": "LOWEST_COST_WITH_BID_CAP"
}
}'
If bid_spec is omitted, the template uses standard rate card pricing — no bidding at all. If bid_spec is present at template creation, it cannot be removed later (you'd have to create a new template without it).
bid_strategy is currently always LOWEST_COST_WITH_BID_CAP.
Calculating bid_amount
Two-step conversion:
- Convert your desired per-delivery price to the currency's smallest unit.
- Multiply by 1,000 (because the field is per 1,000 deliveries, not per delivery).
| Desired per-delivery price | Currency unit | Per-1k value | bid_amount |
|---|---|---|---|
| ₹0.87 | paise | 87 | 87000 |
| $0.05 | cents | 5 | 5000 |
| $0.087 | cents | 8.7 | 8700 |
| ₹2.50 | paise | 250 | 250000 |
Be precise — small rounding errors compound over high volume.
Retrieve and Update Max-Price
Retrieve:
curl 'https://graph.facebook.com/<GRAPH_VERSION>/<TEMPLATE_ID>?fields=bid_spec' \
-H 'Authorization: Bearer <ACCESS_TOKEN>'
{
"bid_spec": {
"bid_strategy": "LOWEST_COST_WITH_BID_CAP",
"bid_amount": 87000
},
"id": "1733678867511493"
}
Update:
curl 'https://graph.facebook.com/<GRAPH_VERSION>/<TEMPLATE_ID>' \
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"bid_spec": {
"bid_strategy": "LOWEST_COST_WITH_BID_CAP",
"bid_amount": 4000
}
}'
You can update bid_spec only on templates that were originally created with it. Adding bid_spec to a template that did not originally have it is not supported — create a new template.
Standard template edit limits apply: 100 edits/hour and 2,400/day on approved templates; unlimited on rejected or paused templates.
Per-Message Multiplier
Per-send adjustment is supported via bid_spec.per_message_bid_multiplier on the /marketing_messages request:
{
"recipient_type": "individual",
"messaging_product": "whatsapp",
"to": "<WHATSAPP_USER_PHONE_NUMBER>",
"type": "template",
"template": {
"name": "seasonal_sale_promo",
"language": { "code": "en" }
},
"bid_spec": {
"per_message_bid_multiplier": "1.5"
}
}
The multiplier is a positive float applied to the template's bid_amount:
1.5→ effective max-price is 150% of template's bid0.5→ 50% of template's bid1(default) → unchanged
A template with bid_amount: 2000 sent with per_message_bid_multiplier: 1.5 has an effective max-price of 3000.
Caveat from Meta: the multiplier is subject to change during beta, and delivery performance often differs from setting the equivalent template-level bid directly even when the effective max-price is the same. Prefer template-level bids for predictability.
Reach Estimation
Meta provides a reach-estimation endpoint that returns expected delivery and cost ranges across multiple bid amounts based on historical data:
curl 'https://graph.facebook.com/<GRAPH_VERSION>/<WABA_ID>/reachestimate?targeting_spec={"geo_locations":{"countries":["IN"]}}&date_interval=L7D' \
-H 'Authorization: Bearer <ACCESS_TOKEN>'
Parameters:
targeting_spec(required) — serialized JSON withgeo_locations.countries, an array of ISO country codesdate_interval(required) — historical lookback:L1D,L7D,L14D,L28D
Response:
{
"waba_currency": "USD",
"estimates": [
{
"bid_amount": 400,
"users": 1000,
"lower_bound_deliveries": 500,
"upper_bound_deliveries": 570,
"cost_lower_bound": 389.74,
"cost_upper_bound": 390.74
},
{
"bid_amount": 520,
"users": 1000,
"lower_bound_deliveries": 600,
"upper_bound_deliveries": 650,
"cost_lower_bound": 400.74,
"cost_upper_bound": 510.74
}
]
}
users is fixed at 1,000 during beta. Cost bounds are in the WABA currency's smallest unit. Estimates are informational only — actual results depend on platform conditions.
Metrics and Billing
Sends with or without bid_spec use the same Marketing Lite SKU for billing. They surface in analytics as:
| API | Field | Value for max-price sends |
|---|---|---|
| Pricing Analytics | pricing_category | MARKETING_LITE (uppercase) |
| Template Analytics | product_type | MARKETING_MESSAGES_LITE_API |
| Status webhooks | pricing.category | marketing_lite (lowercase) |
Webhooks use lowercase, analytics APIs use uppercase. Account for both casings in any code that joins these signals.
Errors
| Code | Meaning | Fix |
|---|---|---|
131061 | Templates with bid_spec cannot be sent through Cloud API /messages | Send through /marketing_messages |
100 | Need to sign the testing legal agreement before sending | Sign Meta's testing legal agreement to gain feature access |
Operational Notes
- Ramp gradually. When sending with a new
bid_spectemplate for the first time, increase volume slowly. Aligns with template pacing best practices and gives the delivery system signal to optimize. - Plan for GA. Once max-price reaches GA in Q2 2027, fixed published rates will only apply on Cloud API. WABAs sending high marketing volume should treat max-price as on the migration path now, not a curiosity.
- Dualhook does not currently expose
bid_specin its template management UI. If you create or update a template directly via Meta withbid_spec, Dualhook will sync the template's other fields, but managingbid_specitself remains a Meta Graph API operation for now.