MeterFlow

Chaque boîte de dialogue « Nouveau … », expliquée en langage clair

Le tableau de bord MeterFlow comporte quelques boîtes de dialogue qui créent de vrais enregistrements dans la base de données — meters, plans, abonnements, crédits, événements d’usage, clés API. Cette page explique ce que fait chacune, champ par champ, avec des exemples simples. Aucune connaissance préalable du metering ou de la facturation à l’usage n’est nécessaire.

Commencez ici : la vue d’ensemble

MeterFlow répond à une seule question pour votre produit : « qui a utilisé combien de quoi — et combien cela lui coûte ? » Tout ce que vous voyez dans le tableau de bord existe pour répondre à cette question.

Vous admin clientLe développeur ou l’entreprise qui utilise MeterFlow. Vous vous connectez à ce tableau de bord, définissez quoi mesurer et fixez les règles tarifaires.
Votre application le SDKVotre propre backend, avec le SDK MeterFlow installé. Il envoie les événements d’usage automatiquement à mesure que vos clients utilisent votre produit. Les boîtes de dialogue usage/crédits/abonnements font à la main exactement ce que le SDK fait dans le code.
Votre client ID clientL’utilisateur final de votre produit. Il ne se connecte jamais à MeterFlow et n’a pas de compte MeterFlow — il n’existe ici que sous la forme d’une chaîne d’identification que vous choisissez (p. ex. user-842 ou un e-mail).

Comment les pièces s’assemblent

Pourquoi certains boutons « Créer » sont-ils grisés ?

Chaque boîte de dialogue désactive son bouton de confirmation tant que tous les champs obligatoires (marqués *) ne sont pas remplis — p. ex. « Create plan » reste désactivé tant que le plan n’a pas de Nom. Si un bouton semble bloqué, cherchez un champ obligatoire vide plus haut.

Nouvelle organisation conteneur

Le conteneur le plus externe — généralement votre entreprise. Tout le reste (projets, meters, plans…) vit à l’intérieur d’une organisation. Vous en avez reçu une automatiquement à l’inscription.

📍 Dashboard → le bouton « New organization » (proposé aussi à la première connexion, quand vous n’en avez pas encore)

  • Name *

    Le nom de votre entreprise ou de votre équipe. Une simple étiquette — modifiable plus tard.

  • Billing email

    Où iraient les factures et avis de facturation de votre compte MeterFlow. Facultatif ; le format est validé, mais rien n’est envoyé pour le vérifier.

ExempleAcme Robotics crée l’organisation « Acme Robotics » avec l’e-mail de facturation finance@acme.dev. Ses deux produits deviendront deux projets à l’intérieur.

Nouveau projet conteneur

Un projet = un produit ou un environnement à mesurer. Chaque meter, plan, clé API, solde client et événement d’usage appartient à exactement un projet — les projets ne voient jamais les données les uns des autres.

📍 Dashboard → le bouton « New project » dans l’en-tête du tableau Projects

  • Organization *

    À quelle organisation appartient le projet. Présélectionnée si vous en avez déjà une active.

  • Name *

    Le nom du produit, p. ex. « PixelForge AI ». Affiché partout dans le tableau de bord et dans le sélecteur de projet.

  • Description

    Texte libre, pour votre propre référence.

ExempleAcme a un outil d’images et un chatbot. Ils créent deux projets — « PixelForge AI » et « ChatDesk » — pour que chaque produit ait ses propres meters, plans et soldes clients. Le même ID client dans deux projets est traité comme deux clients sans aucun lien.

Générer une clé API accès

L’identifiant que votre application utilise pour parler à MeterFlow. Votre backend le transmet au SDK ; chaque événement d’usage, opération de crédits et appel d’abonnement est authentifié — et limité à un seul projet — par cette clé.

📍 Ouvrez un projet → API Keys → le bouton dans l’en-tête du tableau

  • Key name *

    Une étiquette pour vous rappeler où la clé est utilisée — « Backend de production », « Staging », « Tests CI ». Aucun effet technique.

  • Environment

    Les clés Live commencent par mf_live_, les clés Test par mf_test_ — et elles accèdent à deux jeux de données totalement séparés au sein du même projet. Les abonnements, crédits et usages créés avec une clé Test sont invisibles pour les clés Live (et inversement), tandis que vos meters et plans sont partagés : vos tests s’exécutent donc toujours contre votre vraie configuration de facturation. Utilisez des clés Test pour le développement, le staging et la CI ; les clés Live uniquement pour le vrai trafic de production.

Important — affichée une seule foisLa clé complète n’est affichée qu’une seule fois, juste après sa création. MeterFlow ne conserve qu’une empreinte cryptographique (un hachage SHA-256) — la vraie clé ne pourra plus jamais être affichée, pas même par nous. Copiez-la immédiatement dans votre coffre à secrets. Si vous la perdez, révoquez-la et générez-en une nouvelle.
ExempleVous créez « Production backend » / Live, obtenez mf_live_a1b2… une seule fois, et la placez dans les variables d’environnement de votre serveur : new MeterFlow({ apiKey: process.env.METERFLOW_KEY }). La liste du tableau de bord n’affichera plus jamais que le préfixe et les 4 derniers caractères.
Les clés de test partagent-elles les limites de mon forfait MeterFlow ?

