Skip to content

Rate Limits

The SIPSTACK API enforces rate limits to keep the platform stable. Limits are applied per client over fixed windows; sensitive operations have stricter, dedicated limits.

OperationLimit
Flare API requests (/flare/*, messages, contacts, webhooks), per organizationBy plan: Pro 60 / minute, Ultra 300 / minute, Enterprise unlimited
Other API requests (Nova, Aura, numbers, /me, /calls), per API key100 requests / minute
SMS sending endpoints30 sends / minute
Login attempts20 / 15 minutes per IP, plus 3 failed attempts / 30 minutes per email
Password reset requests3 / hour
Two-factor verification10 / 15 minutes
Data exports10 / hour

Separately from request rate limits, sending through POST /api/v2/messages/send is subject to your plan’s SMS limits. When one is reached, the send is refused and nothing is sent or counted. The body carries a code, and for some refusals a reason:

{
"success": false,
"code": "PAID_LIMIT_REACHED",
"reason": "daily",
"error": "Daily send limit of 2500 segments reached."
}
StatuscodereasonMeaningWhat to do
429PAID_LIMIT_REACHEDdailyDaily send limit reachedWait for Retry-After (the next 00:00 UTC)
429PAID_LIMIT_REACHEDmonthly_absoluteMonthly safety ceiling (3× your outbound allowance) reachedWait for Retry-After (your next pool reset)
429PAID_LIMIT_REACHEDnew_account_velocityNew-account limit (2,000 segments in the first 72 hours) reachedWait for Retry-After
429TRIAL_LIMIT_REACHEDlifetimeTrial message limit reachedActivate your plan — retrying won’t help
429TRIAL_LIMIT_REACHEDburstMore than 50 messages in 10 minutes during a trialSlow down and retry in a few minutes
403CARD_NOT_VERIFIED—The send would go beyond your included allowance and no valid payment method is on fileAdd a card on Account → Billing
402CAPABILITY_RESTRICTED_BY_STATE—The send would go beyond your included allowance and the subscription is past due or scheduled to cancelPay the open invoice or undo the cancellation
503TRIAL_LIMIT_REACHED—A limit couldn’t be checked right nowRetry after a short backoff

Honor Retry-After. On a PAID_LIMIT_REACHED response, Retry-After gives the number of seconds until the limit lifts, which can be hours or days away. Don’t retry in a loop. Queue the message and send it after that time, or report the failure to your user. A 429 without Retry-After is either a trial limit (see the table) or the request rate limit below; for the rate limit, back off using RateLimit-Reset.

Branch on the HTTP status first and use code and reason to refine it. A 503 carries TRIAL_LIMIT_REACHED as its code, but it means “try again shortly”, not “limit reached”.

How pools, limits, and overage work: SMS Usage, Limits & Billing. Your usage is on the Flare dashboard.

Responses include the standard RateLimit-* headers:

RateLimit-Limit: 100
RateLimit-Remaining: 87
RateLimit-Reset: 42
HeaderDescription
RateLimit-LimitMaximum requests in the current window
RateLimit-RemainingRequests left in the window
RateLimit-ResetSeconds until the window resets

Read these in your client to throttle proactively instead of hitting the limit.

Exceeding a limit returns HTTP 429 Too Many Requests with a plain-text or JSON message describing which limit you hit. Do not retry immediately. If the response has a Retry-After header (the Flare API request limit, or an SMS plan limit), wait at least that long. Otherwise wait for the window to reset (RateLimit-Reset) and use exponential backoff on consecutive 429s:

async function apiRequest(url, options, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) return response;
if (attempt === maxRetries) throw new Error('Rate limited after max retries');
// An SMS plan limit says exactly when it lifts — often hours away.
// Don't hold the request open; hand it back to your queue instead.
const retryAfter = response.headers.get('Retry-After');
if (retryAfter && Number(retryAfter) > 300) return response;
const reset = Number(retryAfter ?? response.headers.get('RateLimit-Reset') ?? 60);
const delay = Math.min(reset * Math.pow(2, attempt) * 1000, 300_000);
await new Promise((r) => setTimeout(r, delay));
}
}

Beyond API limits, SMS delivery speed is bounded by your Flare plan’s send speed and by carrier-side throughput for the number type — whichever is lower. Carrier limits cannot be raised by SIPSTACK:

Number typeApproximate throughput
US 10DLC (registered)Depends on your brand’s trust score and campaign — see your 10DLC campaign
Toll-free (verified)Roughly 3 messages/second
Canadian local numberJust under 1 message/second per number, best-effort

Flare queues campaign messages that exceed these limits rather than dropping them — large campaigns simply take longer to drain. For faster sending to Canada, use a toll-free number; for US 10DLC, enhanced brand vetting is the usual lever. See Sending Speeds for messages per hour by plan and number type.

  • Cache static data — extension lists and configuration change rarely; don’t re-fetch on every request.
  • Paginate efficiently — request the maximum page size instead of one record at a time.
  • Throttle on RateLimit-Remaining — back off before the limit, not after.
  • Queue your sends — for bulk SMS, feed a queue at a steady rate instead of bursting.