Troubleshooting7 de fev. de 2026· 7 min leitura

Error 131056 WhatsApp API: Rate Limit Hit — How to Fix

Complete guide to fix error 131056 (rate limit hit) on WhatsApp Business API. Causes, subcodes, pair rate limit and solutions with code examples.

What is Error 131056?

Error 131056 is the rate limit hit error from the WhatsApp Business API. It occurs when your application exceeds sending limits — either the account's global limit, the per-phone-number limit, or the pair rate limit (the limit between your business number and a specific consumer number).

{
  "error": {
    "message": "(#131056) (business account, consumer account) pair rate limit hit",
    "type": "OAuthException",
    "code": 131056,
    "error_subcode": 2494055,
    "fbtrace_id": "..."
  }
}

This is one of the most common errors in high-scale operations and can seriously impact your campaigns if not handled correctly.

Types of Rate Limits That Trigger 131056

Error 131056 is not a single limit — it can be triggered by three different types of rate limiting:

1. Pair Rate Limit (Business ↔ Consumer)

The most frequent. Occurs when you send too many messages to the same number in a short period.

Your Business Number → Customer Number = PAIR

Approximate limits:

  • Maximum ~80 messages per second per pair
  • Maximum ~256 template messages per active conversation
  • If the user doesn't reply, Meta progressively reduces the limit

2. Phone Number Throughput Limit

Occurs when your Business number sends messages too fast, regardless of destination.

Cloud API:

  • Default limit: 80 msg/s
  • Maximum limit: 1,000 msg/s (for eligible accounts that request an increase)

Business App:

  • Default limit: ~10 msg/min
  • Maximum limit: N/A

3. 24h Conversation Tier Limit

Occurs when you exceed the number of new conversations you can initiate in 24 hours.

  • Unverified: 250 conversations/24h
  • Tier 1: 1,000 conversations/24h
  • Tier 2: 10,000 conversations/24h
  • Tier 3: 100,000 conversations/24h
  • Tier 4: Unlimited

Error Subcodes

Error 131056 may come with different subcodes indicating which type of rate limit was reached:

  • 2494055 — Pair rate limit: Too many messages to the same user
  • 2494056 — Account rate limit: Global account limit reached
  • 2494057 — Spam rate limit: Spam pattern detected
  • 2494058 — Throughput limit: Too many API calls per second

Common Causes

1. Spamming the Same User

The most common scenario: sending multiple template messages to the same number without waiting for a reply.

// ❌ WRONG: bombarding the same number
for (const template of templates) {
  await sendTemplate(userPhone, template); // Will trigger 131056
}

// ✅ CORRECT: space out and limit per user
const MAX_TEMPLATES_PER_USER = 3;
const DELAY_BETWEEN_MESSAGES = 5000; // 5 seconds

for (let i = 0; i < Math.min(templates.length, MAX_TEMPLATES_PER_USER); i++) {
  await sendTemplate(userPhone, templates[i]);
  await new Promise(r => setTimeout(r, DELAY_BETWEEN_MESSAGES));
}

2. Bulk Campaign Without Rate Limiting

Sending to your entire contact base at once without speed control.

3. Aggressive Retry

When the first attempt fails and the system retries immediately without backoff.

4. Multiple Systems Sending

Two or more systems (CRM, chatbot, campaigns) sending through the same number without coordination.

Solutions

1. Implement Rate Limiter with Bottleneck

import Bottleneck from 'bottleneck';

// Global limiter: respects Cloud API throughput
const globalLimiter = new Bottleneck({
  minTime: 15,        // ~66 msg/s (below the 80 limit)
  maxConcurrent: 10,
  reservoir: 5000,
  reservoirRefreshAmount: 5000,
  reservoirRefreshInterval: 60 * 1000
});

// Per-user limiter: prevents pair rate limit
const userLimiters = new Map();

function getUserLimiter(userId) {
  if (!userLimiters.has(userId)) {
    userLimiters.set(userId, new Bottleneck({
      minTime: 3000,     // 1 msg every 3 seconds per user
      maxConcurrent: 1,
      reservoir: 10,     // Max 10 msgs per window
      reservoirRefreshAmount: 10,
      reservoirRefreshInterval: 60 * 60 * 1000 // Refreshes every hour
    }));
  }
  return userLimiters.get(userId);
}

async function safeSendMessage(to, message) {
  const userLimiter = getUserLimiter(to);
  return globalLimiter.schedule(() =>
    userLimiter.schedule(() =>
      sendWhatsAppMessage(to, message)
    )
  );
}

2. Exponential Backoff with Jitter

When you receive 131056, don't retry immediately. Use backoff with jitter to avoid thundering herd:

async function sendWithBackoff(to, message, attempt = 1, maxAttempts = 5) {
  try {
    return await sendWhatsAppMessage(to, message);
  } catch (error) {
    if (error.code === 131056 && attempt < maxAttempts) {
      // Exponential backoff with jitter
      const baseDelay = Math.pow(2, attempt) * 1000;
      const jitter = Math.random() * 1000;
      const delay = baseDelay + jitter;

      console.log(
        `[131056] Rate limit for ${to}. ` +
        `Attempt ${attempt}/${maxAttempts}. ` +
        `Waiting ${(delay / 1000).toFixed(1)}s...`
      );

      await new Promise(r => setTimeout(r, delay));
      return sendWithBackoff(to, message, attempt + 1, maxAttempts);
    }
    throw error;
  }
}

