Lumail.ioLumail.io
DocsBlogChangelog

Getting Started

  • Introduction
  • Tutorials
  • API Reference
  • Integrations
  • Features
  • Workflows

Tutorials

  • Create an API Token
  • Build a V0 Capture Page
  • Dynamic Promo Codes with Webhooks

API Reference

  • API Tokens
  • Rate Limits
  • POSTSend Transactional Email
  • POSTEmail Verification API
  • POSTCreate Subscriber
  • GETGet Subscriber
  • PATCHUpdate Subscriber
  • DELETEDelete Subscriber
  • POSTAdd Tags to Subscriber
  • DELETERemove Tags from Subscriber
  • POSTTrack Event
  • GETGet Subscriber Events
  • GETGet All Tags
  • POSTCreate a Tag
  • Send Email in HTML
  • Send Email in Markdown
  • Send Email in Tiptap

Integrations

  • ClickFunnels Integration
  • SystemIO Integration

Features

  • Variables
  • Subscriber Events
  • Revenue Tracking
  • Email Deliverability Score
  • Email Engagement Score
  • Content Deliverability Checker

Workflows

  • Wait Step
  • Email Step
  • Action Step
  • Webhook Step

domains

  • Email Domains
  • Web Domains

Rate Limits

Understanding API rate limits, headers, and best practices for handling rate-limited requests

Lumail enforces rate limits to ensure fair usage and protect service quality for all users. This page explains how rate limiting works and how to handle rate-limited requests.

Rate Limits by Plan

API requests are rate-limited per organization based on your subscription plan:

PlanRequests per Minute
Free100
Premium700
Enterprise2,000

Additionally, all requests are subject to an IP-based rate limit of 500 requests per second to prevent abuse.

Rate Limit Headers

Every API response includes rate limit information in the headers:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute
X-RateLimit-RemainingRemaining requests in the current window
X-RateLimit-ResetUnix timestamp when the rate limit resets

Example headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704067260

Rate Limit Exceeded Response

When you exceed the rate limit, the API returns a 429 Too Many Requests response:

{
  "message": "Too many requests",
  "docs": "https://lumail.io/docs/api-reference/api-limits"
}

Additional headers on 429 responses:

HeaderDescription
Retry-AfterSeconds to wait before retrying

Handling Rate Limits

Best Practices

  1. Monitor headers - Track X-RateLimit-Remaining to know when you're approaching the limit
  2. Implement backoff - When rate limited, wait for the Retry-After duration before retrying
  3. Batch requests - Combine multiple operations into fewer API calls where possible
  4. Cache responses - Store frequently accessed data locally to reduce API calls

Exponential Backoff Example

async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);

    if (response.ok) {
      return response;
    }

    if (response.status === 429) {
      // Get retry delay from header or calculate exponentially
      const retryAfter = response.headers.get("Retry-After");
      const waitTime = retryAfter
        ? parseInt(retryAfter, 10) * 1000
        : Math.pow(2, i) * 1000;

      console.log(`Rate limited. Waiting ${waitTime}ms before retry...`);
      await new Promise((resolve) => setTimeout(resolve, waitTime));
      continue;
    }

    throw new Error(`HTTP ${response.status}: ${await response.text()}`);
  }

  throw new Error("Max retries exceeded");
}

Checking Rate Limit Status

Before making requests, you can check your remaining quota:

const response = await fetch("https://lumail.io/api/v1/tags", {
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
  },
});

const limit = response.headers.get("X-RateLimit-Limit");
const remaining = response.headers.get("X-RateLimit-Remaining");
const reset = response.headers.get("X-RateLimit-Reset");

console.log(`${remaining}/${limit} requests remaining`);
console.log(`Resets at: ${new Date(reset * 1000).toISOString()}`);

Increasing Your Rate Limit

If you need higher rate limits:

  1. Upgrade your plan - Premium and Enterprise plans include higher limits
  2. Contact support - For custom enterprise needs, we can discuss tailored solutions

Common Scenarios

Bulk Operations

For bulk imports or updates, consider:

  • Using the POST /api/v1/subscribers endpoint which handles upserts
  • Spreading requests over time instead of bursting
  • Processing in batches with delays between batches
async function bulkImport(subscribers, batchSize = 50, delayMs = 1000) {
  for (let i = 0; i < subscribers.length; i += batchSize) {
    const batch = subscribers.slice(i, i + batchSize);

    // Process batch in parallel
    await Promise.all(
      batch.map((sub) =>
        fetch("https://lumail.io/api/v1/subscribers", {
          method: "POST",
          headers: {
            Authorization: "Bearer YOUR_API_TOKEN",
            "Content-Type": "application/json",
          },
          body: JSON.stringify(sub),
        }),
      ),
    );

    // Wait between batches to stay under rate limit
    if (i + batchSize < subscribers.length) {
      await new Promise((resolve) => setTimeout(resolve, delayMs));
    }
  }
}

Webhooks

When receiving webhooks and calling the API:

  • Process webhook events asynchronously
  • Implement a queue to control request rate
  • Use triggerWorkflows: false when updating subscribers to avoid cascading API calls

Related Documentation

  • API Tokens - Authentication setup
  • Create Subscriber - Bulk import best practices
  • Workflows - Automate without API calls
API TokensSend Transactional Email

On This Page

Rate Limits by PlanRate Limit HeadersRate Limit Exceeded ResponseHandling Rate LimitsBest PracticesExponential Backoff ExampleChecking Rate Limit StatusIncreasing Your Rate LimitCommon ScenariosBulk OperationsWebhooksRelated Documentation

Lumail.io

Create and send e-mail without paying thousands of dollars

Product

BlogDocumentationChangelogDashboard

Company

AboutAccount

Legal

TermsPrivacy

8 The Green STE B, Dover Delaware 19901, United States

© 2025 Codelynx, LLC. All rights reserved.

Sign in