Plafonner la dépense d'un client
Une équipe consomme des modèles à vos frais, et vous voulez borner ce qu’elle peut dépenser dans le mois. Cette page décrit le plan, son plafond, et ce que reçoit exactement l’appelant qui le dépasse.
Trois états, et deux refus qu’on ne doit pas confondre
Section intitulée « Trois états, et deux refus qu’on ne doit pas confondre »Un plan est l’arrangement de facturation sous lequel la passerelle revend l’accès.
plans.max_cost_euro est le plafond mensuel du client, en euros.
| État du compte | Ce que répond la passerelle |
|---|---|
users.plan_id vide — aucun plan |
403 {"error": "No plan assigned. Ask your administrator to assign one."} |
| plan dont le plafond est vide | servi, quelle que soit la dépense — le plan est illimité, à dessein |
| plan avec un plafond | servi tant que la dépense du mois est sous le plafond, 402 {"error": "Plan limit reached"} au-delà |
Les deux codes sont différents parce que ce ne sont pas les mêmes personnes qui les lèvent.
402 dit « le titulaire a dépensé son plan » : un paiement, ou le mois suivant, le
lève, et c’est le titulaire du compte qui agit.
403 dit « il n’y a pas de plan à dépenser » : aucun paiement ne peut y être
imputé, le mois suivant n’y change rien, et seul l’exploitant le lève, en affectant
un plan depuis la console. Un compte sans plan était auparavant servi sans
limite ; ce n’est plus le cas depuis le 2026-07-29.
Un troisième 403 existe, de sens différent — {"error": "Endpoint \"<nom>\" is disabled."} — quand l’endpoint visé existe mais a été désactivé. Il est rendu
avant le contrôle de quota : un endpoint éteint ne consomme rien et n’a pas à
dépendre de la solvabilité de l’appelant.
Créer un plan
Section intitulée « Créer un plan »Onglet Plans, formulaire Add plan : un nom, et un plafond mensuel en euros.
Le nom est unique — la console refuse en 409 un nom déjà pris.
Laisser le champ de plafond vide crée un plan illimité. C’est une valeur
distincte de zéro, et une situation distincte de « ce compte n’a pas de plan » : le
plan illimité passe toujours, le compte sans plan ne passe jamais. Les deux
donnaient jadis la même chose en base ; ils sont séparés depuis la migration
011-plans-plafond-illimite.
Le plan administrator, semé par cette même migration, est illimité par
construction. La passerelle l’affecte au compte admin au démarrage si ce compte
n’a pas déjà un plan : un plan que vous lui auriez donné délibérément, plafonné
par exemple, n’est jamais repris par un redémarrage.
Affecter un plan, ou le retirer
Section intitulée « Affecter un plan, ou le retirer »Onglet Users, sélecteur de la colonne Plan sur la ligne du compte. Le changement prend effet à la requête suivante.
La valeur No plan du même sélecteur retire son plan au compte : c’est le geste de blocage immédiat. Un badge « Blocked » apparaît sur la ligne.
Relever ou abaisser un plafond
Section intitulée « Relever ou abaisser un plafond »Onglet Plans, édition en ligne. La modification porte sur le plan, donc sur tous les comptes qui le portent.
La suppression d’un plan est refusée en 409 tant que des comptes le portent — le
message demande de les réaffecter d’abord. C’est délibéré : supprimer un plan porté
bloquerait en masse les comptes qui en dépendent.
Ce que la passerelle compte, exactement
Section intitulée « Ce que la passerelle compte, exactement »Le plafond n’est pas une estimation périodique : la dépense du mois est recalculée
à chaque requête relayée, par agrégat sur request_logs joint aux prix par token
de la table models.
- La fenêtre est le mois calendaire en cours :
timestamp >= date_trunc('month', NOW()). Elle repart à zéro au premier du mois, pas trente jours après la première requête. - La comparaison est
>=: à plafond exactement atteint, le refus commence. - Le prix vient des modèles, en nano-euros par token entrant et par token sortant. Ce sont ces colonnes, et elles seules, qui alimentent le coût.
C’est la requête la plus coûteuse du service. Elle n’est pas exécutée pour un compte sans plan — il n’y a pas de plafond à comparer, donc pas de total à calculer.
Ce qui empêche un plafond de tenir
Section intitulée « Ce qui empêche un plafond de tenir »À vérifier avant de promettre un plafond à un client. Chaque point ci-dessous fait qu’une consommation réelle ne compte pas dans le total.
Un modèle sans prix compte pour zéro. Les prix par token valent 0 par défaut à
la création d’un modèle. Un modèle servi et laissé à zéro ne fait jamais monter
aucun compteur, donc ne déclenche jamais aucun plafond. C’est le défaut le plus
courant, et le plus silencieux : renseignez les prix en même temps que le modèle.
Un flux en cours n’est pas encore compté. Sur une réponse en streaming, la ligne
de request_logs n’est écrite qu’à la fin du flux. Entre-temps, la consommation
existe et n’est pas visible du contrôle de quota.
Un flux OpenAI sans stream_options compte pour zéro. Le format streaming
d’OpenAI n’émet les compteurs de tokens que si le client a demandé
stream_options: {include_usage: true}. Sans cela, la requête est journalisée à
zéro token et ne pèse sur aucun plafond.
Une journalisation qui échoue est perdue sans bruit. Flux tronqué, amont qui coupe, base indisponible : la ligne est abandonnée, sans exception ni interruption de la réponse au client. Le choix est assumé — un échec de comptage ne coûte jamais rien à l’appelant — et sa contrepartie est qu’une consommation peut n’être jamais facturée.
La requête qui franchit le plafond est servie en entier. Le contrôle compare la dépense déjà enregistrée avant de relayer ; il ne devine pas le coût de la requête en cours. Le dépassement se constate donc toujours après coup, d’au moins un appel.
Les plafonds saisis avant la migration 007 ont pu être arrondis. La colonne
était un entier : 12,50 € était enregistré 13 €, sans erreur. La migration a
corrigé le type mais ne restaure pas les décimales perdues. Sur une base
ancienne, relisez les plafonds à centimes et ressaisissez-les.
Voir où en est un client
Section intitulée « Voir où en est un client »L’onglet Usage donne les coûts, filtrables par compte et par modèle. L’onglet Plans donne les plafonds.
Aucun écran ne rapproche les deux. Ni la liste des comptes, ni l’écran Usage, ni
l’écran Plans ne montrent la consommation du mois en cours face au plafond qui
bloquera : le rapprochement est à faire à la main, et l’approche d’un 402 ne se
voit pas venir dans la console.
Le journal de la passerelle, lui, imprime le rapprochement à chaque requête relayée,
sous la forme [COST] <compte>: €<dépensé> used / €<plafond> limit. C’est
aujourd’hui le seul endroit où les deux nombres apparaissent côte à côte.