Non, le mode test a les siennes. Les événements de test disposent d’un dixième du quota mensuel de votre forfait MeterFlow — Drip 5 000 · Flow 20 000 · Stream 70 000 · Torrent 400 000 — et ne comptent jamais dans le quota live ; les packs d’événements n’augmentent que le quota live. Au-delà (plus la même marge de 10 % qu’en live), les écritures d’usage de test sont refusées avec un 403. Les clés de test font jusqu’à 60 requêtes par minute, les clés live 300. Les données de test expirent : les événements d’usage de test après 30 jours, et un abonnement de test sans usage depuis 90 jours, avec le solde et le registre de test de ce client. La page Billing et la fenêtre Usage de votre organisation affichent les événements de test du mois face à ce quota, à côté des événements live.

Nouveau meter concept clé

Un meter est la définition d’un compteur nommé : il déclare une chose de votre produit qui mérite d’être mesurée, et la façon de transformer les événements bruts en un nombre. Voyez-le comme la création d’une nouvelle colonne dans un rapport d’usage, avant même qu’il n’existe des données.

📍 Ouvrez un projet → Meters → le bouton dans l’en-tête du tableau

  • Name *

    L’étiquette lisible affichée dans le tableau de bord — « Images générées », « Secondes de rendu vidéo ». Pour les yeux humains uniquement.

  • Event name *

    La clé machine — et oui, elle est stockée dans la base de données et comparée à l’exactitude près. Quand votre application signale un usage, elle envoie un nom d’événement ; MeterFlow cherche dans ce projet le meter actif dont l’event_name correspond exactement, casse comprise. S’il n’en existe aucun, l’événement est rejeté avec une erreur 404 (« No active meter found for event … ») et rien n’est enregistré. Chaque nom d’événement est unique au sein d’un projet. Convention : minuscules avec des points, p. ex. image.generated.

  • Aggregation type

    Comment de nombreux événements individuels sont combinés en un seul nombre dans les récapitulatifs d’usage. Voir le tableau ci-dessous — c’est le cœur du meter.

  • Aggregation field

    Obligatoire pour Sum, Max, Min et Unique count ; refusé sur Count, qui ne lit aucune propriété. Il nomme une propriété de vos événements. Pour Sum, Max et Min, c’est là que la quantité est lue quand votre app omet value — un meter dont le champ est seconds lit properties.seconds ; un value envoyé par votre app l’emporte toujours, et un événement sans l’un ni l’autre compte pour 1. Pour Unique count, c’est la propriété dont on compte les valeurs distinctes — model, pour compter les modèles utilisés par un client.

  • Description

    Texte libre pour votre équipe.

Les types d’agrégation, par l’exemple

Supposons que le client user-842 déclenche 4 événements ce mois-ci avec les valeurs 3, 10, 2, 10. Un seul nombre est rapporté par meter — lequel dépend du type d’agrégation :

TypeÀ quelle question il répondRésultat pour 3, 10, 2, 10Usage typique
CountCombien de fois est-ce arrivé ? (valeurs ignorées)4Images générées, appels API, exports
SumCombien au total ?25Secondes de rendu, tokens consommés, Go transférés
MaxQuelle a été la plus grande valeur ?10Pic de tâches simultanées, plus gros envoi
MinQuelle a été la plus petite valeur ?2Rarement pour facturer — surtout du diagnostic
Unique countCombien de valeurs distinctes du champ d’agrégation sont apparues ?3  (3, 10, 2)Modèles distincts utilisés, documents distincts touchés
Exemple — un meter completName « Video render seconds » · Event name video.rendered · Agrégation Sum · Aggregation field seconds.
Votre app termine le rendu d’un clip de 42 secondes pour user-842 et signale l’événement video.rendered avec la valeur 42. Répétez quelques fois et la page d’usage du client affichera une ligne : Video render seconds — 3 événements — 117.
Le nom d’événement doit-il correspondre à ce qu’envoie mon app ? Que se passe-t-il en cas de faute de frappe ?

Oui — exactement, casse comprise. Le nom d’événement du meter est stocké dans la base de données et sert d’étiquette d’adressage pour les événements entrants. Si votre app envoie video.render alors que le meter dit video.rendered, l’API répond 404 « No active meter found for event 'video.render' in this project » et l’événement n’est pas stocké. C’est voulu : une faute de frappe silencieuse laisserait fuir à jamais de l’usage non facturé. Créez d’abord le meter, puis commencez à envoyer des événements portant le même nom.

Puis-je changer le type d’agrégation plus tard ?

