Skip to main content

Rate Limiting

Rate limits protect the platform and ensure fair usage across all accounts. Limits are applied at two levels: a global per-plan ceiling and endpoint-specific limits for sensitive operations.

Global Rate Limits by Plan

Every API request counts against your plan's global rate limit:

PlanRequests/Minute
Free60
Starter300
Pro600
Scale1,200
EnterpriseUnlimited

These limits are applied per account across all API keys and projects.

Endpoint-Specific Rate Limits

In addition to the global plan limit, certain endpoint categories have their own limits:

Notification & Platform Endpoints

CategoryLimitApplies To
Dashboard Auth10 req/minDashboard login, register, password reset
Sensitive5 req/minKey rotation, application create/delete, OAuth provider config
Standard API100 req/minEmail/push/SMS send, webhook CRUD, subscriber upsert
Read-only200 req/minList/get endpoints (emails, push, SMS, subscribers, users)

Auth-as-a-Service Endpoints

Auth-as-a-Service rate limits are plan-aware and split into two tiers based on the operation type:

Credential Operations

These are brute-force-sensitive operations (registration, login, password resets). They have lower limits to prevent credential stuffing:

PlanLimit
Free20 req/min
Starter60 req/min
Pro120 req/min
Scale300 req/min
EnterpriseUnlimited

Endpoints in this tier:

  • POST /v1/auth/users/register — Register end user
  • POST /v1/auth/users/login — Login end user
  • DELETE /v1/auth/users/me — Delete account
  • POST /v1/auth/magic-link/send — Send magic link
  • POST /v1/auth/forgot-password — Request password reset
  • POST /v1/auth/reset-password — Reset password
  • POST /v1/auth/validate-reset-token — Validate reset token
  • POST /v1/auth/verify-email/send — Send verification email
  • POST /v1/auth/verify-email/resend — Resend verification
  • POST /v1/auth/phone/register/send — Send phone OTP (register)
  • POST /v1/auth/phone/login/send — Send phone OTP (login)

Token Operations

These are high-throughput operations your backend calls frequently (token refresh, verification, OAuth callbacks). They have much higher limits:

PlanLimit
Free120 req/min
Starter600 req/min
Pro1,200 req/min
Scale3,000 req/min
EnterpriseUnlimited

Endpoints in this tier:

  • POST /v1/auth/sessions/refresh — Refresh access token
  • POST /v1/auth/magic-link/verify — Verify magic link
  • POST /v1/auth/verify-email/confirm — Confirm email verification
  • POST /v1/auth/oauth/:provider/callback — OAuth callback
  • POST /v1/auth/oauth/tokens/:provider/refresh — Refresh OAuth tokens
  • POST /v1/auth/phone/register/verify — Verify phone OTP (register)
  • POST /v1/auth/phone/login/verify — Verify phone OTP (login)
  • POST /v1/auth/webauthn/registration/start — Start WebAuthn registration
  • POST /v1/auth/webauthn/registration/verify — Verify WebAuthn registration
  • POST /v1/auth/webauthn/authentication/start — Start WebAuthn authentication
  • POST /v1/auth/webauthn/authentication/verify — Verify WebAuthn authentication

Unrestricted Auth Endpoints

