# Limites de requisições

> Como o Emailit limita o envio por workspace, os cabeçalhos ratelimit de cada envio, como é uma resposta 429, os limites de outros endpoints e como tentar de novo com backoff.

O Emailit limita a velocidade e a quantidade de envio de um workspace, não o número de chamadas à API que você faz. Esta página explica os limites de envio, os cabeçalhos que os informam, os poucos endpoints com limites próprios e como aplicar backoff quando você recebe um `429`.

## Limites de envio

Todo workspace tem dois limites de envio. Workspaces novos começam com estes valores padrão em todos os planos:

| Limite | Padrão | Janela |
| --- | --- | --- |
| Por segundo | 2 e-mails | Janela deslizante de um segundo |
| Por dia | 5.000 e-mails | Dia do calendário em UTC, reiniciado às 00:00 UTC |

Como os limites se aplicam:

- **Por workspace.** Todas as chaves de API e o [SMTP relay](/pt/docs/smtp/) compartilham os mesmos contadores. Enviar por SMTP consome a mesma cota que a API.
- **Contados por destinatário.** Cada endereço único em `to`, `cc` e `bcc` é um e-mail. Uma requisição com três destinatários conta como três.
- **Só os envios contam.** Os limites se aplicam a [Enviar um e-mail](/pt/docs/api-reference/emails/send/) e [Encaminhar um e-mail](/pt/docs/api-reference/emails/forward/). Ler dados e gerenciar recursos não conta para eles.
- **Verificado antes, contado depois.** Um envio é aceito desde que o workspace ainda não tenha atingido o limite, e os destinatários dele são somados aos contadores depois. Uma única requisição com muitos destinatários pode levar você além do limite, e as requisições seguintes recebem `429` até a janela ser liberada.

Você pode ver os limites atuais e o uso de hoje no card **Sending Limits** da página inicial do **Dashboard**.

## Cabeçalhos de limite de requisições

As respostas dos endpoints de envio e de encaminhamento incluem estes cabeçalhos:

| Cabeçalho | Descrição |
| --- | --- |
| `ratelimit-limit` | E-mails que o workspace pode enviar por segundo. |
| `ratelimit-remaining` | E-mails restantes na janela de um segundo atual. |
| `ratelimit-reset` | Segundos até a janela por segundo ser reiniciada. |
| `ratelimit-daily-limit` | E-mails que o workspace pode enviar por dia. |
| `ratelimit-daily-remaining` | E-mails restantes hoje. |
| `ratelimit-daily-reset` | Segundos até o limite diário ser reiniciado, às 00:00 UTC. |
| `retry-after` | Segundos a esperar antes de tentar de novo. Enviado apenas com respostas `429`. |

```http
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
ratelimit-limit: 2
ratelimit-remaining: 1
ratelimit-reset: 1
ratelimit-daily-limit: 5000
ratelimit-daily-remaining: 4812
ratelimit-daily-reset: 52113
```

## Quando você atinge um limite

Um envio acima do limite retorna `429 Too Many Requests` com um cabeçalho `retry-after`. O corpo indica qual limite foi atingido:

**429 Por segundo**

```json
{
  "error": "Rate limit exceeded",
  "message": "Too many requests. Maximum 2 messages per second allowed.",
  "limit": 2,
  "current": 2,
  "retry_after": 1
}
```

**429 Diário**

```json
{
  "error": "Daily limit exceeded",
  "message": "Daily sending limit of 5000 messages has been reached.",
  "limit": 5000,
  "current": 5000,
  "retry_after": 41760
}
```

| Campo | Descrição |
| --- | --- |
| `error` | `Rate limit exceeded` para o limite por segundo, `Daily limit exceeded` para o limite diário. |
| `limit` | O limite que foi atingido. |
| `current` | Quantos e-mails já foram contados na janela. |
| `retry_after` | Segundos a esperar. `1` para o limite por segundo e, para o limite diário, os segundos até 00:00 UTC. |

Quando uma requisição é rejeitada, nada é enviado e nenhum crédito é usado. Tente de novo as rejeições do limite por segundo após uma breve espera. Para as rejeições do limite diário, coloque o e-mail na fila e envie-o depois da reinicialização, ou peça um limite maior.

## Outros limites

Alguns endpoints têm limites próprios:

| Endpoint | Limite | Contado por |
| --- | --- | --- |
| `POST /emails/{id}/forward` | 3 por hora | Workspace |
| `POST /webhooks/{id}/test` | 5 por minuto | Endereço IP |
| Links hospedados de inscrição e de descadastro (`/subscribe/{token}`, `/unsubscribe/{token}`) | 30 por minuto | Endereço IP |
| Endpoints públicos de formulário: carregar um formulário (`GET /forms/{token}`) | 60 por minuto | Endereço IP |
| Endpoints públicos de formulário: enviar um formulário (`POST /forms/{token}/submit`) | 30 por minuto | Endereço IP |

Os encaminhamentos também contam para os limites de envio acima. Acima do limite de encaminhamentos, a API retorna `429` com um cabeçalho `retry-after`:

