Developer Docs

Getting Started
  • Quick Start
  • Getting Started
  • Authentication
API Reference
  • Overview
  • Orders
  • Products
  • Inventory
  • Shipments
  • Customers
  • Returns
  • Tracking
Integrations
  • Shopify
  • WooCommerce
  • BigCommerce
  • Custom API
Webhooks
  • Overview
  • Webhook Events
Resources
  • Rate Limits
  • Error Codes
  • API Playground
  • SDK Libraries
  • Changelog
  • API Status
Support
  • Community
  • GitHub
  • Support
HomeDeveloper HubDocsRate Limits
API Performance

API Rate Limits

Understand rate limiting policies, monitor your usage with response headers, and implement best practices for optimal API performance.

Standard Tier

1,000

requests per hour

Professional Tier

5,000

requests per hour

Enterprise Tier

25,000+

requests per hour

Rate Limit Policy

The 3PL SHIP API uses a sliding window rate limiting algorithm to ensure fair usage and optimal performance for all users. Rate limits are applied per API key and configured based on your account tier.

Rate Limit Tracking

Rate limits track requests across three time windows: per minute, per hour, and per day. Each API key has its own configured limits stored in the api_keys table.

Rate Limit Headers

Every API response includes headers that help you monitor your rate limit status:

HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1704974400
Retry-After: 3600

X-RateLimit-Limit

Maximum number of requests allowed in the current time window for your API key.

X-RateLimit-Remaining

Number of requests remaining in the current time window before hitting the limit.

X-RateLimit-Reset

Unix timestamp (seconds since epoch) when the rate limit window resets.

Retry-After

Number of seconds to wait before making another request (included in 429 RATE_LIMIT_EXCEEDED responses).

Handling Rate Limit Errors

When you exceed the rate limit, the API returns a 429 Too Many Requests status code with error code RATE_LIMIT_EXCEEDED. Implement exponential backoff to handle these gracefully:

JavaScript/Node.jsExponential Backoff
const apiKey = 'zl_live_xxxxx';

async function makeRequest(url, options, retries = 3) {
  try {
    const response = await fetch(url, {
      ...options,
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        ...options.headers
      }
    });
    
    const result = await response.json();
    
    if (response.status === 429) {
      const retryAfter = parseInt(
        response.headers.get('Retry-After') || '60'
      );
      const resetTime = response.headers.get(
        'X-RateLimit-Reset'
      );
      
      console.log(`Rate limited. Reset at: ${resetTime}`);
      
      if (retries > 0) {
        await sleep(retryAfter * 1000);
        return makeRequest(url, options, retries - 1);
      }
      
      throw new Error('Rate limit exceeded');
    }
    
    // Log current rate limit status
    console.log(`Remaining: ${response.headers.get(
      'X-RateLimit-Remaining'
    )}`);
    
    return result;
  } catch (error) {
    throw error;
  }
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
PythonRetry Logic
import requests
import time

api_key = 'zl_live_xxxxx'

def make_request(url, max_retries=3):
    retries = 0
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }
    
    while retries < max_retries:
        response = requests.get(url, headers=headers)
        result = response.json()
        
        if response.status_code == 429:
            retry_after = int(
                response.headers.get('Retry-After', 60)
            )
            reset_time = response.headers.get(
                'X-RateLimit-Reset'
            )
            
            print(f"Rate limited until: {reset_time}")
            time.sleep(retry_after)
            retries += 1
            continue
        
        # Log current rate limit status
        remaining = response.headers.get(
            'X-RateLimit-Remaining'
        )
        print(f"Remaining requests: {remaining}")
            
        return result
    
    raise Exception("Max retries exceeded")

Best Practices

✓ Monitor Headers

Always check rate limit headers and implement proactive throttling before hitting the limit.

✓ Implement Caching

Cache responses locally to reduce API calls for frequently accessed data.

✓ Use Webhooks

Subscribe to webhooks instead of polling endpoints for real-time updates.

✓ Batch Requests

Use batch endpoints when available to reduce the number of API calls.

✗ Avoid Parallel Requests

Don't make excessive parallel requests as they count against your limit simultaneously.

✗ Don't Ignore 429s

Always respect 429 responses and implement proper retry logic with backoff.

Need Higher Rate Limits?

Enterprise plans include custom rate limits tailored to your business needs.

Contact SalesView All Docs