Quotas et limites
Les limites de G-SMS existent pour protéger le service et ton solde, pas pour contraindre les usages : elles sont hautes pour un trafic transactionnel, et connues à l'avance. En voici la liste complète, ainsi que la manière de les absorber proprement.
Toutes les limites en un tableau
| Limite | Valeur | Au dépassement |
|---|---|---|
| Débit par clé API | 10 requêtes par seconde | 429 RATE_LIMITED, avec Retry-After: 1 |
| Quota journalier par compte | désactivé par défaut | 429 QUOTA_EXCEEDED une fois le plafond atteint, remis à zéro au jour calendaire UTC |
| Longueur du texte | 1600 caractères | 400 TEXT_TOO_LONG |
| Longueur de clientReference | 64 caractères | 400 VALIDATION_ERROR |
| Taille de page du journal | 20 par défaut, 100 au maximum | une valeur supérieure est ramenée à 100, sans erreur |
| Durée de vie d'un message en attente | 24 heures | FAILED avec failureReason TIMEOUT, et remboursement |
| Rétention du texte des messages | 90 jours | le texte est effacé, les métadonnées de facturation restent |
| Fenêtre de validité de la signature webhook | 5 minutes | au-delà, c'est au consommateur de refuser l'appel |
| Abandon d'un webhook non remis | 48 heures | la livraison passe EXHAUSTED et reste rejouable depuis la console |
Gérer un 429 proprement
La limite de débit s'applique par clé API, pas par compte : créer une clé par usage — une pour les codes de vérification, une pour les notifications de masse — évite qu'un traitement de nuit n'étouffe un envoi urgent.
Un dépassement renvoie 429 RATE_LIMITED avec Retry-After: 1. Rien n'a été débité, rien n'a été créé : la requête peut être rejouée telle quelle.
Trois règles suffisent à ne jamais perdre de message :
- Lire
Retry-Afteret attendre cette durée. Réessayer immédiatement ne fait que consommer un jeton de plus et prolonger le blocage. - Ne réessayer que ce qui mérite de l'être. Un
429, oui. Un400, jamais : il redonnera le même résultat. - Poser un
clientReference. Un réessai après une réponse perdue ne créera alors jamais de doublon — voir l'idempotence.
const pause = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function envoyerAvecReprise(charge, essaisMax = 4) {
for (let essai = 1; essai <= essaisMax; essai++) {
const reponse = await fetch('https://api.sms.gworldship.com/v1/sms', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.GSMS_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(charge),
});
// Seul le 429 se réessaie tel quel : un 400 réessayé restera un 400.
if (reponse.status !== 429) {
return reponse;
}
// Le serveur dit combien de temps attendre. On le croit.
const attente = Number(reponse.headers.get('Retry-After') || essai);
await pause(attente * 1000);
}
throw new Error('Limite de débit toujours atteinte après ' + essaisMax + ' tentatives');
}Pour un envoi de masse, la reprise sur erreur ne suffit pas : mieux vaut ne jamais heurter la limite. Un rythme régulier, légèrement sous le plafond, est plus rapide qu'une rafale suivie d'attentes forcées.
// Envoi de masse : un rythme régulier plutôt que des rafales.
// 9 envois par seconde laissent une marge sous la limite de 10.
const INTERVALLE_MS = 1000 / 9;
async function envoyerLot(messages) {
const resultats = [];
for (const message of messages) {
const debut = Date.now();
resultats.push(await envoyerAvecReprise(message));
const reste = INTERVALLE_MS - (Date.now() - debut);
if (reste > 0) {
await pause(reste);
}
}
return resultats;
}À plus grande échelle, la même logique se délègue à une file de travaux avec un débit plafonné : l'appelant dépose les messages, un seul consommateur les écoule au rythme autorisé. L'avantage n'est pas le débit, c'est qu'un incident ne perd rien.
Le quota journalier, lui, ne se contourne pas par une attente de quelques secondes : un 429 QUOTA_EXCEEDED ne porte pas d'en-tête Retry-After et le compteur repart au changement de jour UTC. Ce quota est désactivé par défaut ; s'il est en place sur ton compte, c'est le signe qu'un plafond a été demandé.
Durée de vie et remboursement
Un message accepté est débité immédiatement. S'il n'a pas pu être remis dans les 24 heures, il n'est pas laissé indéfiniment en attente : il bascule en FAILED avec failureReason: TIMEOUT, et le montant est recrédité.
Tout FAILED est remboursé, quelle qu'en soit la cause, pour le montant exact du débit et une seule fois. Le journal des mouvements de la console montre les deux écritures, le débit puis le crédit : la facturation reste vérifiable ligne à ligne.
Un SENT reste facturé même s'il ne devient jamais DELIVERED : le message a bien été remis à l'opérateur. Les détails sont sur la page statuts et accusés de réception.
Longueur du texte et segments
Un SMS est facturé au segment, et le nombre de segments dépend de l'alphabet utilisé. Tant que le texte n'emploie que des caractères de l'alphabet GSM-7, un segment contient 160 caractères ; au-delà d'un segment, chacun n'en contient plus que 153, la place perdue servant au réassemblage. Dès qu'un seul caractère sort de cet alphabet, le message entier bascule en UCS-2 : 70 caractères pour un segment seul, 67 par segment ensuite.
Un unique caractère peut donc doubler la facture d'une campagne. Les principaux coupables, tous absents de l'alphabet GSM-7 :
ê â î ô û ë ï ç œ « » ’ … et tout émoji À l'inverse, é, è, à, ù, ö, ä, ñ et ü appartiennent à l'alphabet GSM-7 : le français courant passe sans surcoût, à condition d'écrire une apostrophe droite et trois points plutôt que leurs équivalents typographiques. Quelques caractères (€, {, }, [, ], |, ~, ^, \) restent en GSM-7 mais comptent double.
La limite absolue est de 1600 caractères, tous alphabets confondus. Un émoji compte pour deux dans ce décompte, comme dans celui des segments.
Le calculateur de segments applique exactement ces règles et donne le coût avant l'envoi.
Ces quatre tailles — 160, 153, 70 et 67 — sont elles aussi des réglages du serveur. Elles correspondent aux valeurs standard du SMS, mais rien n'oblige à les traiter comme gravées dans le protocole : la source de vérité reste le champ segments de la réponse.
Rétention des textes
Le texte d'un message est conservé 90 jours, puis effacé. Ce qui reste ensuite au journal : l'identifiant, le destinataire, l'opérateur, le nombre de segments, le prix, le statut et les horodatages — de quoi vérifier une facture ou reconstituer une livraison, sans garder indéfiniment le contenu des communications.
Si une obligation impose de conserver le contenu plus longtemps, c'est à l'application émettrice de l'archiver de son côté : G-SMS n'est pas un système d'archivage.
Prêt à envoyer ton premier SMS ?
Crée un compte, reçois 100 F de crédit et une clé API immédiate.