Non — après la création, seuls le nom, la description et l’indicateur actif sont modifiables. L’agrégation définit ce que signifie l’historique stocké ; la changer rétroactivement réécrirait le passé. S’il vous faut un autre calcul, créez un nouveau meter avec un nouveau nom d’événement.

Quand « Aggregation field » est-il obligatoire ?

Cela dépend du type. Le formulaire ne l’affiche que pour Sum, Max, Min et Unique count, et le serveur refuse une création qui le laisse vide pour ces types. Sur un meter Count, le formulaire le masque et le serveur le refuse s’il est envoyé : un comptage ne lit aucune propriété, le champ nommerait donc quelque chose que rien ne lit.

Nouveau plan concept clé

Un plan est un palier tarifaire — « Free », « Pro à 29 $/mois »… Il associe un prix récurrent à un ensemble de limites de meter qui disent quelle quantité de chaque fonction mesurée est incluse et ce qui se passe au-delà. Les clients sont rattachés à un plan via un abonnement.

📍 Ouvrez un projet → Plans → le bouton dans l’en-tête du tableau

  • Name *

    Le nom du palier — « Free », « Pro », « Enterprise ». Obligatoire ; le bouton de création reste désactivé tant qu’il n’est pas rempli.

  • Description

    Texte libre, p. ex. la phrase d’accroche marketing du palier.

  • Price / Currency / Billing period

    L’abonnement récurrent : Price est le montant (0 convient très bien à un palier gratuit), Currency un code comme USD, et Billing period la fréquence — mensuel, annuel, hebdomadaire ou paiement unique. Figés après la création — modifier le plan ensuite ne peut pas les changer (créez plutôt un nouveau plan, pour que les conditions des abonnés existants ne changent pas en douce).

  • Trial days

    Jours gratuits au début de chaque nouvel abonnement. Avec 14, un nouvel abonné passe 2 semaines au statut « trialing » avant le début de la période payante. 0 = pas d’essai.

  • Published

    Si le plan existe pour vos clients. Laissé désactivé, c’est un brouillon : vous pouvez en définir le prix, les limites et les clés de fonctionnalité en plusieurs fois, et vos clés d’API ne le voient jamais — il est absent de la liste des plans du SDK, un identifiant divulgué répond 404, et personne ne peut y être abonné. Les nouveaux plans sont publiés ; désactivez-le pour en préparer un tranquillement, puis réactivez-le à la mise en vente. Le désactiver ensuite ferme la porte aux nouveaux abonnés sans toucher à ceux déjà en place.

  • Features

    Les avantages oui/non inclus dans le plan — des clés courtes que vous inventez, comme sso ou priority-support (minuscules, chiffres, - et _). Votre app demande au SDK entitlements.check(customerId, 'sso') et obtient oui uniquement pour les clients abonnés à un plan qui liste cette clé. Modifiables à tout moment, sur les plans nouveaux comme existants ; pour ce que vous comptez, utilisez plutôt une limite de meter ci-dessous.

Limites de meter — la section « + Add limit »

Chaque ligne de limite relie ce plan à un meter et répond à : quelle quantité de cette chose est incluse, et que se passe-t-il au-delà ?

  • Meter *

    À quelle grandeur mesurée cette limite s’applique. La liste déroulante affiche les meters que vous avez créés dans ce projet — ni plus, ni moins. Ce n’est pas un catalogue figé : toute nouvelle capacité du produit demande simplement un nouveau meter d’abord, et il apparaît ici aussitôt.

  • Included units

    Le volume compris dans le prix du plan, par période de facturation. « Pro inclut 500 images par mois » → 500. Sur une ligne Hard ou Soft, un chiffre est obligatoire avant de créer le plan — un volume vide ne plafonnerait rien — sauf si vous cochez Unlimited ci-dessous pour dire que c’était bien l’intention. Sur une ligne Metered, le vide est déjà une réponse : paiement à l’usage dès la première unité.

  • Unlimited

    Uniquement sur les lignes Hard et Soft, et la façon explicite de dire « aucun plafond sur ce meter ». Coché, Included units est désactivé et vidé ; décoché, ce chiffre reste obligatoire. Les lignes Metered n’ont pas l’interrupteur, car le vide y signifie déjà quelque chose.

  • Overage rate

    Le prix en crédits par unité une fois que le client dépasse les unités incluses — 0.5 signifie que chaque unité supplémentaire coûte un demi-crédit sur son solde. Il appartient au seul type Metered : le formulaire le demande sur une ligne Metered et le masque sur Hard et Soft, et l’API refuse un tarif sur une ligne Hard ou Soft (422). Une ligne Metered sans unités incluses ni tarif refuserait chaque unité, donc l’API refuse aussi cette ligne (422).

  • Limit type

    Ce que répond entitlements.check() du SDK une fois les unités incluses épuisées — l’appel que votre app fait avant d’effectuer le travail. Hard (bloquer) — check() répond non (hard_limit_reached) et votre app refuse l’action ; le client se heurte à un mur jusqu’à la période suivante ou une montée en gamme. Soft (avertir) — check() répond toujours oui, signalé soft_limit_exceeded : votre app laisse passer et incite le client à monter en gamme. Metered (facturer) — check() répond oui tant que les crédits du client couvrent les unités supplémentaires, et chaque unité supplémentaire est prélevée sur son solde au tarif de dépassement ; quand le solde ne suffit plus, la réponse est non (insufficient_credits). Metered est l’option « paiement à l’usage » et la seule qui déplace de l’argent (des crédits) toute seule. Une limite Metered est refusée sur un meter Max ou Min (422) : une valeur maximale ou minimale ne se facture pas à l’unité. Sur une ligne Metered, un plafond de dépenses sur l’abonnement du client peut faire répondre non à check() avant que le solde ne s’épuise (spend_cap_reached). Hard et Soft déclenchent le webhook limit.reached une fois par période de facturation, la première fois que la ligne est franchie. Dans tous les cas MeterFlow continue d’enregistrer les événements que votre app envoie — la barrière, c’est check(), dans votre code.

