Skip to main content
Every account can send on every channel, to any destination, from its first minute. Verification is not a permission to send: it raises how much you may send per day. What stands in front of an individual message is the message itself — its content, and the pattern of sends around it.

Account levels

A level decides your daily ceilings. It never decides which channels or destinations you may reach. Business verification is required for one thing: registering a 10DLC brand and campaign. Every sms and sms_oneway message to a +1 number needs an approved campaign, and carriers register a campaign against a vetted legal entity. Sending to a +1 number without one returns 403 with code ten_dlc_required. No channel asks for KYB in order to send. Accounts created before 24 August 2026 start at Verified.

Raising your ceilings

Do any one of these in the dashboard. Each is self-serve:
  • Verify your identity under Identity verification (/kyc): an ID document and a selfie, a few minutes.
  • Add a payment method under Billing: about half a minute. Nothing is charged.
  • Settle a deposit under Billing.
  • Subscribe to a paid plan.
Any one of them moves the account to Verified. Identity or business verification is what raises the SMS ceiling to 10,000 a day — see the note under the table.

Daily ceilings

Channels that share a budget share one counter. Counts reset at 00:00 UTC.
  • The SMS ceiling above Sandbox keys on identity, not on the level: an account that reached Verified by saving a card sends 200 a day until its identity or business verification is approved. A higher limit can be agreed for an account.
  • Email has no verification gate on single sends. A sender with a verified domain sends from day one, within the plan’s quota: 100 a day and 3,000 a month on Free.
  • A daily ceiling never reduces a monthly allowance: 100 a day on the conversational group still reaches the 2,000 messages a month Free includes.
  • Broadcasts count each recipient against the same ceiling. Recipients beyond it are marked failed with errorCode DAILY_LIMIT_EXCEEDED and are not retried the next day.

Monthly allowance on the app channels

whatsapp, telegram, instagram and messenger share one monthly allowance: 2,000 messages on Free. Paid plans have no message cap. The counter resets on the 1st at 00:00 UTC. It counts messages in both directions. A message a contact sends you consumes one unit exactly as a message you send them does. This is the part that surprises people: a project that has sent 300 messages and received 1,700 has used the whole allowance, and the figure on the dashboard will not match a count of your own sends. The plan card breaks the total into received and sent for that reason. What does not count:
  • Messages you send from the WhatsApp Business App on your own phone while coexistence is on. Meta mirrors them to Zavu so they appear in your inbox, but Zavu did not send them and does not count them.
  • Failed sends. An outbound message counts when it is accepted by the channel, not when it is created.
  • SMS, voice and email. Each is billed or metered on its own terms; see the daily ceilings above and your plan’s email quota.

What happens at the cap

On Free, both directions stop:
  • Sending is refused. POST /v1/messages answers 429 a2p_limit_exceeded, and so does every other way of sending: the dashboard composer, an inbox reply, a group reply, a reaction, an AI agent’s reply, and each remaining recipient of a broadcast (marked failed with errorCode A2P_LIMIT_EXCEEDED).
  • Receiving is refused too. An incoming message on those channels is not stored, does not appear in your inbox, and fires no message.inbound webhook. It is not delivered later when the month resets. We email the team the first time this happens in a month.
Sending and receiving resume on their own when the counter resets, or immediately on a paid plan.

Risk review

Every outbound sms, sms_oneway, email and voice message is read before it is sent: the content, and how the account has been sending lately. A broadcast is read once, on its own text, rather than once per recipient. Three things can follow. It is sent. Nothing appears in the API, and this is what happens to ordinary traffic. It is held. The message waits for a person. It stays queued while it waits — there is no new status for a hold, and MessageStatus is unchanged — so code that polls GET /v1/messages/{messageId} or listens for the webhooks needs no change. Approved, it sends normally and delivery continues as usual. The window is a couple of hours, not days: a one-time code that arrives late is worse than one that never arrives. It is refused. The message moves to failed and fires message.failed. errorCode says which happened: An SMS that fails any of these ways is not charged: the prepaid amount is returned to your balance. Two rules worth knowing before they surprise you:
  • A call is never held. A call cannot arrive two hours late, so a call the review stops is failed rather than placed. It ends with status failed.
  • A message that cannot be read is held rather than sent. When the content check is briefly unavailable, the safe answer is to wait for a person. An account with an approved business verification is unaffected, and so is one that has verified something, already sends real traffic, and has a clean recent record.
If a message was refused and you believe it should not have been, contact support with the message ID.

Errors

a2p_limit_exceeded (429)

Returned by POST /v1/messages and POST /v1/messages/{messageId}/reactions when the month’s allowance on the app channels is spent. Free plans only: a paid plan is never refused for volume.
Distinct from daily_limit_exceeded, which clears at 00:00 UTC. This one clears on the 1st of the month, or the moment the account moves to a paid plan.

daily_limit_exceeded (429)

Returned by POST /v1/messages and POST /v1/calls when the channel group’s ceiling for today is spent.
details.limit is the ceiling that applied. Wait for 00:00 UTC, or raise it: identity verification or a payment method for the SMS, voice and conversational groups, a plan upgrade for email.

sending_suspended (403)

Returned by POST /v1/messages and POST /v1/calls when an account’s sending has been suspended after the review refused several of its messages. Every channel is refused while it lasts, and a message already queued fails with errorCode SENDING_SUSPENDED.
A suspension is lifted by a person. Contact support; waiting does not clear it.

ten_dlc_required (403)

Returned by POST /v1/messages on sms and sms_oneway when the destination is a US or Canadian (+1) number and the project has no approved 10DLC campaign. Register a brand and a campaign in the dashboard; both need an approved business verification. See 10DLC.

Test-mode keys

A zv_test_ key is separate from the levels above, and narrower than they are. Whatever the account has proven:
  • WhatsApp by default. Without a configured sender the key sends from Zavu’s shared sandbox number, and any other channel is refused with 400 Sandbox mode only supports WhatsApp.
  • Only to a phone on your team. On WhatsApp, Telegram, Instagram and Messenger the recipient must be a phone number verified in your account. Anything else is refused with 403.
  • No calls. POST /v1/calls refuses a test key with 400.
A number is verified from the phone itself, which is what makes the check mean something:
  1. In the dashboard, go to Sandbox and click Generate Verification Code.
  2. Scan the QR code or click Open WhatsApp on the phone you want to verify.
  3. Send the pre-filled VERIFY- message to Zavu’s sandbox number.
The number is marked verified automatically. Up to 5 numbers per project; a code expires after 10 minutes. There is nothing to type into the dashboard, no API call, and no support ticket. The messages are delivered for real — a test key changes who you can reach, not whether the message arrives.

Next Steps

Quickstart

Send your first message

Rate Limiting

Per-minute API request limits