Sendable Docs

Rate Limits

Understanding Sendable API rate limits and best practices.

Limits by Plan

PlanRequests/MinuteMessages/HourConcurrent Sessions
Free601001
Starter3001,0003
Pro1,00010,00010
EnterpriseCustomCustomCustom

Rate Limit Headers

Every API response includes rate limit headers:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1709380800
HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when limit resets

Handling Rate Limits

When you exceed the rate limit, you'll receive a 429 status code:

{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Try again in 60 seconds.",
    "retryAfter": 60
  }
}

Best Practices

1. Implement client-side throttling

class RateLimiter {
  private queue: Array<() => Promise<any>> = []
  private running = 0
  private maxConcurrent = 5

  async add(task: () => Promise<any>) {
    if (this.running < this.maxConcurrent) {
      this.running++
      try {
        return await task()
      } finally {
        this.running--
        this.processQueue()
      }
    }
    return new Promise((resolve, reject) => {
      this.queue.push(async () => {
        try {
          resolve(await task())
        } catch (e) {
          reject(e)
        }
      })
    })
  }

  private processQueue() {
    if (this.queue.length > 0 && this.running < this.maxConcurrent) {
      const next = this.queue.shift()
      if (next) this.add(next)
    }
  }
}

2. Use exponential backoff

async function withBackoff(fn: () => Promise<any>, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      return await fn()
    } catch (error: any) {
      if (error.status === 429) {
        const delay = Math.min(1000 * Math.pow(2, i), 30000)
        await new Promise(r => setTimeout(r, delay))
        continue
      }
      throw error
    }
  }
}

3. Monitor your usage

Track your rate limit headers to proactively adjust your request patterns.

On this page