Exemple — un plan Pro réalistePro · 29 $ USD · Mensuel · 14 jours d’essai · Published ✓
Limite 1 : meter Images générées, incluses 500, type Hard → après 500 images, check() répond non et votre app cesse de générer jusqu’au mois suivant ou à une montée en gamme.
Limite 2 : meter Secondes de rendu vidéo, incluses 1 000, dépassement 0,02, type Metered → au-delà de 1 000 secondes, chaque seconde supplémentaire coûte en silence 0,02 crédit du portefeuille du client.
Pourquoi « + Add limit » est-il grisé ?

Parce que le projet n’a pas encore de meter — une limite est toujours un plafond sur un meter ; sans meter, il n’y a rien à quoi la rattacher. La boîte de dialogue affiche l’indice « Create meters first to attach limits to this plan. » Allez dans Meters → New meter, créez-en au moins un, puis rouvrez cette boîte de dialogue.

Pourquoi la liste Meter ne montre-t-elle que quelques options ? Et si mon produit a quelque chose de nouveau ?

La liste déroulante, ce sont simplement vos propres meters du projet sélectionné. Dans les données de démonstration, il se trouve que ce sont « Images generated », « Video render seconds », « Upscales processed », « Peak GPU memory » et « Active prompters » — mais cette liste vous appartient et peut grandir. Elle ne restreint pas ce que les clients peuvent faire : les clients ne choisissent jamais de meters ; c’est vous qui définissez des meters pour tout ce que fait votre produit. Une nouvelle fonctionnalité demain ? Créez un meter pour elle et il apparaîtra ici.

Un client a dépassé une limite Hard — pourquoi ses événements sont-ils encore enregistrés ?

Parce que MeterFlow ne décide jamais à la place de votre produit ce qu’un utilisateur peut faire — c’est votre app qui décide, en appelant entitlements.check() avant l’action. Une limite Hard fait répondre non à cet appel ; si votre app saute l’appel et fait le travail quand même, l’événement d’usage est tout de même accepté et stocké, pour que votre historique et toute facturation metered restent honnêtes. Voyez la limite comme la règle et check() comme le videur à la porte : MeterFlow écrit la règle, votre code tient la porte.

Que répond check() quand MeterFlow ne répond pas ?

Depuis meterflow 0.10.0 (npm) / 0.5.0 (PyPI), le SDK continue de répondre. Il réutilise chaque réponse pendant les 15 secondes que l’API autorise, et un enregistrement d’usage, un crédit ou un débit pour un client rend obsolètes les réponses de ce client. Si MeterFlow est injoignable — une erreur réseau, un délai dépassé, ou un 5xx ou 429 après les nouvelles tentatives —, check() donne la dernière réponse, marquée stale: true ; à défaut, la valeur par défaut que vous fixez par fonctionnalité dans entitlementDefaults ('allow' ou 'deny', '*' pour le reste), avec reason: 'offline_default' ; sans l’une ni l’autre, il lève une erreur. Votre hook onError est prévenu en premier. Un 401, 403, 404 ou 422 est une vraie réponse et n’est jamais masqué.

Pourquoi ne puis-je pas modifier le prix ou les limites d’un plan existant ?

C’est voulu : les abonnés existants ont souscrit à ces conditions, donc le prix, la devise, la période de facturation et les limites de meter sont gelés à la création. La modification d’un plan ne peut changer que son nom, sa description, ses jours d’essai, son état de publication, son indicateur actif et ses clés de fonctionnalités. Pour changer les tarifs, créez un nouveau plan (p. ex. « Pro 2026 ») et orientez-y les nouveaux clients.

Nouvel abonnement relie client ⇄ plan

Un abonnement rattache un de vos clients à un plan. À partir de ce moment, son usage est jugé à l’aune des limites de meter de ce plan. En production, c’est généralement votre backend qui le crée via le SDK à l’instant où quelqu’un choisit un palier au paiement — la boîte de dialogue fait la même chose à la main.

