GhalaGhalaHelp Center
Back to ghala.ioghala.ioSign in
  • Getting Started
    • Ghala Documentation
    • Send Your First WhatsApp Message via API
    • Receiving Events with Webhooks
  • Commerce
    • Start Selling on WhatsApp
    • Set Up the AI Sales Agent
    • Get Paid with Snippe
  • Ai Automation
    • Configuring AI Auto-Reply for WhatsApp
    • Setting Up Human Handover Protocol
  • Campaigns Messaging
    • WhatsApp Message Templates: Complete Guide
    • Bulk WhatsApp Messaging: Complete Campaign Guide
  • Contacts Crm
    • WhatsApp Contact Management Guide
  • Best Practices
    • WhatsApp Customer Support Best Practices
    • Message Template Best Practices
  • Api Reference
    • Ghala Developer API Reference
    • Ghala API vs Meta Cloud API
    • Supported Capabilities
    • Multiple Numbers and Multi-Tenant Platforms
    • Errors and Retries
    • Limits and Quotas
    • Authentication and Access Tokens
    • Connecting and Onboarding a Number
    • Templates and Media
    • Developer Tooling
    • Versioning and Changelog

Products

  • Ghala
  • Sarufi
  • Snippe
  • Sema

Explore

  • Use Cases
  • Pricing
  • Ghala Academy
  • Blog

Developers

  • Docs
  • API Reference
  • API Quickstart
  • Webhooks Guide

Contact

  • SkyCity Mall, 9th Floor, Dar es Salaam, Tanzania
  • info@ghala.io
  • +255 699 920 009
© 2026 Neurotech Company LimitedTerms of ServicePrivacy PolicySitemap
  1. Help Center
  2. Api Reference
  3. Limits and Quotas

Limits and Quotas

v2

Payload caps, pagination, rate limiting, webhook retention, and the Meta limits that ultimately govern how much you can send.

Payload limits

These are enforced by Ghala on the way in, so exceeding one fails fast with 422 rather than being handed to Meta.

Field Limit
text 4096 characters
media_caption 1024 characters
interactive.body Required; the message text above the options
interactive.footer 60 characters
interactive.buttons Up to 3
interactive.button_text 20 characters (list menus; defaults to View)
interactive.sections[].title 24 characters
interactive.sections[].rows 1 to 10 rows in total across all sections
interactive.sections[].rows[].description 72 characters

The row cap is the one that catches people: it is ten rows for the whole menu, not ten per section. Repeated option ids are also rejected, because WhatsApp cannot tell you which one the customer tapped.

Pagination

Parameter Default Maximum
limit 25 100
cursor — Pass next_cursor from the previous response

Pagination is cursor-based, not offset-based. Read until has_more is false; do not assume a page count.

Rate limiting

POST /api/v2/messages returns 429 when WhatsApp is rate-limiting the number. Back off exponentially and retry with the same Idempotency-Key, so a retry cannot become a second message.

Rate limiting is WhatsApp's, not Ghala's. There is no Ghala request-per-minute quota, on any plan. Two consequences:

  • A 429 always originates upstream. It reflects what Meta is allowing that number right now, which moves with the number's messaging tier and quality rating. It is not Ghala throttling you, and it will not be fixed by upgrading your plan.
  • What the plan controls is the API access entitlement, and it is a yes or no. A team without it gets 402 plan_feature_locked on every request; a team with it is limited only by WhatsApp.

There are no X-RateLimit-* headers on responses, and no Retry-After. Use exponential backoff with jitter, starting around 500ms and capping at a few seconds, over a bounded number of attempts.

// 429 and 5xx: back off, keep the same key, give up after a bounded count.
for (let attempt = 0; attempt < 5; attempt++) {
  const resp = await send(body, idempotencyKey);
  if (resp.ok) return resp.json();
  if (resp.status !== 429 && resp.status < 500) throw await resp.json();

  const backoff = Math.min(2 ** attempt * 500, 8000);
  await sleep(backoff + Math.random() * 250); // jitter, so retries do not sync
}

If you are driving a bulk send, pace it yourself rather than discovering the ceiling with 429s. Campaigns in the dashboard already drip rather than burst, which is the behaviour to imitate.

The limits that actually govern throughput

Ghala is not the constraint on how many messages you can send. Meta is, in three separate ways, all of which are properties of your WhatsApp Business Account rather than of Ghala:

Meta limit What it governs
Messaging limit tier How many unique customers you may start a conversation with in a rolling 24 hours. Tiers step up as you send successfully
Quality rating Green, yellow, or red. A falling rating caps your tier and can pause templates
Throughput How many API calls per second Meta accepts for the number
Template quality Per template. quality_score on GET /api/v2/templates turns RED before Meta pauses one

These are managed in WhatsApp Manager, not in Ghala, and they change over time based on how customers respond to your messages. Meta's WhatsApp Business Platform documentation is the authority on the current numbers; anything Ghala printed here would go stale.

The practical consequences for an integration:

  • Watch quality_score. It is the earliest warning available through the API that a template is about to stop working.
  • Expect tiers to change under you. A send volume that worked last month may 429 this month if the rating dropped.
  • The 24-hour window is not a rate limit, but it is the constraint people mistake for one. See the API reference.

Media constraints

Media is sent by public HTTPS URL and fetched by Meta, not by Ghala. So the constraints are Meta's:

  • The URL must be public HTTPS and resolvable from the open internet.
  • Supported formats and maximum file size are per media type and are set by WhatsApp.
  • A URL behind authentication, on localhost, or inside a VPC will fail with 502.

Templates and Media covers formats and sizing in more detail.

Webhook and event limits

Behaviour Value
Endpoint auto-disabled after 20 consecutive failed deliveries
Signature timestamp tolerance 300 seconds
Delivery attempt history retained 7 days (settled attempts are pruned)
Event log retained 30 days
Delivery guarantee At-least-once, unordered
Endpoint scheme Public HTTPS only. http://, loopback, link-local, and RFC1918 addresses are rejected with 400

Acknowledge within a few seconds and process asynchronously; a slow response counts as a failure, and twenty of those in a row disables the endpoint.

Not currently published: the per-attempt delivery timeout, the exact retry schedule and maximum retry count, and the concurrency with which deliveries are made to one endpoint. Design your handler so none of them matter: acknowledge immediately, process out of band, deduplicate on X-Ghala-Delivery, and treat handlers as idempotent.

Retention summary

Data Retained
Event log, including delivered payloads 30 days
Webhook delivery attempts 7 days
Idempotency keys Until the request settles; a failed send releases its key

Thirty days is also how far back a subscriber's history can be reconstructed, so anything you need beyond that should be persisted on your side as it arrives.

What's next

  • Errors and Retries — what to do with a 429 or a 502
  • Templates and Media — formats, sizes, and variables
  • Ghala Developer API Reference — the endpoints
PreviousErrors and RetriesNextAuthentication and Access Tokens

On this page

  • Payload limits
  • Pagination
  • Rate limiting
  • The limits that actually govern throughput
  • Media constraints
  • Webhook and event limits
  • Retention summary
  • What's next