Message quota events
Events related to the per-number message quota, measured against the
organization’s current billing cycle (cycle_start/cycle_end).
Limits per plan: Free 300,
Lone Wolf 1,800, Business 50,000 and Custom 500,000 per number, per cycle.
The message quota is per number, like the contact quota: each linked number (main or an extra alias) has its own allowance, and an account with N numbers has N times the plan’s allowance. These events identify the affected number by the number_alias of the envelope (not in data). Only messages sent through Turbo Notify (origin: "tn") consume the quota.
To configure the webhook URL, validate the signature and understand the envelope, see Webhook: setup and envelope.
Events
| Event | When |
|---|---|
message.quota.warning | Crossed the 80, 90 or 95% threshold of the number’s message quota |
message.quota.exceeded | Attempt rejected because the quota is exhausted (HTTP 429) |
number_alias in the envelope
Both events carry, right below organization_id, the number_alias field: the identifier of the Turbo Notify number whose message quota was reached ("main" for the main number or the alias of an extra number). The event data carries the quota fields threshold_percent (only in warning), used, quota, cycle_start, cycle_end, resets_at, tier, channel, origin. number_alias sits in the envelope, never inside data.
used/quota are measured against the organization’s evaluated billing cycle (cycle_start/cycle_end, ISO 8601 UTC); resets_at equals cycle_end.
threshold_percent is the percentage of the quota reached, as an integer: 80, 90 or 95 (80 means 80%). An exhausted quota does not arrive as threshold_percent: 100: it arrives as the message.quota.exceeded event, which has no such field.
Among the account events,
number_aliasis omitted instorage.*and inmedia.unavailable. The whole*.quota.*family (contacts and messages) carries this field.
Example: message.quota.warning
{ "id": "evt_...", "type": "message.quota.warning", "organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4", "number_alias": "main", "number_id": "num_0a1b2c3d4e5f60718293a4b5c6d7e8f9", "created_at": "2026-06-20T12:00:00Z", "data": { "threshold_percent": 80, "used": 240, "quota": 300, "cycle_start": "2026-06-01T00:00:00Z", "cycle_end": "2026-07-01T00:00:00Z", "resets_at": "2026-07-01T00:00:00Z", "tier": "FREE", "channel": "whatsapp", "origin": "tn" }}Example: message.quota.exceeded
{ "id": "evt_...", "type": "message.quota.exceeded", "organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4", "number_alias": "main", "number_id": "num_0a1b2c3d4e5f60718293a4b5c6d7e8f9", "created_at": "2026-06-20T12:00:00Z", "data": { "quota": 300, "used": 300, "cycle_start": "2026-06-01T00:00:00Z", "cycle_end": "2026-07-01T00:00:00Z", "resets_at": "2026-07-01T00:00:00Z", "tier": "FREE", "channel": "whatsapp", "origin": "tn" }}Timestamps and correlation
- These events are generated by Turbo Notify itself (they do not reflect an action on WhatsApp): they do not carry
atindata, only the envelopecreated_at(moment Turbo Notify emitted the event). cycle_start/cycle_endare the evaluated billing cycle against whichused/quotawere measured.resets_atis the moment the quota count starts over: equal tocycle_endat emission, it is not the moment something happened.- There is no
phonein the content of these events. To correlate with the request that triggered the overflow, useGET /v1/events?request_id=req_....
Recommended action
- Move to a larger plan (see the plan table in Quota and usage).
- Follow, in the dashboard under Usage, the consumption of each number in the current cycle.