kenari.dev

Throughput & quality#

Meta sets the sending limits for every WhatsApp number. kenari doesn't raise or lower them. It shows them in the dashboard and sizes its own per-number rate limit from them, so that bursts are stopped at kenari instead of being rejected by Meta.

Meta's three signals#

SignalWhat Meta means by itWhere you see it in kenari
Throughput levelHow many messages per second the number may sendThroughput on the Numbers page (throughput_level)
Messaging limit tierHow many people the business can start conversations with in a rolling 24 hoursShown after the throughput level (messaging_limit_tier)
Quality ratingMeta's rating of recent messaging, based on how recipients respond: GREEN, YELLOW, RED or UNKNOWNQuality on the Numbers page (quality_rating)

kenari shows the values exactly as Meta reports them. It updates them when:

  • Meta sends a phone_number_quality_update or phone_number_name_update webhook for the number
  • you choose Refresh from Meta in the number's ⋯ menu (at most once every 10 seconds)

Subscribe an endpoint to phone_number_quality_update and account_alerts if your own systems need to react to these changes. See Webhooks.

What kenari adds: a per-number rate limit#

Each number has a token bucket in front of Meta. It's sized from the number's throughput level:

NumberBucket size
Coexistence number20 messages per second
Throughput level HIGH1,000 messages per second
Any other or unknown level80 messages per second

The bucket holds one second's worth of requests and refills continuously. A number can therefore burst up to its full size at once, then keeps sending at the steady rate. When Meta reports a new throughput level, kenari resizes the bucket.

Which calls count#

CallsLimit
POST or PUT to a number's /messages, and POST to its /mediaThe number's bucket above
Everything else through the proxy (templates, media reads, WABA reads)5,000 per hour per WABA

When you hit the limit#

kenari returns 429 with a KenariThrottleException right away. The request never reaches Meta, and kenari doesn't queue or retry it for you.

json
{  "error": {    "message": "Rate limit reached for this number.",    "type": "KenariThrottleException",    "code": 1006,    "fbtrace_id": "<kenari request id>"  }}

Every response that reaches the rate-limit step (see Rate limits), including the 429, carries these headers:

HeaderMeaning
RateLimit-LimitBucket size
RateLimit-RemainingRequests left right now
RateLimit-ResetSeconds until the bucket is full again
Retry-AfterOnly on a 429: seconds to wait before retrying

Wait for Retry-After before sending again, and spread large sends out rather than firing them all at once.

What kenari doesn't change#

  • Messaging limit tier. kenari doesn't count conversations or enforce the tier. When you exceed it, the error comes from Meta.
  • Quality rating. kenari doesn't send on your behalf or change what you send, so your rating depends only on your messaging.
  • Tier upgrades. Meta upgrades or downgrades tiers based on the number's history and quality. Connecting through kenari doesn't speed that up or slow it down.
  • Meta's throughput. kenari's bucket never allows more than the size above, and Meta can still reject sends at its own limit.

Low quality warnings#

When a number's quality rating becomes RED:

  • the Numbers page shows Message quality is low. Review recent messaging before sending more.
  • kenari notifies the account

A RED rating doesn't stop kenari from proxying sends. Check Meta's guidance and your recent templates and opt-in practices before you send more.

If Meta restricts or temporarily blocks the number, its status on the Numbers page changes to Restricted or Flagged. See Number status.