📍 Ouvrez un projet → Subscriptions → le bouton dans l’en-tête du tableau

  • Customer ID *

    Votre propre identifiant du client final — n’importe quelle chaîne de votre choix : un ID utilisateur de votre base (user-842), un e-mail, un slug de tenant. MeterFlow ne le valide contre rien ; ce que vous envoyez désigne le propriétaire de l’abonnement. Utilisez le même ID partout (abonnements, crédits, usage), sinon les pièces ne se relieront pas.

  • Plan *

    Sur quel palier tarifaire il se trouve — la liste affiche les plans de ce projet. Si le plan a des jours d’essai, l’abonnement démarre en « trialing » ; sinon en « active ».

ExempleLe client user-842 clique sur « Passer à Pro » dans votre app → votre backend appelle subscriptions.create({ customer_external_id: 'user-842', plan_id: … }). Chaque événement d’usage de user-842 est désormais confronté aux limites de Pro.
Et si un client n’a pas d’abonnement — ses événements sont-ils perdus ?

Non. Les événements sont toujours enregistrés et apparaissent toujours dans les récapitulatifs d’usage. Sans abonnement actif ou en essai, rien n’est facturé, et entitlements.check() répond non avec no_subscription — une app qui demande d’abord ne laissera donc pas passer l’action. La logique de facturation s’enclenche dès qu’un abonnement existe.

Puis-je plafonner ce qu’un client dépense sur une période ?

Oui — définissez spend_cap, en crédits, sur l’abonnement via le SDK ou l’API ; vide signifie aucun plafond. Une fois les dépenses de la période arrivées au plafond, l’usage enregistré cesse de consommer des crédits, un credits.deduct() qui le dépasse est refusé avec un 409, entitlements.check() répond non avec spend_cap_reached avant qu’une action facturée ne le franchisse, et le webhook cap.reached se déclenche une fois sur la période.

Un client a résilié — peut-il revenir ?

Oui, sur le même abonnement. Remettez son statut à active — subscriptions.update(id, { status: 'active' }), ou Reactivate sur sa ligne. Si l’ancienne période est terminée, une nouvelle commence tout de suite, avec les crédits de période de la formule ; un essai résilié avant sa fin reprend en essai. Une formule désactivée ou dépubliée entre-temps ne reprend personne (409), et un abonnement géré par le connecteur de votre fournisseur de paiement revient par le fournisseur, pas ici.

Puis-je retrouver l’abonnement d’un client dans une longue liste ?

Oui. La page Subscriptions a un filtre par client et des puces de statut, et le SDK accepte les deux mêmes : subscriptions.list({ q, status }). q trouve tout ID client qui le contient ; status vaut active, trialing, past_due, paused, canceled ou expired. Le serveur filtre avant de découper la page, donc chaque page ne contient que des correspondances. Dans le SDK depuis meterflow 0.9.0 (npm) / 0.4.0 (PyPI). Depuis 0.12.0 / 0.7.0, il accepte aussi sort — created_at (par défaut), customer_external_id ou status — et order, desc ou asc ; passez les deux avec chaque next_cursor.

La page client un client, en entier

Chaque client pour qui votre app a écrit quelque chose — un abonnement, un solde de crédits ou un événement d’usage — est une ligne de la page Customers. Ouvrez-le et sa page raconte toute l’histoire : qui il est, sa formule, et quatre onglets.

📍 Ouvrez un projet → Customers → la ligne du client

  • Credits

    Son solde et chaque ligne de registre derrière, avec Grant et Deduct — les fenêtres expliquées plus bas.

  • Usage

    Ce qu’il a utilisé, meter par meter.

  • Subscription

    Sa formule et son statut, avec Cancel ou Reactivate.

  • Entitlements

    Ce que sa formule accorde, fonctionnalité par fonctionnalité : ce qui reste de chaque allocation facturée, et la raison pour laquelle une fonctionnalité est refusée, exactement comme entitlements.check() la donnerait.

Créditer / Débiter des crédits le portefeuille

Les crédits sont un solde prépayé par client (par projet) — pensez à un portefeuille ou à une carte rechargeable. C’est vous qui décidez de la valeur d’un crédit dans votre tarification. Le dépassement « metered » puise dans ce portefeuille automatiquement ; les deux boîtes de dialogue déplacent des crédits à la main.

📍 Ouvrez un projet → Customers → la ligne du client → onglet Credits → « Grant » / « Deduct »

  • Amount *

    Combien de crédits ajouter (Grant) ou retirer (Deduct). Doit être supérieur à zéro — la direction est décidée par le bouton qui a ouvert la boîte de dialogue, pas par un signe moins.

  • Description

    Une note facultative enregistrée sur la ligne du registre — « Bonus de bienvenue », « Remboursement suite à l’incident », « Geste commercial ». Votre futur vous dira merci.

