ESC
Type to search across all documentation

Rate Limits

All COALS API endpoints are rate-limited per API key. Limits vary by service and plan. Every response includes headers so your client always knows its current standing.

Default Limits

Unless overridden by a plan-specific limit, each API key is allowed 1,000 requests within the rolling window. The window resets at the timestamp returned in the X-RateLimit-Reset header.

1,000

requests per window

per key

limits are not shared across keys

rolling

window resets progressively

Rate Limit Headers

These headers are present on every response — success or failure — so you can proactively throttle your client before hitting the limit.

X-RateLimit-Limit The total number of requests allowed in the current window for this key.
X-RateLimit-Remaining The number of requests remaining before the limit is hit.
X-RateLimit-Reset Unix timestamp (UTC) when the current window resets and the counter returns to the limit.

Example Response Headers

HTTP/1.1 200 OK
X-RateLimit-Limit:     1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset:     1740960000
Content-Type:          application/json

429 — Too Many Requests

When the limit is exceeded the API returns 429 Too Many Requests. The response includes a Retry-After header indicating how many seconds to wait before the next request will succeed.

Response Headers

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit:     1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset:     1740960000
Retry-After:           42

Response Body

{
  "success": false,
  "error": {
    "code":    "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Retry after 42 seconds."
  }
}

SimCoal — SMS Plan Limits

In addition to the global key limit, the SimCoal POST /send and POST /send-bulk endpoints enforce per-minute throughput caps based on your plan. This prevents carrier throttling and protects deliverability.

Plan SMS / Minute Notes
Free 1 / min Best for testing and low-volume personal projects.
Pro 60 / min Suitable for production applications and bulk campaigns.
Enterprise 300 / min High-throughput workloads. Contact us for custom limits.

Best Practices

Respect Retry-After

When you receive a 429, read the Retry-After header and wait exactly that many seconds before retrying. Ignoring it and retrying immediately will continue to return 429.

Implement Exponential Backoff

For transient 500 errors or network failures, retry with exponential backoff — start at 1 second, double each attempt, and cap at ~60 seconds. Add a small random jitter to avoid thundering herd.

// Example: backoff with jitter (JavaScript)
const retry = async (fn, attempts = 5) => {
  for (let i = 0; i < attempts; i++) {
    try { return await fn(); }
    catch (err) {
      if (i === attempts - 1) throw err;
      const delay = Math.min(1000 * 2 ** i, 60000)
                   + Math.random() * 500;
      await new Promise(r => setTimeout(r, delay));
    }
  }
};

Monitor X-RateLimit-Remaining

Read X-RateLimit-Remaining on every successful response. When it falls below a threshold (e.g. 10% of the limit), slow down your request rate proactively rather than waiting for a 429.

Use Bulk Endpoints

Where available (e.g. POST /simcoal/send-bulk), batch operations into a single request rather than sending many individual requests. This is more efficient and uses fewer rate limit slots.