These read-only and session management endpoints only count against your global plan limit:

  • GET /v1/auth/password-requirements — Get password policy
  • GET /v1/auth/users/me — Get current user
  • PATCH /v1/auth/users/me — Update current user
  • GET /v1/auth/sessions — List sessions
  • POST /v1/auth/sessions/revoke — Logout (single)
  • POST /v1/auth/sessions/revoke-all — Logout all
  • GET /v1/auth/oauth/* — OAuth provider info, connections
  • GET /v1/auth/webauthn/* — WebAuthn credentials, status
Token refresh is the hot path

If your app verifies auth on every API request by refreshing tokens, the token operations tier is sized for that pattern. On the Pro plan, you get 1,200 token operations per minute — enough for 20 active users each making a request per second.

SMS Per-Phone Limits

SMS endpoints have additional per-phone-number rate limits to prevent abuse:

OperationLimit
Send OTP3 per 15 minutes per phone
Verify OTP10 attempts per 15 minutes per phone
Send SMS10 per hour per phone

Channel Quotas by Plan

Free Plan

ChannelDaily LimitMonthly Limit
Email2501,000
Push2501,000
SMS5005,000
In-App5005,000

Free plan limits are hard-blocked — exceeding them returns a quota_exceeded error. Free plan limits are aggregated across all accounts owned by the same user.

Paid plans use monthly quotas based on your subscription. Daily limits are removed. Overage is tracked and billed separately.

Auth-as-a-Service Quotas

QuotaFreeStarterProScaleEnterprise
Monthly Active Users (MAU)1,00010,00025,000100,000Unlimited
Credential ops/min2060120300Unlimited
Token ops/min1206001,2003,000Unlimited
Auth applications1510UnlimitedUnlimited
Test environment users1010101010

Test environment users (za_test_* keys) do not count toward MAU or auth request quotas. See Test Mode for details.

Rate Limit Headers

Every response includes rate limit information:

X-RateLimit-Limit: 600
X-RateLimit-Remaining: 595
X-RateLimit-Reset: 1705312800
X-RateLimit-Plan: pro
HeaderDescription
X-RateLimit-LimitMaximum requests per window
X-RateLimit-RemainingRemaining requests in current window
X-RateLimit-ResetUnix timestamp when the window resets
X-RateLimit-PlanYour account's plan

Error Responses

Rate Limit Exceeded (429)

{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Try again in 60 seconds."
},
"meta": {
"request_id": "...",
"retry_after": 60
}
}

Channel Quota Exceeded (429)

{
"error": {
"code": "quota_exceeded",
"message": "Monthly email quota exceeded (1000 emails for free plan). Upgrade your plan to send more.",
"limit": 1000,
"current": 1000
}
}

Daily Limit Exceeded (429)

{
"error": {
"code": "daily_limit_exceeded",
"message": "Daily email limit exceeded (250 emails/day for free plan). Try again tomorrow or upgrade your plan.",
"limit": 250,
"current": 250
}
}

Test Environment Limit (403)

{
"error": {
"code": "test_environment_limit",
"message": "Test environment is limited to 10 users. Current: 10. Use live keys for production.",
"limit": 10,
"current": 10
}
}

SMS Rate Limit (429)

{
"error": {
"code": "otp_send_rate_limit_exceeded",
"message": "Too many OTP requests for this phone number. Try again in 15 minutes."
}
}

Retry Logic

Implement exponential backoff when you receive a 429:

async function sendWithRetry(fn: () => Promise<any>, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error: any) {
if (error.status === 429) {
const retryAfter = error.retryAfter || Math.pow(2, i) * 1000;
await new Promise(r => setTimeout(r, retryAfter));
} else {
throw error;
}
}
}
throw new Error('Max retries exceeded');
}

Email Warmup

New accounts start with email sending limits that gradually increase as your sending reputation is established. This protects deliverability for all Zyphr users.

Warmup Stages

StageDaily LimitMinimum Duration
1 — Initial50 emails3 days
2 — Building200 emails4 days
3 — Scaling1,000 emails7 days
4 — CompletedPlan limit

Total minimum warmup period: 14 days

Stage Progression Requirements

To advance to the next stage, your account must meet:

  • Bounce rate ≤ 5%
  • Complaint rate ≤ 0.1%
  • Minimum duration completed in current stage
  • Minimum 50% utilization of the daily limit (when metrics are available)

If your bounce or complaint rate exceeds thresholds, stage progression is blocked until metrics improve.

Warmup Error Response

{
"error": {
"code": "DAILY_LIMIT_EXCEEDED",
"message": "Daily warmup limit of 50 emails reached. Your account is in warmup stage 1.",
"daily_limit": 50,
"daily_sent": 50,
"warmup_stage": 1
}
}

Warmup Tips

  • Start with your most engaged recipients to build positive reputation signals
  • Gradually increase volume each day within your stage limit
  • Monitor bounce and complaint rates in the Dashboard
  • Test mode (zy_test_* keys) does not count toward warmup limits

What Bypasses Rate Limits

ScenarioRate Limits Applied?
Dashboard (JWT auth)No — first-party users bypass rate limits
API key (zy_live_*, zy_test_*)Yes — global plan + endpoint-specific
Application key (za_live_*, za_test_*)Yes — global plan + auth endpoint limit
Enterprise planNo — unlimited requests
Test mode notifications (zy_test_*)Yes — rate limits still apply, but quotas don't count
Test mode auth (za_test_*)Yes — rate limits still apply, but MAU/auth quotas don't count

Best Practices

  • Use batch endpoints (/v1/emails/batch, /v1/inbox/send/batch) to reduce request count
  • Implement exponential backoff for retry logic
  • Monitor X-RateLimit-Remaining headers to throttle proactively
  • Use test mode keys during development to avoid hitting quotas
  • Add delays in scripts — if seeding test data, don't blast registration endpoints faster than 10 req/min
  • Contact support for Enterprise plan with custom limits