Skip to main content

Rate Limits

The ColdSend API enforces rate limits to ensure platform stability and fair usage.

Current Limits

LimitValueWindow
Requests100Per minute
Requests1,000Per hour

Rate Limit Headers

Every API response includes rate limit information:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704067200
HeaderDescription
X-RateLimit-LimitMaximum requests per window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the window resets

Handling Rate Limits

When You Hit the Limit

If you exceed the rate limit, the API returns: Status: 429 Too Many Requests
{
  "detail": "Rate limit exceeded. Retry after 60 seconds."
}

Implementing Backoff

Use exponential backoff to handle rate limiting gracefully:
import requests
import time

def api_request_with_retry(method, url, max_retries=5, **kwargs):
    for attempt in range(max_retries):
        response = requests.request(method, url, **kwargs)
        
        if response.status_code != 429:
            return response
        
        # Exponential backoff: 1s, 2s, 4s, 8s, 16s
        wait_time = 2 ** attempt
        time.sleep(wait_time)
    
    return response

Checking Remaining Requests

Before making a request, check the headers from your last request:
def make_request_if_available(method, url, **kwargs):
    response = requests.request(method, url, **kwargs)
    
    remaining = int(response.headers.get("X-RateLimit-Remaining", 0))
    
    if remaining < 10:
        # Getting close to the limit
        reset_time = int(response.headers.get("X-RateLimit-Reset", 0))
        current_time = time.time()
        wait_seconds = reset_time - current_time
        
        if wait_seconds > 0:
            time.sleep(wait_seconds)
    
    return response

Best Practices

Batch Operations

When processing multiple items, space out your requests:
import time

campaigns = ["campaign-1", "campaign-2", "campaign-3"]

for campaign_id in campaigns:
    response = requests.get(
        f"{base_url}/api/public/v1/campaigns/{campaign_id}",
        headers={"X-API-Key": api_key}
    )
    # Process response...
    
    # Small delay between requests
    time.sleep(0.1)

Use Webhooks

For real-time updates instead of polling:
  • Configure webhooks for campaign events
  • Receive notifications for opens, replies, and bounces
  • Reduces the need for frequent API calls

Cache Responses

Cache frequently accessed data:
import time

cache = {}
cache_ttl = 300  # 5 minutes

def get_campaign(campaign_id):
    cache_key = f"campaign:{campaign_id}"
    
    if cache_key in cache:
        cached, timestamp = cache[cache_key]
        if time.time() - timestamp < cache_ttl:
            return cached
    
    response = requests.get(
        f"{base_url}/api/public/v1/campaigns/{campaign_id}",
        headers={"X-API-Key": api_key}
    )
    
    data = response.json()
    cache[cache_key] = (data, time.time())
    
    return data

Monitor Usage

Track your API usage:
import time

class RateLimitTracker:
    def __init__(self):
        self.requests = []
        self.window = 60  # seconds
        self.max_requests = 100
    
    def can_make_request(self):
        now = time.time()
        # Remove requests outside the window
        self.requests = [r for r in self.requests if now - r < self.window]
        
        return len(self.requests) < self.max_requests
    
    def record_request(self):
        self.requests.append(time.time())

tracker = RateLimitTracker()

def make_tracked_request(method, url, **kwargs):
    if not tracker.can_make_request():
        wait_time = tracker.window - (time.time() - tracker.requests[0])
        time.sleep(wait_time)
    
    tracker.record_request()
    return requests.request(method, url, **kwargs)

Rate Limit by Endpoint

All endpoints share the same rate limit pool. High-volume operations should be spread across time:
OperationTypical Rate Impact
Create campaign1 request
Update campaign1 request
Delete campaign1 request
Add sender account1 request (includes validation)
Delete sender account1 request

Contacting Support

If you need higher rate limits for your use case, contact [email protected] with:
  • Your account ID
  • Expected request volume
  • Use case description