Référence
Limites de débit
Comment Emailit limite l’envoi par espace de travail, les en-têtes ratelimit de chaque envoi, l’aspect d’une réponse 429, les autres limites des endpoints et comment relancer avec un intervalle exponentiel.
Emailit limite la vitesse et le volume d’envoi d’un espace de travail, pas le nombre d’appels API que vous effectuez. Cette page présente les limites d’envoi, les en-têtes qui les indiquent, les quelques endpoints qui ont leurs propres limites et la façon d’espacer vos requêtes lorsque vous recevez une réponse 429.
Limites d’envoi
Chaque espace de travail a deux limites d’envoi. Les nouveaux espaces de travail démarrent avec ces valeurs par défaut, quel que soit le forfait :
| Limite | Par défaut | Fenêtre |
|---|---|---|
| Par seconde | 2 e-mails | Fenêtre glissante d’une seconde |
| Par jour | 5 000 e-mails | Jour calendaire en UTC, réinitialisé à 0 h 00 UTC |
Application des limites :
- Par espace de travail. Toutes les clés API et le relais SMTP partagent les mêmes compteurs. Un envoi via SMTP consomme le même quota que l’API.
- Décompte par destinataire. Chaque adresse unique dans
to,ccetbcccompte pour un e-mail. Une requête avec trois destinataires compte pour trois. - Seuls les envois comptent. Les limites s’appliquent à Envoyer un e-mail et à Transférer un e-mail. La lecture de données et la gestion des ressources ne sont pas décomptées.
- Vérification avant, décompte après. Un envoi est accepté tant que l’espace de travail n’a pas encore atteint la limite, et ses destinataires sont ajoutés aux compteurs ensuite. Une seule requête avec de nombreux destinataires peut vous faire dépasser la limite : les requêtes suivantes reçoivent alors
429jusqu’à ce que la fenêtre se libère.
Les limites actuelles et la consommation du jour s’affichent dans la carte Sending Limits de la page d’accueil Dashboard.
En-têtes de limite de débit
Les réponses des endpoints d’envoi et de transfert comportent ces en-têtes :
| En-tête | Description |
|---|---|
ratelimit-limit |
Nombre d’e-mails que l’espace de travail peut envoyer par seconde. |
ratelimit-remaining |
Nombre d’e-mails restants dans la fenêtre d’une seconde en cours. |
ratelimit-reset |
Secondes avant la réinitialisation de la fenêtre par seconde. |
ratelimit-daily-limit |
Nombre d’e-mails que l’espace de travail peut envoyer par jour. |
ratelimit-daily-remaining |
Nombre d’e-mails restants aujourd’hui. |
ratelimit-daily-reset |
Secondes avant la réinitialisation de la limite quotidienne, à 0 h 00 UTC. |
retry-after |
Secondes à attendre avant de relancer. Envoyé uniquement avec les réponses 429. |
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: 52113Lorsque vous atteignez une limite
Un envoi au-delà de la limite renvoie 429 Too Many Requests avec un en-tête retry-after. Le corps indique quelle limite vous avez atteinte :
{
"error": "Rate limit exceeded",
"message": "Too many requests. Maximum 2 messages per second allowed.",
"limit": 2,
"current": 2,
"retry_after": 1
}{
"error": "Daily limit exceeded",
"message": "Daily sending limit of 5000 messages has been reached.",
"limit": 5000,
"current": 5000,
"retry_after": 41760
}| Champ | Description |
|---|---|
error |
Rate limit exceeded pour la limite par seconde, Daily limit exceeded pour la limite quotidienne. |
limit |
La limite atteinte. |
current |
Le nombre d’e-mails déjà décomptés dans la fenêtre. |
retry_after |
Secondes à attendre. 1 pour la limite par seconde, et le nombre de secondes jusqu’à 0 h 00 UTC pour la limite quotidienne. |
Lorsqu’une requête est rejetée, rien n’est envoyé et aucun crédit n’est consommé. Relancez les requêtes rejetées par la limite par seconde après une courte attente. En cas de rejet par la limite quotidienne, mettez l’e-mail en file d’attente et envoyez-le après la réinitialisation, ou demandez une limite plus élevée.
Autres limites
Quelques endpoints ont leurs propres limites :
| Endpoint | Limite | Décompte par |
|---|---|---|
POST /emails/{id}/forward |
3 par heure | Espace de travail |
POST /webhooks/{id}/test |
5 par minute | Adresse IP |
Liens d’inscription et de désinscription hébergés (/subscribe/{token}, /unsubscribe/{token}) |
30 par minute | Adresse IP |
Endpoints publics des formulaires : chargement d’un formulaire (GET /forms/{token}) |
60 par minute | Adresse IP |
Endpoints publics des formulaires : envoi d’un formulaire (POST /forms/{token}/submit) |
30 par minute | Adresse IP |
Les transferts sont aussi décomptés des limites d’envoi ci-dessus. Au-delà de la limite de transferts, l’API renvoie 429 avec un en-tête retry-after :
{
"error": "too_many_requests",
"message": "Forwarding is limited to 3 emails per hour for this workspace. Try again later."
}Ces limites sont fixes et ne varient pas selon votre forfait ni vos limites d’envoi.
Tous les autres endpoints
Les endpoints qui lisent des données ou gèrent des ressources n’ont pas de limite fixe par endpoint. Gardez un usage raisonnable : utilisez un petit nombre de requêtes simultanées plutôt que des milliers en parallèle, mettez en cache les données qui changent rarement, et utilisez des webhooks plutôt que d’interroger régulièrement l’API pour connaître le statut des e-mails.
Augmenter vos limites
- Pro et Business. Les limites augmentent automatiquement à mesure que vous envoyez, en fonction de votre santé d’envoi. Emailit les augmente au plus une fois tous les sept jours, et uniquement tant que votre santé d’envoi est bonne et qu’aucun de vos domaines n’est en pause.
- Tous les forfaits. Demandez une hausse depuis la page d’accueil Dashboard : sélectionnez Request Increase dans la carte Sending Limits, puis saisissez les limites par seconde et par jour dont vous avez besoin, la provenance de votre liste et la raison de votre demande. L’équipe support examine généralement les demandes sous 24 heures.
Pour toutes les limites des forfaits, consultez Limites.
Relancer avec un intervalle exponentiel
Relancez les requêtes qui renvoient 429, 409 (clé d’idempotence en cours d’utilisation), 500 et 503. Attendez retry-after secondes lorsque l’en-tête est présent, et utilisez sinon un intervalle exponentiel avec une part d’aléatoire (jitter). Envoyez une Idempotency-Key pour qu’un envoi relancé ne soit jamais livré deux fois, et n’attendez pas la fin d’une limite quotidienne dans une boucle de requêtes.
# 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."
}'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);
}
}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)Conseils pour les gros volumes
- Envoyez depuis une file d’attente avec un nombre fixe de workers, et dimensionnez le pool selon votre limite par seconde.
- Répartissez les gros traitements par lots sur la journée au lieu de les lancer tous en même temps, pour qu’une seule tâche ne consomme pas tout le quota quotidien.
- Surveillez
ratelimit-daily-remaininget ralentissez avant qu’il n’atteigne zéro. - Pour les newsletters destinées à vos listes de contacts, utilisez les campagnes plutôt qu’une boucle sur l’endpoint d’envoi.