Rate Limiting Guide

Understand how rate limiting works and how to handle rate limit responses.

Rate Limits

Rate limits depend on your plan:

  • Free Plan: 100 requests per minute
  • Starter Plan: 1,000 requests per minute
  • Professional Plan: 10,000 requests per minute
  • Enterprise Plan: Custom limits

Rate Limit Headers

Every API response includes rate limit information:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1610520000

Header Meanings

  • X-RateLimit-Limit - Total requests allowed per minute
  • X-RateLimit-Remaining - Requests remaining in current minute
  • X-RateLimit-Reset - Unix timestamp when limit resets

Handling Rate Limits

PHP Example

<?php
$response = curl_exec($ch);
$headers = curl_getinfo($ch);

$remaining = $headers['X-RateLimit-Remaining'];
$reset = $headers['X-RateLimit-Reset'];

if ($remaining < 10) {
    echo "Warning: Only $remaining requests remaining";
}

if ($headers['http_code'] === 429) {
    // Rate limited - wait before retrying
    $wait_time = $reset - time();
    sleep($wait_time);
    // Retry request
}
?>

Python Example

import requests
import time

url = 'https://api.opensms.co.ke/v3/sms/send'
headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
}

response = requests.post(url, json=data, headers=headers)

remaining = response.headers.get('X-RateLimit-Remaining')
reset = response.headers.get('X-RateLimit-Reset')

if int(remaining) < 10:
    print(f"Warning: Only {remaining} requests remaining")

if response.status_code == 429:
    wait_time = int(reset) - int(time.time())
    print(f"Rate limited. Waiting {wait_time} seconds...")
    time.sleep(wait_time)
    # Retry request

Node.js Example

const axios = require('axios');

const url = 'https://api.opensms.co.ke/v3/sms/send';
const headers = {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
};

try {
    const response = await axios.post(url, data, { headers });
    
    const remaining = response.headers['x-ratelimit-remaining'];
    const reset = response.headers['x-ratelimit-reset'];
    
    if (remaining < 10) {
        console.log(`Warning: Only ${remaining} requests remaining`);
    }
} catch (error) {
    if (error.response.status === 429) {
        const reset = error.response.headers['x-ratelimit-reset'];
        const waitTime = reset - Math.floor(Date.now() / 1000);
        console.log(`Rate limited. Waiting ${waitTime} seconds...`);
        await new Promise(resolve => setTimeout(resolve, waitTime * 1000));
        // Retry request
    }
}

Exponential Backoff Strategy

PHP Implementation

<?php
function makeRequestWithRetry($url, $data, $max_retries = 3) {
    $retry_count = 0;
    
    while ($retry_count < $max_retries) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer YOUR_API_KEY',
            'Content-Type: application/json'
        ]);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        
        if ($http_code === 429) {
            $wait_time = pow(2, $retry_count); // 1, 2, 4 seconds
            sleep($wait_time);
            $retry_count++;
            continue;
        }
        
        return json_decode($response, true);
    }
    
    throw new Exception("Max retries exceeded");
}
?>

Best Practices

  • Monitor the X-RateLimit-Remaining header
  • Implement exponential backoff for retries
  • Batch requests when possible to reduce API calls
  • Cache responses to reduce API calls
  • Upgrade your plan if you consistently hit limits
  • Spread requests over time instead of sending them all at once
  • Use webhooks instead of polling for delivery reports

Upgrading Your Plan

If you need higher rate limits, you can upgrade your plan in your account settings. Contact our support team for enterprise plans with custom limits.

Next Steps