> ## Documentation Index
> Fetch the complete documentation index at: https://docs.unosend.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate Limits

> Understand API rate limits per plan and how to handle them in your applications.

## Overview

Rate limits protect the API from abuse and ensure fair usage for all users. Limits are applied **per organization** using an in-memory sliding window.

### API Request Limits

| Tier            | Requests/Second | Requests/Minute | Requests/Day |
| --------------- | --------------- | --------------- | ------------ |
| **Standard**    | 10              | 500             | 50,000       |
| **High Volume** | 50              | 2,000           | 200,000      |

<Note>
  Need higher limits? [Contact us](/contact) to discuss your volume requirements.
</Note>

### Email Sending

Unosend uses a credit-based system. 1 credit = 1 email. [Contact us](https://unosend.co/contact) for pricing and volume details.

* No subscription — buy credits when you need them
* Email size limit: **15 MB** (headers + body + inline images + attachments)

### Domain Sending Limit

There is a global daily limit of **200,000 emails per sender domain** across all plans. This protects shared infrastructure and ensures deliverability.

### Domain Creation Rate Limit

All plans include **unlimited domains**. To prevent abuse, domain creation is rate limited to **10 domains per hour** per organization. This is a velocity cap — there is no limit on the total number of domains you can add.

| Limit            | Value                 |
| ---------------- | --------------------- |
| Domains per hour | 10                    |
| Total domains    | Unlimited (all plans) |

If you exceed this limit, the API returns `429 Too Many Requests`. Wait and retry after a few minutes.

## Rate Limit Headers

Every API response includes headers to help you track your rate limit status:

| Header                  | Description                            |
| ----------------------- | -------------------------------------- |
| `X-RateLimit-Limit`     | Maximum requests allowed per window    |
| `X-RateLimit-Remaining` | Requests remaining in current window   |
| `X-RateLimit-Reset`     | Unix timestamp when window resets      |
| `Retry-After`           | Seconds to wait (only on 429 response) |

### Example Response Headers

```txt response-headers.txt theme={null}
HTTP/1.1 200 OK
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 485
X-RateLimit-Reset: 1705320060
Content-Type: application/json
```

## Check Current Usage

You can check your current rate limit status with any API request by inspecting the response headers, or use the usage endpoint:

```bash Terminal theme={null}
curl -X GET "https://api.unosend.co/usage" \
  -H "Authorization: Bearer un_your_api_key" \
  -i
```

### Response

```json response.json theme={null}
{
  "credits_remaining": 37550,
  "credits_used": 12450,
  "credits_total": 50000,
  "credits_expire_at": "2026-07-01T00:00:00Z"
}
```

## Handling Rate Limits

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

```json rate-limit-response.json theme={null}
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Retry after 60 seconds.",
    "retry_after": 60
  }
}
```

### Implementing Retry Logic

<CodeGroup>
  ```bash cURL with Retry theme={null}
  # Use --retry flag for automatic retries
  curl -X POST "https://api.unosend.co/emails" \
    -H "Authorization: Bearer un_your_api_key" \
    -H "Content-Type: application/json" \
    --retry 3 \
    --retry-delay 5 \
    -d '{"from": "hello@yourdomain.com", "to": "user@example.com", "subject": "Hello", "html": "<p>Hi!</p>"}'
  ```

  ```typescript JavaScript/TypeScript theme={null}
  async function sendEmailWithRetry(
    payload: EmailPayload,
    maxRetries: number = 3
  ): Promise<Response> {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
      const response = await fetch('https://api.unosend.co/emails', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(payload)
      });
      
      if (response.status === 429) {
        const retryAfter = parseInt(
          response.headers.get('Retry-After') || '60'
        );
        console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
        await sleep(retryAfter * 1000);
        continue;
      }
      
      return response;
    }
    
    throw new Error('Max retries exceeded');
  }

  function sleep(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
  ```

  ```python Python theme={null}
  import requests
  import time

  def send_email_with_retry(payload, max_retries=3):
      api_key = "un_your_api_key"
      
      for attempt in range(max_retries):
          response = requests.post(
              "https://api.unosend.co/emails",
              headers={
                  "Authorization": f"Bearer {api_key}",
                  "Content-Type": "application/json"
              },
              json=payload
          )
          
          if response.status_code == 429:
              retry_after = int(response.headers.get("Retry-After", 60))
              print(f"Rate limited. Waiting {retry_after} seconds...")
              time.sleep(retry_after)
              continue
          
          return response
      
      raise Exception("Max retries exceeded")
  ```
</CodeGroup>

## Exponential Backoff

For robust retry logic, use exponential backoff with jitter to avoid thundering herd:

```typescript exponential-backoff.ts theme={null}
async function sendWithExponentialBackoff(
  payload: EmailPayload,
  maxRetries: number = 5
): Promise<Response> {
  const baseDelay = 1000; // 1 second
  
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch('https://api.unosend.co/emails', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(payload)
      });
      
      if (response.status === 429) {
        // Calculate delay with exponential backoff + jitter
        const delay = baseDelay * Math.pow(2, attempt);
        const jitter = Math.random() * 1000;
        const waitTime = delay + jitter;
        
        console.log(`Rate limited. Waiting ${waitTime}ms (attempt ${attempt + 1})`);
        await sleep(waitTime);
        continue;
      }
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      
      return response;
      
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
      
      const delay = baseDelay * Math.pow(2, attempt);
      await sleep(delay);
    }
  }
  
  throw new Error('Max retries exceeded');
}
```

## Queue Pattern for Bulk Sending

For sending many emails, use a queue with rate limiting to stay within limits:

```typescript rate-limited-queue.ts theme={null}
class RateLimitedQueue {
  private queue: EmailPayload[] = [];
  private processing = false;
  private requestsPerSecond: number;
  
  constructor(requestsPerSecond: number = 10) {
    this.requestsPerSecond = requestsPerSecond;
  }
  
  async add(payload: EmailPayload): Promise<void> {
    this.queue.push(payload);
    this.process();
  }
  
  private async process(): Promise<void> {
    if (this.processing) return;
    this.processing = true;
    
    const interval = 1000 / this.requestsPerSecond;
    
    while (this.queue.length > 0) {
      const payload = this.queue.shift()!;
      
      try {
        await sendEmailWithRetry(payload);
      } catch (error) {
        console.error('Failed to send email:', error);
      }
      
      await sleep(interval);
    }
    
    this.processing = false;
  }
}

// Usage
const queue = new RateLimitedQueue(10); // 10 req/sec

for (const recipient of recipients) {
  queue.add({
    from: 'hello@yourdomain.com',
    to: recipient.email,
    subject: 'Hello!',
    html: '<p>Your email content</p>'
  });
}
```

<Tip>
  For bulk sending, consider using the `/emails/batch` endpoint which allows up to 100 emails per request, significantly reducing API calls.
</Tip>

## Best Practices

<Steps>
  <Step title="Monitor rate limit headers">
    Check `X-RateLimit-Remaining` and slow down before hitting limits.
  </Step>

  <Step title="Use batch endpoints">
    Send multiple emails in one request using `POST /emails/batch` to reduce API calls.
  </Step>

  <Step title="Implement queuing">
    Queue emails during high-traffic periods and process them at a controlled rate.
  </Step>

  <Step title="Use webhooks instead of polling">
    Instead of polling for status, use webhooks to receive delivery updates asynchronously.
  </Step>

  <Step title="Cache responses when possible">
    Cache responses from endpoints like `GET /domains` to reduce unnecessary requests.
  </Step>
</Steps>

## Need Higher Limits?

<Info>
  If you need higher rate limits for your use case, upgrade your plan or contact us for Enterprise options with custom limits.

  * [View Plans →](https://www.unosend.co/pricing)
  * [Contact Sales →](mailto:support@unosend.co)
</Info>