ExempleLe nouvel inscrit user-842 reçoit un crédit de 100 (« Bonus de bienvenue »). Il rend 2 500 secondes de vidéo sur un plan avec 1 000 incluses et un dépassement metered de 0,02 → 1 500 × 0,02 = 30 crédits débités automatiquement. Solde : 70.
Bon à savoir — le registre ne ment jamaisLes soldes ne sont jamais modifiés directement. Chaque crédit, débit et prélèvement automatique d’usage est une nouvelle ligne permanente dans un registre en ajout seul, qui note le solde avant et après — une piste d’audit complète, comme un relevé bancaire. Une erreur ? On ne supprime pas la ligne ; on en ajoute une de compensation. Et un débit supérieur aux crédits disponibles (le solde moins ceux retenus) est refusé net (l’API renvoie une erreur « 402 solde insuffisant ») — un portefeuille ne peut pas passer en négatif.
L’usage de ce client consommera-t-il son solde ?

Demandez au solde : credits.balance() répond avec usage_draws_credits. true — sa formule facture l’usage au-delà de l’allocation, l’usage enregistré consomme donc des crédits tout seul. false — seul un credits.deduct() explicite le fait bouger. null — il n’a pas d’abonnement actif ou en essai.

Mon app peut-elle recharger un client automatiquement ?

MeterFlow dit à votre app quand et combien ; votre app débite le client, puis accorde les crédits. Donnez à un endpoint de webhook un seuil de solde bas et il reçoit balance.low quand le solde d’un client passe en dessous — par une déduction ou par un usage facturé — et balance.topped_up quand un crédit accordé le fait repasser au-dessus. Définissez topup_amount sur l’abonnement du client et balance.low le transmet comme suggested_topup. Définissez max_topups_per_window et un crédit au-delà de ce nombre sur une même période est refusé avec un 409, pour qu’une boucle dans votre code ne puisse pas recharger sans fin.

Puis-je mettre des crédits de côté pour une longue tâche ?

Oui, à partir de meterflow 0.11.0 (npm) / 0.6.0 (PyPI). credits.reserve() bloque une partie du solde d’un client pendant ttl_seconds — 5 minutes sauf indication contraire, un jour au plus. Le solde ne bouge pas, mais rien d’autre ne peut dépenser ce qui est bloqué : un credits.deduct(), l’usage facturé, un check() qui débiterait et un autre blocage ne voient que les crédits disponibles, c’est-à-dire le solde moins ce qui est bloqué. Une fois la tâche finie, credits.confirmReservation(id, { amount }) prend tout ou partie du blocage en un débit normal dans le registre et libère le reste, et credits.releaseReservation(id) le libère entièrement ; un blocage oublié se libère tout seul à son expiration. credits.balance() affiche reserved et available à côté du solde, et les crédits bloqués comptent aussi dans le plafond de dépenses.

Montrez leur solde à vos clients

La page de solde hébergée pour un client : le solde avec le bouton Buy more, le forfait avec ce qui reste de chaque quota et les dernières lignes du registre

MeterFlow héberge une page qui montre à l’un de vos clients ses propres crédits : le solde, les dernières lignes du registre qui le composent, sa formule avec ce qui reste de chaque allocation facturée, et ce qu’il a utilisé hors formule. Vous n’avez ni à la construire ni à l’héberger — votre serveur remet un lien au client.

Comment un client y arrive 1. Votre app affiche un bouton — « Vos crédits » — qui appelle votre serveur. 2. Votre serveur demande un lien à MeterFlow et envoie le client sur link.url. Le lien porte son propre jeton de courte durée : votre clé API ne quitte jamais votre serveur. En Python, c’est client.portal.create_session(…), avec les mêmes champs. const link = await client.portal.createSession({
  customer_external_id: 'user-842',
  topup_url: 'https://acme.dev/billing',
  return_url: 'https://acme.dev/app',
  expires_in_minutes: 60,
});
3. Buy more ouvre topup_url — votre propre page de paiement, exactement telle que vous l’avez saisie, sans rien y ajouter. C’est facultatif : sans topup_url, ni sur le lien ni dans les valeurs par défaut du projet, la page n’a pas de bouton Buy more. ← Back mène à return_url, facultatif de la même façon. 4. MeterFlow n’encaisse jamais le paiement : quand votre checkout en signale un, votre serveur appelle credits.grant() et la page affiche le nouveau solde.
  • Le lien

    Il dure 60 minutes, sauf si vous fixez expires_in_minutes — 24 heures au plus — et ne peut pas être retiré avant. Il ouvre la page d’un seul client, en lecture seule : il ne peut rien modifier ni montrer un autre client. Un lien créé avec une clé de test (mf_test_…) affiche des données de test, sous un badge Test data.

  • Votre apparence

    Ouvrez un projet → Portal : nom de l’entreprise, logo, thème clair / sombre / automatique, couleurs et rayon des coins, ainsi que les valeurs par défaut — URL de Buy more, URL de Back et durée — pour les liens qui ne les précisent pas. Une case à cocher applique l’apparence à tous les projets de l’organisation.

  • Un lien à la main

    Dans le tableau Customers, l’action de ligne Create a portal link crée un lien pour ce client sans code — tout comme Portal link dans son onglet Credits.