3. Queue with BullMQ and Rate Limiting

For high-scale operations, use queues with speed control:

import { Queue, Worker } from 'bullmq';

const messageQueue = new Queue('whatsapp-messages', {
  connection: { host: 'localhost', port: 6379 }
});

// Enqueue message
async function queueMessage(to, message, priority = 'normal') {
  await messageQueue.add(
    'send',
    { to, message },
    {
      priority: priority === 'urgent' ? 1 : 10,
      attempts: 5,
      backoff: {
        type: 'exponential',
        delay: 3000
      },
      // Group by recipient to avoid pair rate limit
      group: { id: to }
    }
  );
}

// Worker with built-in rate limiting
const worker = new Worker(
  'whatsapp-messages',
  async job => {
    return await sendWhatsAppMessage(job.data.to, job.data.message);
  },
  {
    connection: { host: 'localhost', port: 6379 },
    limiter: {
      max: 50,        // 50 messages
      duration: 1000  // per second
    },
    concurrency: 5
  }
);

worker.on('failed', (job, error) => {
  if (error.code === 131056) {
    console.log(`Rate limit for ${job.data.to}. Auto-retry scheduled.`);
  }
});

4. Monitor and Auto-Pause

class RateLimitMonitor {
  constructor() {
    this.rateLimitCount = 0;
    this.totalSent = 0;
    this.windowStart = Date.now();
  }

  recordSent() {
    this.totalSent++;
  }

  recordRateLimit() {
    this.rateLimitCount++;
  }

  getRateLimitPercentage() {
    if (this.totalSent === 0) return 0;
    return (this.rateLimitCount / this.totalSent) * 100;
  }

  shouldPause() {
    // Pause if more than 5% of messages hit rate limit
    return this.getRateLimitPercentage() > 5;
  }

  shouldSlowDown() {
    // Slow down if more than 2% hit rate limit
    return this.getRateLimitPercentage() > 2;
  }

  reset() {
    this.rateLimitCount = 0;
    this.totalSent = 0;
    this.windowStart = Date.now();
  }
}

const monitor = new RateLimitMonitor();

async function sendWithMonitoring(to, message) {
  if (monitor.shouldPause()) {
    console.log('⚠️ High rate limit ratio. Pausing for 60s...');
    await new Promise(r => setTimeout(r, 60000));
    monitor.reset();
  }

  try {
    const result = await sendWhatsAppMessage(to, message);
    monitor.recordSent();
    return result;
  } catch (error) {
    if (error.code === 131056) {
      monitor.recordRateLimit();
    }
    throw error;
  }
}

Difference Between 131056 and Other Errors

  • 131056 — Rate limit hit: ✅ Yes, retry with backoff
  • 131047 — 24h window expired: ❌ No (use template)
  • 131026 — Message undeliverable: ❌ No (invalid number)
  • 130429 — Cloud API throttle: ✅ Yes, retry with backoff

The key difference: 131056 is temporary. Waiting and retrying resolves it. Other errors indicate problems that retry won't fix.

Prevention: Best Practices

  1. Gradual warm-up: Never send at maximum capacity on new accounts. Start at 10% and scale up over 14 days.

  2. Respect opt-out: Users who block or report reduce your Quality Rating and increase rate limiting chances.

  3. Coordinate systems: If multiple services send through the same number, use a centralized queue.

  4. Monitor Quality Rating: Low Quality Rating = more aggressive limits.

async function checkQualityAndLimits() {
  const response = await fetch(
    `https://graph.facebook.com/v22.0/${phoneNumberId}` +
    `?fields=quality_rating,messaging_limit_tier`,
    {
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    }
  );

  const data = await response.json();
  console.log('Quality:', data.quality_rating);
  console.log('Tier:', data.messaging_limit_tier);
  return data;
}
  1. Use response headers: The Cloud API returns rate limit headers. Monitor them:
async function sendAndCheckHeaders(to, message) {
  const response = await fetch(/* ... */);

  // Rate limit headers
  const remaining = response.headers.get('x-ratelimit-remaining');
  const reset = response.headers.get('x-ratelimit-reset');

  if (remaining && parseInt(remaining) < 10) {
    console.log(`⚠️ Only ${remaining} calls remaining. Reset in ${reset}s`);
  }

  return response.json();
}

Conclusion

Error 131056 is recoverable — unlike other WhatsApp API errors, you just need to wait and retry. The key takeaways:

  1. Implement rate limiting before sending (prevent > cure)
  2. Exponential backoff with jitter on retries
  3. Centralized queue to coordinate multiple systems
  4. Active monitoring to pause when error rates climb

Need help scaling your WhatsApp operation without rate limits? Contact me for specialized consulting.

Artigos Relacionados

  • Troubleshooting

    Erro 131056 WhatsApp API: Rate Limit Hit — Como Resolver

  • Troubleshooting

    Webhook WhatsApp API Não Recebe Mensagens: Guia Completo de Troubleshooting

  • Troubleshooting

    Erros de Autenticação WhatsApp API: Token Expirado e Permissões

.