WhatsApp API Rate Limit: Batasan yang Perlu Diketahui

Panduan rate limit WhatsApp API. Batasan pesan, cara handle limit, dan strategi untuk avoid throttling. Developer guide!

WhatsApp API Rate Limit
WhatsApp API Rate Limit

Kirim terlalu banyak pesan = Kena limit!

Semua API punya rate limit. Pahami batasannya supaya aplikasi kamu tidak di-block.


Jenis Rate Limit

1. WhatsApp Cloud API (Official)

MESSAGING LIMITS:

Tier 1 (New): 1,000 messages/24 hours
Tier 2: 10,000 messages/24 hours
Tier 3: 100,000 messages/24 hours
Tier 4: Unlimited (dengan approval)

Cara naik tier:
- Quality rating bagus
- Volume konsisten
- Tidak banyak block/report

2. WhatsApp Business API (On-Premise)

Throughput: 80 messages/second
Template messages: Tergantung tier
Session messages: Unlimited (dalam 24h window)

3. Unofficial API (whatsapp-web.js, Baileys)

⚠️ TIDAK ADA OFFICIAL LIMIT, TAPI:

Safe practice:
- 1 message per 3-5 detik
- Max 200-500 messages/hari
- Random delay antar pesan

Terlalu cepat/banyak = BANNED!

Cloud API Tier System

┌─────────────────────────────────────────┐
│        WHATSAPP CLOUD API TIERS         │
├─────────────────────────────────────────┤
│                                         │
│  TIER 1 (Start)                         │
│  • 1,000 business-initiated/24h         │
│  • Untuk testing & small scale          │
│                                         │
│  TIER 2 (Growing)                       │
│  • 10,000 business-initiated/24h        │
│  • Setelah konsisten + quality bagus    │
│                                         │
│  TIER 3 (Scaling)                       │
│  • 100,000 business-initiated/24h       │
│  • High volume verified business        │
│                                         │
│  TIER 4 (Enterprise)                    │
│  • Unlimited                            │
│  • Butuh approval Meta                  │
│                                         │
└─────────────────────────────────────────┘

Jenis Message & Limit

Business-Initiated (Template):

- Pesan pertama ke customer
- Butuh template yang di-approve
- Kena limit berdasarkan tier
- Berbayar per conversation

User-Initiated (Session):

- Reply dalam 24h window
- Tidak perlu template
- Tidak kena tier limit
- Termasuk dalam conversation pricing

Session Window:

Customer kirim pesan
    ↓
Window 24 jam TERBUKA
    ↓
Bisa reply tanpa template (unlimited)
    ↓
24 jam berlalu
    ↓
Window TERTUTUP
    ↓
Perlu template untuk message baru

Handle Rate Limit

Detect Limit Hit:

javascript

// Cloud API response saat kena limit
{
    "error": {
        "message": "Rate limit hit",
        "type": "OAuthException",
        "code": 80007,
        "error_subcode": 2494055,
        "fbtrace_id": "xxx"
    }
}

Implement Retry Logic:

javascript

async function sendWithRetry(phone, message, maxRetries = 3) {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            const response = await sendWhatsAppMessage(phone, message);
            return response;
        } catch (error) {
            if (error.code === 80007) { // Rate limit
                const waitTime = Math.pow(2, attempt) * 1000; // Exponential backoff
                console.log(`Rate limit hit, waiting ${waitTime}ms...`);
                await sleep(waitTime);
            } else {
                throw error;
            }
        }
    }
    throw new Error('Max retries exceeded');
}

Queue System:

javascript

const Queue = require('bull');

const messageQueue = new Queue('whatsapp-messages', {
    limiter: {
        max: 50,      // Max 50 jobs
        duration: 1000 // Per 1 second
    }
});

// Add to queue
messageQueue.add({
    phone: '628123456789',
    message: 'Hello!'
});

// Process queue
messageQueue.process(async (job) => {
    await sendWhatsAppMessage(job.data.phone, job.data.message);
});

Unofficial API Rate Limit Strategy

Safe Sending Pattern:

