G-SMS.

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

LimiteValeurAu dépassement
Débit par clé API10 requêtes par seconde429 RATE_LIMITED, avec Retry-After: 1
Quota journalier par comptedésactivé par défaut429 QUOTA_EXCEEDED une fois le plafond atteint, remis à zéro au jour calendaire UTC
Longueur du texte1600 caractères400 TEXT_TOO_LONG
Longueur de clientReference64 caractères400 VALIDATION_ERROR
Taille de page du journal20 par défaut, 100 au maximumune valeur supérieure est ramenée à 100, sans erreur
Durée de vie d'un message en attente24 heuresFAILED avec failureReason TIMEOUT, et remboursement
Rétention du texte des messages90 joursle texte est effacé, les métadonnées de facturation restent
Fenêtre de validité de la signature webhook5 minutesau-delà, c'est au consommateur de refuser l'appel
Abandon d'un webhook non remis48 heuresla livraison passe EXHAUSTED et reste rejouable depuis la console
Ces valeurs sont des réglages du serveur, pas des constantes du protocole : elles peuvent être ajustées, à la hausse pour un compte qui le justifie. Ne les code pas en dur comme des vérités éternelles — traite plutôt les réponses qu'elles produisent.

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-After et 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. Un 400, 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.

Créer un compte