Enregistrer un événement d’usage concept clé

Un événement d’usage = « ce client vient de faire cette chose, dans cette quantité. » En production, votre application les envoie automatiquement via le SDK, des milliers de fois par jour ; la boîte de dialogue existe pour en injecter un à la main, pour les tests et les démos.

📍 Ouvrez un projet → Usage → recherchez un client → « Record event »

  • Event name *

    Doit correspondre exactement au nom d’événement d’un meter existant et actif dans ce projet (sensible à la casse). C’est cette correspondance qui indique à MeterFlow quel compteur cet événement alimente. Aucun meter correspondant → l’API rejette l’événement avec un 404 et rien n’est stocké. Vérifiez l’orthographe exacte sur la page Meters.

  • Customer ID *

    Lequel de vos clients l’a fait — la même chaîne d’ID libre que pour les abonnements et les crédits. La cohérence est primordiale : user-842 et USER-842 sont deux clients différents.

  • Value

    La quantité — facultative. Omise, un meter Sum, Max ou Min la lit dans la propriété de l’événement que nomme son champ d’agrégation (votre app l’envoie dans properties) ; sinon l’événement compte pour 1. Son sens dépend de l’agrégation du meter : pour un meter Count la valeur est ignorée (chaque événement compte comme une occurrence) ; pour Sum c’est la quantité à ajouter (42 secondes, 1 300 tokens) ; pour Max/Min c’est la mesure comparée ; un meter Unique count compte les valeurs distinctes de son champ d’agrégation.

Ce qui se passe après avoir appuyé sur « Record » — le parcours complet1. Le nom d’événement est associé à un meter — disons video.rendered → « Video render seconds ». 2. L’événement est stocké définitivement (brut — l’agrégation a lieu plus tard, à la lecture). 3. En arrière-plan, MeterFlow vérifie si le client a un abonnement actif et si ce plan a une limite sur ce meter. 4. Si la limite est Metered, les unités au-delà de l’allocation incluse sont prélevées au tarif de dépassement sur le solde de crédits du client et une ligne de registre est écrite — jusqu’au plafond de dépenses de la période, si l’abonnement en a un ; si elle est Hard ou Soft et que cet événement est le premier à franchir les unités incluses sur la période, le webhook limit.reached se déclenche une fois. Ici l’événement n’est jamais refusé — refuser, c’est le rôle de check(), dans votre app. 5. Le récapitulatif d’usage affiché sur cette page est recalculé à partir des événements bruts selon le type d’agrégation du meter.
J’ai enregistré un événement et j’ai eu une erreur — pourquoi ?

Presque toujours le nom d’événement : il ne correspond exactement à aucun meter actif de ce projet. L’erreur le dit mot pour mot — « No active meter found for event '…' in this project. » Copiez le nom d’événement depuis la page Meters plutôt que de le retaper. Notez aussi que les meters sont propres à chaque projet : un meter d’un autre projet ne compte pas.

Si mon app rejoue une requête, l’événement sera-t-il compté deux fois ?

Pas si vous utilisez le SDK correctement : chaque écriture accepte une clé d’idempotence — une étiquette unique pour « cette action précise ». Si la même clé arrive deux fois (une nouvelle tentative après un raté réseau), MeterFlow la reconnaît et renvoie le résultat d’origine au lieu de stocker un doublon. La boîte de dialogue manuelle n’en envoie pas : appuyer deux fois sur Record à la main crée donc bel et bien deux événements.

Faut-il un événement par appel d’API ?

Non — et en général mieux vaut éviter. Value est une quantité, et un meter Sum additionne ces quantités : un seul événement avec la valeur 1 300 compte pour un événement sur le quota mensuel de votre forfait et 1 300 unités sur le meter. Un événement par appel d’API, c’est ce qui épuise un forfait : 1 000 utilisateurs faisant 100 appels par jour, cela fait environ 3 millions d’événements par mois.

Agrégez dans votre propre application sur une fenêtre que vous pourriez vous permettre de perdre en cas de plantage — une requête, un traitement, une minute — puis enregistrez un unique événement avec le total. Les envoyer en batch n’est pas la même chose : un batch de 100 économise des requêtes HTTP, mais chaque événement reste un enregistrement à part et continue de compter.

Cela vaut pour les meters Sum. Un meter Count ignore la valeur et compte les occurrences : là, chaque occurrence a bien besoin de son propre événement. Dans les deux cas, la facture ne change pour personne : une limite Metered facture à l’unité.

Puis-je enregistrer un usage survenu il y a un moment ?

Seulement dans les cinq minutes. Le timestamp d’un événement peut être au plus 5 minutes dans le passé et 60 secondes dans le futur ; hors de cette fenêtre, l’API le refuse avec une 422 et n’enregistre rien. Sans timestamp, l’événement porte l’heure de son arrivée. Enregistrez l’usage au moment où il se produit : un usage plus ancien ne peut pas être chargé après coup.