javascript

const MIN_DELAY = 3000;  // 3 detik minimum
const MAX_DELAY = 8000;  // 8 detik maximum
const DAILY_LIMIT = 300; // Max per hari

let dailyCount = 0;

async function safeSendMessage(phone, message) {
    // Check daily limit
    if (dailyCount >= DAILY_LIMIT) {
        throw new Error('Daily limit reached');
    }
    
    // Random delay
    const delay = Math.random() * (MAX_DELAY - MIN_DELAY) + MIN_DELAY;
    await sleep(delay);
    
    // Send message
    await client.sendMessage(phone, message);
    dailyCount++;
    
    // Reset count at midnight
    scheduleReset();
}

// Batch sending with throttle
async function batchSend(recipients, message) {
    for (const phone of recipients) {
        await safeSendMessage(phone, message);
        console.log(`Sent to ${phone}, count: ${dailyCount}`);
    }
}

Time-Based Distribution:

javascript

// Spread messages throughout the day
async function distributedSend(recipients, message) {
    const totalRecipients = recipients.length;
    const hoursAvailable = 12; // 9 AM - 9 PM
    const messagesPerHour = Math.ceil(totalRecipients / hoursAvailable);
    
    let index = 0;
    
    for (let hour = 0; hour < hoursAvailable; hour++) {
        const batchSize = Math.min(messagesPerHour, totalRecipients - index);
        const batch = recipients.slice(index, index + batchSize);
        
        for (const phone of batch) {
            await safeSendMessage(phone, message);
        }
        
        index += batchSize;
        
        // Wait until next hour
        if (index < totalRecipients) {
            await sleep(60 * 60 * 1000); // 1 hour
        }
    }
}

Monitor & Optimize

Track Your Usage:

javascript

const usageStats = {
    sent: 0,
    failed: 0,
    rateLimited: 0,
    lastReset: new Date()
};

async function trackSend(phone, message) {
    try {
        await sendMessage(phone, message);
        usageStats.sent++;
    } catch (error) {
        if (isRateLimitError(error)) {
            usageStats.rateLimited++;
        }
        usageStats.failed++;
        throw error;
    }
}

// Report stats
function getUsageReport() {
    return {
        ...usageStats,
        successRate: usageStats.sent / (usageStats.sent + usageStats.failed),
        rateLimitRate: usageStats.rateLimited / usageStats.sent
    };
}

Quality Score (Cloud API):

Faktor yang mempengaruhi tier:
- Phone number quality rating
- Customer feedback
- Block/report rate
- Message delivery rate

Tips maintain quality:
✅ Relevant messages only
✅ Honor opt-out
✅ Quick response time
✅ Don't spam

Best Practices

1. Implement Queuing

Jangan send langsung, masukkan ke queue.
Queue handle rate limiting automatically.

2. Exponential Backoff

Kena limit?
Retry 1: Wait 2 seconds
Retry 2: Wait 4 seconds
Retry 3: Wait 8 seconds
...

3. Monitor Continuously

Track:
- Messages sent per hour/day
- Rate limit hits
- Quality score
- Delivery rate

4. Graceful Degradation

Saat peak:
- Prioritize important messages
- Delay non-urgent
- Notify users if delayed

FAQ

Bagaimana tahu saya kena rate limit?

Cloud API kasih error code spesifik. Unofficial biasanya message gagal atau akun banned.

Berapa lama harus tunggu setelah kena limit?

Cloud API: Biasanya reset per 24 jam rolling. Unofficial: Tunggu beberapa jam sampai 24 jam.

Bagaimana naik tier di Cloud API?

Kirim messages secara konsisten dengan quality bagus. Meta akan auto-upgrade tier.


Kesimpulan

Rate limit = Reality yang harus di-handle!

API TypeSafe LimitStrategy
Cloud API Tier 11,000/dayQueue + monitor
Cloud API Tier 2+10k+/dayBatch + distribute
Unofficial200-500/daySlow + random delay

Respect the limits, avoid the bans!

Handle Rate Limit dengan Balaswa →


Artikel Terkait