```json
{
  "error": "too_many_requests",
  "message": "Forwarding is limited to 3 emails per hour for this workspace. Try again later."
}
```

Esses limites são fixos e não mudam com o seu plano nem com os seus limites de envio.

## Todos os outros endpoints

Os endpoints que leem dados ou gerenciam recursos não têm um limite fixo por endpoint. Mantenha o seu uso razoável: use um pequeno pool de requisições simultâneas em vez de milhares em paralelo, guarde em cache os dados que raramente mudam e use [webhooks](/pt/docs/webhooks/) em vez de consultar periodicamente o status dos e-mails.

## Aumentar os seus limites

- **Pro e Business.** Os limites aumentam automaticamente à medida que você envia, com base na sua [saúde de envio](/pt/docs/deliverability/sending-health/). O Emailit os aumenta no máximo uma vez a cada sete dias, e apenas enquanto a sua saúde de envio estiver boa e nenhum dos seus domínios estiver pausado.
- **Todos os planos.** Peça um aumento na página inicial do **Dashboard**: selecione **Request Increase** no card **Sending Limits** e informe os limites por segundo e por dia de que você precisa, de onde vem a sua lista e o motivo. A equipe de suporte normalmente analisa as solicitações em até 24 horas.

Consulte [Limites](/pt/docs/limits/) para ver todos os limites dos planos.

## Tentar de novo com backoff

Tente de novo as respostas `429`, `409` (chave de idempotência em uso), `500` e `503`. Aguarde `retry-after` segundos quando o cabeçalho estiver presente e use backoff exponencial com jitter quando ele não estiver. Envie um [`Idempotency-Key`](/pt/docs/api-reference/idempotency/) para que um envio repetido nunca seja entregue duas vezes, e não espere o fim de um limite diário em um loop de requisições.

**cURL**

```bash
# curl retries 429 and 5xx responses and honors retry-after.
curl https://api.emailit.com/v2/emails \
  --retry 5 --retry-max-time 60 \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-confirmation" \
  -d '{
    "from": "Acme <orders@acme.com>",
    "to": "ada@example.com",
    "subject": "Your order #1042",
    "text": "Thanks for your order."
  }'
```

**Node.js**

```javascript
import { randomUUID } from 'node:crypto';

const RETRYABLE = new Set([409, 429, 500, 503]);
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

export async function sendEmail(payload, maxAttempts = 5) {
  const idempotencyKey = randomUUID();

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const response = await fetch('https://api.emailit.com/v2/emails', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.EMAILIT_API_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': idempotencyKey,
      },
      body: JSON.stringify(payload),
    });
    const body = await response.json();
    if (response.ok) return body;

    const retryAfter = Number(response.headers.get('retry-after')) || 0;
    // Daily limit: retry_after is hours away, so give up and queue it.
    if (!RETRYABLE.has(response.status) || retryAfter > 60 || attempt === maxAttempts) {
      throw new Error(`Emailit ${response.status}: ${body.message ?? body.error}`);
    }

    const backoff = Math.min(1000 * 2 ** (attempt - 1), 30_000);
    await sleep(retryAfter ? retryAfter * 1000 : backoff + Math.random() * 250);
  }
}
```

**Python**

```python
import os
import random
import time
import uuid

import requests

RETRYABLE = {409, 429, 500, 503}

def send_email(payload, max_attempts=5):
    idempotency_key = str(uuid.uuid4())

    for attempt in range(1, max_attempts + 1):
        response = requests.post(
            "https://api.emailit.com/v2/emails",
            headers={
                "Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}",
                "Idempotency-Key": idempotency_key,
            },
            json=payload,
            timeout=30,
        )
        if response.ok:
            return response.json()

        retry_after = int(response.headers.get("retry-after", 0))
        # Daily limit: retry_after is hours away, so give up and queue it.
        if response.status_code not in RETRYABLE or retry_after > 60 or attempt == max_attempts:
            response.raise_for_status()

        backoff = min(2 ** (attempt - 1), 30) + random.random() / 4
        time.sleep(retry_after or backoff)
```

## Dicas para alto volume

- Envie a partir de uma fila com um número fixo de workers e dimensione o pool de acordo com o seu limite por segundo.
- Distribua grandes jobs em lote ao longo do dia em vez de iniciar todos de uma vez, para que um único job não consuma toda a cota diária.
- Acompanhe `ratelimit-daily-remaining` e reduza o ritmo antes que ele chegue a zero.
- Para newsletters para as suas listas de contatos, use [campanhas](/pt/docs/campaigns/) em vez de chamar o endpoint de envio em um loop.

## Veja também

  - [Limites](/pt/docs/limits/): Limites de envio e cotas dos planos em um só lugar.
  - [Saúde de envio](/pt/docs/deliverability/sending-health/): A pontuação que determina os aumentos automáticos de limite.
  - [Idempotência](/pt/docs/api-reference/idempotency/): Tente enviar de novo sem enviar duas vezes.
  - [Erros](/pt/docs/api-reference/errors/): Todos os formatos de erro e códigos de status.

---
Fonte: https://emailit.com/pt/docs/api-reference/rate-limits/