Nouveau webhook notifications

Un webhook est une URL sur votre serveur que MeterFlow appelle quand quelque chose se passe dans votre projet — des crédits accordés, une limite atteinte, un solde qui baisse. Chaque appel est signé, et relancé si votre serveur ne répond pas.

📍 Ouvrez un projet → Webhooks → le bouton dans l’en-tête du tableau

  • Endpoint URL *

    Où MeterFlow envoie les événements, p. ex. https://api.acme.dev/meterflow.

  • Events to deliver

    Les événements dont cet endpoint est informé : usage.recorded, credit.granted, credit.deducted (une déduction, ou un usage Metered facturé — son transaction_type dit lequel), subscription.created, .updated, .renewed et .canceled, limit.reached, cap.reached, balance.exhausted, et les deux ci-dessous.

  • Low balance threshold

    Un solde, en crédits. Définissez-le et l’endpoint reçoit aussi balance.low quand le solde d’un client passe en dessous et balance.topped_up quand il repasse au-dessus ; effacez-le et les deux s’arrêtent. Les deux événements vont et viennent avec le seuil, car sans ligne on ne peut pas prévenir un endpoint d’un franchissement.

Depuis votre codeVotre app peut lire ses endpoints et leurs accusés de livraison via le SDK, pour savoir si un événement est arrivé : webhooks.list(), webhooks.deliveries(id) pour les 100 plus récents, et webhooks.deliveryPage(id) (en Python delivery_page) pour chaque tentative, une page à la fois, des plus récentes aux plus anciennes. Le journal de livraisons du tableau de bord se pagine de la même façon. Créer et modifier les endpoints se fait ici, dans le tableau de bord.

Connecter votre fournisseur de paiement votre facturation

Si vos clients vous paient via Paddle, Polar, Lemon Squeezy, Chargebee ou Razorpay, un connecteur laisse ce compte piloter MeterFlow : votre fournisseur appelle MeterFlow à chaque changement d’abonnement et chaque paiement, et l’abonnement ou le crédit correspondant apparaît ici — sans code dans votre app.

📍 Ouvrez un projet → Connectors → le bouton dans l’en-tête du tableau

  • Provider *

    Celui des cinq par lequel vos clients paient.

  • Which of your accounts

    Live — le compte de production de votre fournisseur, qui écrit des données live ; Test — son bac à sable, qui écrit des données de test. Un connecteur par fournisseur et par compte.

  • Signing secret *

    Le secret avec lequel votre fournisseur signe ses webhooks — pour Chargebee, qui ne signe rien, l’identifiant et le mot de passe qu’il envoie à la place. Il est vérifié à chaque appel et jamais réaffiché : le tableau n’en montre que les quatre derniers caractères.

Une fois créé

  • L’URL du webhook

    Affichée dès que le connecteur est créé : collez-la dans les réglages webhook de votre fournisseur.

  • Correspondances prix → formule

    Quel prix de votre fournisseur — un produit sur Polar, une variante sur Lemon Squeezy, une formule sur Chargebee et Razorpay — place un client sur laquelle de vos formules. Un événement pour un prix sans correspondance est enregistré et ne change rien.

  • Journal de livraison

    Chaque événement reçu par le connecteur, avec ce qu’il en a fait en une phrase : ce qui a été appliqué, et pourquoi le reste a été ignoré.

Membres et invitations accès de l’équipe

La page Members de votre organisation liste qui en fait partie — avec son rôle et qui l’a invité — et les invitations encore en attente. Un owner ou un admin invite par email ; la personne n’a pas encore besoin d’un compte MeterFlow.

📍 Members dans la barre latérale, à côté de Billing → « Invite member » (aussi une action de ligne sur les organisations du Dashboard)

  • Email *

    Où part l’invitation. MeterFlow envoie un lien qui fonctionne une fois, pendant 7 jours, pour cette adresse seulement : la personne l’ouvre et rejoint — depuis son compte, ou en en créant un via le lien.

  • Role

    Admin — réglages de l’organisation, invitations, clés API, webhooks, connecteurs, projets et facturation. Member — celui qui travaille au quotidien : meters, formules et les pages Subscriptions, Usage et client. Viewer — lecture seule. Il n’y a volontairement pas d’option « owner » : la propriété ne se donne pas par invitation.

  • Invitations en attente

    Listées sur la page Members jusqu’à ce qu’elles soient acceptées, révoquées ou expirées. Revoke coupe le lien aussitôt.

  • Change role · Remove

    Sur la ligne de chaque membre, pour les owners et admins. L’appartenance de l’owner et la vôtre ne se changent pas là. Retirer quelqu’un lui ôte l’accès ; son compte, et ce qu’il a créé, restent.

ExempleVous invitez dana@acme.dev comme Viewer pour que l’équipe finance puisse suivre l’usage et les soldes sans pouvoir changer les tarifs.
↑