MeterFlow

Jeder „Neu …“-Dialog, in einfacher Sprache erklärt

Das MeterFlow-Dashboard hat eine Handvoll Dialoge, die echte Datensätze in der Datenbank anlegen — Meter, Pläne, Abonnements, Credits, Nutzungsereignisse, API-Schlüssel. Diese Seite erklärt, was jeder davon tut, Feld für Feld, mit einfachen Beispielen. Vorwissen über Metering oder nutzungsbasierte Abrechnung ist nicht nötig.

Hier starten: das große Ganze

MeterFlow beantwortet für dein Produkt genau eine Frage: „Wer hat wie viel wovon genutzt — und was kostet ihn das?“ Alles im Dashboard existiert, um diese Frage zu beantworten.

Du Kunden-AdminDer Entwickler oder das Unternehmen, das MeterFlow nutzt. Du meldest dich in diesem Dashboard an, legst fest, was gemessen wird, und bestimmst die Preisregeln.
Deine Anwendung das SDKDein eigenes Backend mit installiertem MeterFlow-SDK. Es meldet Nutzungsereignisse automatisch, während deine Kunden dein Produkt verwenden. Die Dashboard-Dialoge für Nutzung/Credits/Abonnements machen von Hand genau das, was das SDK im Code tut.
Dein Kunde Kunden-IDDer Endnutzer deines Produkts. Er meldet sich nie bei MeterFlow an und hat kein MeterFlow-Konto — er existiert hier nur als eine von dir gewählte ID-Zeichenkette (z. B. user-842 oder eine E-Mail).

Wie die Teile zusammenspielen

Warum sind manche „Erstellen“-Buttons ausgegraut?

Jeder Dialog deaktiviert seinen Bestätigen-Button, bis alle Pflichtfelder (mit * markiert) ausgefüllt sind — z. B. bleibt „Create plan“ deaktiviert, bis der Plan einen Namen hat. Wenn ein Button festzuhängen scheint, suche weiter oben nach einem leeren Pflichtfeld.

Neue Organisation Container

Der äußerste Container — normalerweise dein Unternehmen. Alles andere (Projekte, Meter, Pläne…) lebt innerhalb einer Organisation. Eine hast du bei der Registrierung automatisch bekommen.

📍 Dashboard → der Button „New organization“ (wird auch beim ersten Login angeboten, wenn du noch keine hast)

  • Name *

    Der Name deines Unternehmens oder Teams. Reines Etikett — du kannst ihn später ändern.

  • Billing email

    Wohin Rechnungen und Abrechnungshinweise für dein MeterFlow-Konto gehen würden. Optional; das Format wird geprüft, aber es wird nichts zur Bestätigung verschickt.

BeispielAcme Robotics erstellt die Organisation „Acme Robotics“ mit der Rechnungs-E-Mail finance@acme.dev. Ihre zwei Produkte werden darin zu zwei Projekten.

Neues Projekt Container

Ein Projekt = ein Produkt oder eine Umgebung, die du messen willst. Jeder Meter, Plan, API-Schlüssel, Kundensaldo und jedes Nutzungsereignis gehört zu genau einem Projekt — Projekte sehen niemals die Daten der anderen.

📍 Dashboard → der Button „New project“ im Kopf der Projects-Tabelle

  • Organization *

    Zu welcher Organisation das Projekt gehört. Vorausgewählt, wenn bereits eine aktiv ist.

  • Name *

    Der Produktname, z. B. „PixelForge AI“. Erscheint überall im Dashboard und im Projektumschalter.

  • Description

    Freitext für deine eigene Referenz.

BeispielAcme hat ein Bild-Tool und einen Chatbot. Sie erstellen zwei Projekte — „PixelForge AI“ und „ChatDesk“ — damit jedes Produkt seine eigenen Meter, Pläne und Kundensalden bekommt. Dieselbe Kunden-ID in zwei Projekten gilt als zwei völlig getrennte Kunden.

API-Schlüssel erzeugen Zugang

Der Berechtigungsnachweis, mit dem deine Anwendung mit MeterFlow spricht. Dein Backend übergibt ihn dem SDK; jedes Nutzungsereignis, jede Credit-Operation und jeder Abonnement-Aufruf wird durch diesen Schlüssel authentifiziert — und auf genau ein Projekt begrenzt.

📍 Projekt öffnen → API Keys → der Button im Tabellenkopf

  • Key name *

    Ein Etikett, damit du weißt, wo der Schlüssel verwendet wird — „Produktions-Backend“, „Staging“, „CI-Tests“. Ohne technische Wirkung.

  • Environment

    Live-Schlüssel beginnen mit mf_live_, Test-Schlüssel mit mf_test_ — und sie greifen auf zwei vollständig getrennte Datensätze im selben Projekt zu. Abonnements, Guthaben und Verbrauch, die mit einem Test-Schlüssel erzeugt wurden, sind für Live-Schlüssel unsichtbar (und umgekehrt), während Meter und Pläne geteilt werden — Tests laufen also immer gegen deine echte Abrechnungskonfiguration. Nutze Test-Schlüssel für Entwicklung, Staging und CI; Live-Schlüssel nur für echten Produktionsverkehr.

Wichtig — wird nur einmal angezeigtDer vollständige Schlüssel wird nur ein einziges Mal angezeigt, direkt nach der Erstellung. MeterFlow speichert nur einen kryptografischen Fingerabdruck (einen SHA-256-Hash) — der echte Schlüssel kann nie wieder angezeigt werden, auch nicht von uns. Kopiere ihn sofort in deinen Geheimnisspeicher. Verlierst du ihn, widerrufe ihn und erzeuge einen neuen.
BeispielDu erstellst „Production backend“ / Live, bekommst einmalig mf_live_a1b2… und legst ihn in die Umgebungsvariablen deines Servers: new MeterFlow({ apiKey: process.env.METERFLOW_KEY }). Die Dashboard-Liste zeigt für immer nur das Präfix und die letzten 4 Zeichen.
Teilen Test-Keys die Limits meines MeterFlow-Plans?

Nein, der Testmodus hat eigene. Test-Ereignisse bekommen ein Zehntel des monatlichen Kontingents deines MeterFlow-Plans — Drip 5 000 · Flow 20 000 · Stream 70 000 · Torrent 400 000 — und zählen nie zum Live-Kontingent; Event-Pakete erhöhen nur das Live-Kontingent. Darüber hinaus (plus dieselben 10 % Kulanz wie live) werden Test-Nutzungsmeldungen mit einem 403 abgelehnt. Test-Keys stellen bis zu 60 Anfragen pro Minute, Live-Keys 300. Testdaten laufen ab: Test-Nutzungsereignisse nach 30 Tagen, und ein Test-Abonnement ohne Nutzung seit 90 Tagen, zusammen mit Test-Guthaben und Test-Journal dieses Kunden. Die Billing-Seite und der Usage-Dialog deiner Organisation zeigen die Test-Ereignisse des Monats gegen dieses Kontingent, neben den Live-Ereignissen.

Neuer Meter Kernkonzept

Ein Meter ist die Definition eines benannten Zählers: Er erklärt eine Sache in deinem Produkt für messenswert und legt fest, wie rohe Ereignisse in eine Zahl verwandelt werden. Stell ihn dir wie eine neue Spalte in einem Nutzungsbericht vor, bevor es überhaupt Daten gibt.

📍 Projekt öffnen → Meters → der Button im Tabellenkopf

  • Name *

    Das menschenfreundliche Etikett im Dashboard — „Erzeugte Bilder“, „Video-Render-Sekunden“. Nur für menschliche Augen.

  • Event name *

    Der Maschinenschlüssel — und ja, er wird in der Datenbank gespeichert und exakt abgeglichen. Wenn deine Anwendung Nutzung meldet, sendet sie einen Ereignisnamen; MeterFlow sucht in dem Projekt den aktiven Meter, dessen event_name exakt übereinstimmt, Groß-/Kleinschreibung inklusive. Existiert keiner, wird das Ereignis mit einem 404-Fehler abgelehnt („No active meter found for event …“) und nichts wird erfasst. Jeder Ereignisname ist innerhalb eines Projekts eindeutig. Konvention: klein mit Punkten, z. B. image.generated.

  • Aggregation type

    Wie viele einzelne Ereignisse in den Nutzungsübersichten zu einer Zahl zusammengefasst werden. Siehe Tabelle unten — das ist das Herz des Meters.

  • Aggregation field

    Pflicht bei Sum, Max, Min und Unique count; bei Count abgelehnt, denn Count liest keine Eigenschaft. Es benennt eine Eigenschaft deiner Ereignisse. Bei Sum, Max und Min kommt die Menge von dort, wenn deine App value weglässt — ein Meter mit dem Feld seconds liest properties.seconds; ein von deiner App gesendetes value hat immer Vorrang, und ein Ereignis ohne beides zählt als 1. Bei Unique count ist es die Eigenschaft, deren verschiedene Werte gezählt werden — model, um die Modelle zu zählen, die ein Kunde genutzt hat.

  • Description

    Freitext für dein Team.

Die Aggregationstypen, an einem Beispiel

Angenommen, der Kunde user-842 löst diesen Monat 4 Ereignisse mit den Werten 3, 10, 2, 10 aus. Pro Meter wird eine Zahl gemeldet — welche, hängt vom Aggregationstyp ab:

TypWelche Frage er beantwortetErgebnis für 3, 10, 2, 10Typische Verwendung
CountWie oft ist es passiert? (Werte ignoriert)4Erzeugte Bilder, API-Aufrufe, Exporte
SumWie viel insgesamt?25Gerenderte Sekunden, verbrauchte Tokens, übertragene GB
MaxWas war der größte Einzelwert?10Spitze gleichzeitiger Jobs, größter Upload
MinWas war der kleinste Einzelwert?2Selten zur Abrechnung — eher Diagnose
Unique countWie viele verschiedene Werte des Aggregationsfelds kamen vor?3  (3, 10, 2)Verschiedene genutzte Modelle, verschiedene bearbeitete Dokumente
Beispiel — ein vollständiger MeterName „Video render seconds“ · Event name video.rendered · Aggregation Sum · Aggregation field seconds.
Deine App rendert einen 42-Sekunden-Clip für user-842 fertig und meldet das Ereignis video.rendered mit dem Wert 42. Ein paar Mal wiederholt, zeigt die Nutzungsseite des Kunden eine Zeile: Video render seconds — 3 Ereignisse — 117.
Muss der Ereignisname zu dem passen, was meine App sendet? Was passiert bei einem Tippfehler?

Ja — exakt, inklusive Groß-/Kleinschreibung. Der Ereignisname des Meters wird in der Datenbank gespeichert und wirkt wie das Adressetikett für eingehende Ereignisse. Sendet deine App video.render, der Meter heißt aber video.rendered, antwortet die API mit 404 „No active meter found for event 'video.render' in this project“ und das Ereignis wird nicht gespeichert. Das ist Absicht: Ein stiller Tippfehler würde für immer unabgerechnete Nutzung durchsickern lassen. Erst den Meter anlegen, dann Ereignisse mit demselben Namen senden.

Kann ich den Aggregationstyp später ändern?

Nein — nach der Erstellung sind nur Name, Beschreibung und Aktiv-Flag änderbar. Die Aggregation definiert, was die gespeicherte Historie bedeutet; sie rückwirkend zu ändern, würde die Vergangenheit umschreiben. Brauchst du eine andere Rechnung, lege einen neuen Meter mit neuem Ereignisnamen an.

Wann ist „Aggregation field“ Pflicht?

Das hängt vom Typ ab. Das Formular zeigt es nur bei Sum, Max, Min und Unique count, und der Server lehnt eine Erstellung ab, die es bei diesen Typen leer lässt. Bei einem Count-Meter blendet das Formular es aus, und der Server lehnt es ab, wenn es mitgeschickt wird: Ein Zählen liest keine Eigenschaft, das Feld würde also etwas benennen, das niemand liest.

Neuer Plan Kernkonzept

Ein Plan ist eine Preisstufe — „Free“, „Pro für 29 $/Monat“… Er bündelt einen wiederkehrenden Preis mit einer Reihe von Meter-Limits, die festlegen, wie viel jeder gemessenen Funktion inklusive ist und was darüber hinaus passiert. Kunden werden über ein Abonnement an einen Plan gebunden.

📍 Projekt öffnen → Plans → der Button im Tabellenkopf

  • Name *

    Der Name der Stufe — „Free“, „Pro“, „Enterprise“. Pflicht; der Erstellen-Button bleibt deaktiviert, bis er ausgefüllt ist.

  • Description

    Freitext, z. B. der Marketing-Einzeiler der Stufe.

  • Price / Currency / Billing period

    Die wiederkehrende Abogebühr: Price ist der Betrag (0 ist für eine Gratis-Stufe völlig in Ordnung), Currency ein Code wie USD, und Billing period der Rhythmus — monatlich, jährlich, wöchentlich oder einmalig. Nach der Erstellung fest — späteres Bearbeiten des Plans kann sie nicht ändern (lege stattdessen einen neuen Plan an, damit sich die Konditionen bestehender Abonnenten nicht stillschweigend ändern).

  • Trial days

    Gratistage am Anfang jedes neuen Abonnements. Mit 14 verbringt ein neuer Abonnent 2 Wochen im Status „trialing“, bevor die bezahlte Periode beginnt. 0 = keine Testphase.

  • Published

    Ob der Plan für deine Kunden überhaupt existiert. Ausgeschaltet ist er ein Entwurf: Du kannst Preis, Limits und Feature-Keys über mehrere Sitzungen festlegen, und deine API-Schlüssel sehen ihn nie — er fehlt in der Planliste des SDK, eine durchgesickerte Plan-ID antwortet 404, und niemand kann ihn abonnieren. Neue Pläne sind veröffentlicht; schalte es aus, um einen in Ruhe vorzubereiten, und wieder ein, wenn er verkauft wird. Später wieder auszuschalten schließt die Tür für neue Abonnenten, ohne die bestehenden anzutasten.

  • Features

    Die An/Aus-Vorteile, die der Plan enthält — kurze Schlüssel, die du dir ausdenkst, etwa sso oder priority-support (Kleinbuchstaben, Ziffern, - und _). Deine App fragt das SDK entitlements.check(customerId, 'sso') und bekommt nur für Kunden auf einem Plan, der den Schlüssel führt, ein Ja. Jederzeit änderbar, bei neuen wie bestehenden Plänen; für Dinge, die du zählst, nimm stattdessen ein Meter-Limit weiter unten.

Meter-Limits — der Abschnitt „+ Add limit“

Jede Limit-Zeile verbindet diesen Plan mit einem Meter und beantwortet: Wie viel davon ist inklusive, und was passiert darüber hinaus?

  • Meter *

    Auf welche gemessene Größe sich dieses Limit bezieht. Das Dropdown listet die Meter, die du in diesem Projekt angelegt hast — nicht mehr, nicht weniger. Es ist kein fester Katalog: Jede neue Produktfähigkeit braucht nur zuerst einen neuen Meter, und er erscheint hier sofort.

  • Included units

    Das im Planpreis enthaltene Kontingent, pro Abrechnungszeitraum. „Pro enthält 500 Bilder pro Monat“ → 500. In einer Hard- oder Soft-Zeile ist eine Zahl Pflicht, bevor der Plan angelegt werden kann — ein leeres Kontingent würde nichts begrenzen — es sei denn, du hakst unten Unlimited an und sagst damit, dass genau das gemeint war. In einer Metered-Zeile ist leer bereits eine Aussage: Pay-as-you-go ab der ersten Einheit.

  • Unlimited

    Nur in Hard- und Soft-Zeilen, und der ausdrückliche Weg zu sagen „kein Limit für diesen Meter“. Angehakt wird Included units abgeschaltet und geleert; nicht angehakt bleibt die Zahl Pflicht. Metered-Zeilen haben den Schalter nicht, weil leer dort schon etwas bedeutet.

  • Overage rate

    Der Preis in Credits pro Einheit, sobald der Kunde die inkludierten Einheiten überschreitet — 0.5 heißt: Jede zusätzliche Einheit kostet einen halben Credit von seinem Guthaben. Er gehört nur zum Typ Metered: Das Formular verlangt ihn in einer Metered-Zeile und blendet ihn bei Hard und Soft aus, und die API lehnt einen Satz in einer Hard- oder Soft-Zeile ab (422). Eine Metered-Zeile ohne inkludierte Einheiten und ohne Satz würde jede Einheit ablehnen, deshalb lehnt die API auch diese Zeile ab (422).

  • Limit type

    Was entitlements.check() des SDK antwortet, sobald die inkludierten Einheiten aufgebraucht sind — der Aufruf, den deine App vor der Arbeit macht. Hard (blockieren) — check() antwortet nein (hard_limit_reached) und deine App lehnt die Aktion ab; der Kunde stößt bis zur nächsten Periode oder einem Upgrade an eine Wand. Soft (warnen) — check() antwortet weiterhin ja, markiert mit soft_limit_exceeded, deine App lässt es also durch und bewegt den Kunden zum Upgrade. Metered (abrechnen) — check() antwortet ja, solange die Credits des Kunden die zusätzlichen Einheiten decken, und jede zusätzliche Einheit wird zum Mehrverbrauchssatz vom Guthaben abgebucht; reicht das Guthaben nicht, lautet die Antwort nein (insufficient_credits). Metered ist die „Pay-as-you-go“-Option und die einzige, die von selbst Geld (Credits) bewegt. Ein Metered-Limit wird bei einem Max- oder Min-Meter abgelehnt (422): Ein Höchst- oder Tiefstwert lässt sich nicht pro Einheit abrechnen. In einer Metered-Zeile kann ein Ausgabenlimit am Abonnement des Kunden check() schon mit nein antworten lassen, bevor das Guthaben aufgebraucht ist (spend_cap_reached). Hard und Soft lösen den Webhook limit.reached einmal pro Abrechnungszeitraum aus, beim ersten Überschreiten der Grenze. In jedem Fall zeichnet MeterFlow die Ereignisse, die deine App sendet, weiter auf — das Tor ist check(), in deinem Code.

Beispiel — ein realistischer Pro-PlanPro · 29 $ USD · Monatlich · 14 Testtage · Published ✓
Limit 1: Meter Erzeugte Bilder, inklusive 500, Typ Hard → nach 500 Bildern antwortet check() nein und deine App stellt die Erzeugung bis zum nächsten Monat oder einem Upgrade ein.
Limit 2: Meter Video-Render-Sekunden, inklusive 1 000, Mehrverbrauch 0,02, Typ Metered → jenseits von 1 000 Sekunden kostet jede weitere Sekunde stillschweigend 0,02 Credits aus dem Guthaben des Kunden.
Warum ist „+ Add limit“ ausgegraut?

Weil das Projekt noch keine Meter hat — ein Limit ist immer eine Obergrenze auf einem Meter; ohne Meter gibt es nichts, woran man es hängen könnte. Der Dialog zeigt den Hinweis „Create meters first to attach limits to this plan.“ Gehe zu Meters → New meter, lege mindestens einen an und öffne diesen Dialog erneut.

Warum zeigt das Meter-Dropdown nur wenige Optionen? Was, wenn mein Produkt etwas Neues hat?

Das Dropdown zeigt schlicht deine eigenen Meter des aktuell gewählten Projekts. In den Demo-Daten sind das zufällig „Images generated“, „Video render seconds“, „Upscales processed“, „Peak GPU memory“ und „Active prompters“ — aber diese Liste gehört dir und wächst mit. Sie beschränkt nicht, was Kunden tun können: Kunden wählen nie Meter aus; du definierst Meter für alles, was dein Produkt tut. Morgen ein neues Feature? Lege einen Meter dafür an, und er taucht hier auf.

Ein Kunde ist über einem Hard-Limit — warum werden seine Ereignisse trotzdem aufgezeichnet?

Weil MeterFlow nie anstelle deines Produkts entscheidet, was ein Nutzer darf — das tut deine App, indem sie vor der Aktion entitlements.check() aufruft. Ein Hard-Limit lässt diesen Aufruf nein antworten; überspringt deine App den Aufruf und erledigt die Arbeit trotzdem, wird das Nutzungsereignis dennoch angenommen und gespeichert, damit deine Historie und jede Metered-Abbuchung ehrlich bleiben. Stell dir das Limit als Regel vor und check() als Türsteher: MeterFlow schreibt die Regel, dein Code steht an der Tür.

Was antwortet check(), wenn MeterFlow nicht erreichbar ist?

Ab meterflow 0.10.0 (npm) / 0.5.0 (PyPI) antwortet das SDK weiter. Es verwendet jede Antwort für die 15 Sekunden wieder, die die API erlaubt, und eine Nutzungsmeldung, Gutschrift oder Abbuchung für einen Kunden macht dessen Antworten veraltet. Ist MeterFlow nicht erreichbar — ein Netzwerkfehler, ein Timeout oder ein 5xx bzw. 429 nach den Wiederholungen —, gibt check() die letzte Antwort zurück, markiert mit stale: true; gibt es keine, den Standardwert, den du pro Funktion in entitlementDefaults festlegst ('allow' oder 'deny', '*' für den Rest), mit reason: 'offline_default'; ohne beides wirft es einen Fehler. Dein onError-Hook erfährt es zuerst. Ein 401, 403, 404 oder 422 ist eine echte Antwort und wird nie verdeckt.

Warum kann ich Preis oder Limits eines bestehenden Plans nicht bearbeiten?

Absichtlich: Bestehende Abonnenten haben zu diesen Konditionen abgeschlossen, deshalb werden Preis, Währung, Abrechnungszeitraum und Meter-Limits bei der Erstellung eingefroren. Beim Bearbeiten eines Plans lassen sich nur Name, Beschreibung, Testtage, Veröffentlichungsstatus, Aktiv-Flag und Feature-Schlüssel ändern. Zum Umbepreisen legst du einen neuen Plan an (z. B. „Pro 2026“) und führst neue Kunden dorthin.

Neues Abonnement verbindet Kunde ⇄ Plan

Ein Abonnement bindet einen deiner Kunden an einen Plan. Ab diesem Moment wird seine Nutzung an den Meter-Limits dieses Plans gemessen. In Produktion erstellt dein Backend es üblicherweise per SDK, sobald jemand beim Checkout eine Stufe wählt — der Dialog macht dasselbe von Hand.

📍 Projekt öffnen → Subscriptions → der Button im Tabellenkopf

  • Customer ID *

    Dein eigener Bezeichner für den Endkunden — eine beliebige Zeichenkette deiner Wahl: eine Nutzer-ID aus deiner Datenbank (user-842), eine E-Mail, ein Tenant-Kürzel. MeterFlow validiert sie gegen nichts; was du sendest, ist, wem das Abonnement gehört. Verwende überall dieselbe ID (Abonnements, Credits, Nutzung), sonst finden die Teile nicht zueinander.

  • Plan *

    Auf welcher Preisstufe er ist — das Dropdown listet die Pläne dieses Projekts. Hat der Plan Testtage, startet das Abonnement im Status „trialing“, sonst „active“.

BeispielKunde user-842 klickt in deiner App auf „Upgrade auf Pro“ → dein Backend ruft subscriptions.create({ customer_external_id: 'user-842', plan_id: … }) auf. Jedes Nutzungsereignis von user-842 wird nun gegen die Limits von Pro geprüft.
Was, wenn ein Kunde kein Abonnement hat — gehen seine Ereignisse verloren?

Nein. Ereignisse werden immer gespeichert und erscheinen immer in den Nutzungsübersichten. Ohne aktives Abonnement oder laufende Testphase wird nichts abgerechnet, und entitlements.check() antwortet nein mit no_subscription — eine App, die vorher fragt, lässt die Aktion also nicht durch. Die Abrechnungslogik schaltet sich ein, sobald ein Abonnement existiert.

Kann ich begrenzen, was ein Kunde in einem Zeitraum ausgibt?

Ja — setze spend_cap, in Credits, am Abonnement über das SDK oder die API; leer heißt kein Limit. Erreichen die Ausgaben des Zeitraums es, verbraucht aufgezeichnete Nutzung keine Credits mehr, ein credits.deduct() darüber hinaus wird mit 409 abgelehnt, entitlements.check() antwortet nein mit spend_cap_reached, bevor eine abgerechnete Aktion es überschreiten würde, und der Webhook cap.reached feuert einmal im Zeitraum.

Ein Kunde hat gekündigt — kann er zurückkommen?

Ja, auf demselben Abonnement. Setze seinen Status wieder auf active — subscriptions.update(id, { status: 'active' }) oder Reactivate in seiner Zeile. Ist der alte Zeitraum abgelaufen, beginnt sofort ein neuer, mit den Credits des Plans für den Zeitraum; eine vor ihrem Ende gekündigte Testphase läuft als Testphase weiter. Ein inzwischen deaktivierter oder nicht mehr veröffentlichter Plan nimmt niemanden zurück (409), und ein Abonnement, das der Connector deines Zahlungsanbieters steuert, kommt über den Anbieter zurück, nicht hier.

Kann ich das Abonnement eines Kunden in einer langen Liste finden?

Ja. Die Seite Subscriptions hat einen Kundenfilter und Status-Chips, und das SDK nimmt dieselben zwei: subscriptions.list({ q, status }). q findet jede Kunden-ID, die es enthält; status ist einer von active, trialing, past_due, paused, canceled oder expired. Der Server filtert, bevor er die Seite zuschneidet, also enthält jede Seite nur Treffer. Im SDK ab meterflow 0.9.0 (npm) / 0.4.0 (PyPI). Ab 0.12.0 / 0.7.0 nimmt es außerdem sort — created_at (Standard), customer_external_id oder status — und order, desc oder asc; gib beide mit jedem next_cursor erneut mit.

Die Kundenseite ein Kunde, vollständig

Jeder Kunde, für den deine App etwas geschrieben hat — ein Abonnement, ein Credit-Guthaben oder ein Nutzungsereignis — ist eine Zeile auf der Seite Customers. Öffne ihn, und seine Seite enthält die ganze Geschichte: wer er ist, auf welchem Plan er ist, und vier Tabs.

📍 Projekt öffnen → Customers → die Zeile des Kunden

  • Credits

    Sein Guthaben und jede Ledger-Zeile dahinter, mit Grant und Deduct — die Dialoge sind weiter unten erklärt.

  • Usage

    Was er genutzt hat, Meter für Meter.

  • Subscription

    Sein Plan und dessen Status, mit Cancel oder Reactivate.

  • Entitlements

    Was sein Plan gewährt, Feature für Feature: was von jedem abgerechneten Kontingent übrig ist, und der Grund, aus dem ein Feature abgelehnt wird, genau wie entitlements.check() ihn liefern würde.

Credits gutschreiben / abziehen das Guthaben

Credits sind ein vorausbezahltes Guthaben pro Kunde (pro Projekt) — wie ein Portemonnaie oder eine Prepaid-Karte. Du entscheidest, was ein Credit in deiner Preisgestaltung wert ist. „Metered“-Mehrverbrauch bedient sich automatisch aus diesem Guthaben; die beiden Dialoge bewegen Credits von Hand.

📍 Projekt öffnen → Customers → die Zeile des Kunden → Tab Credits → „Grant“ / „Deduct“

  • Amount *

    Wie viele Credits hinzukommen (Grant) oder abgehen (Deduct). Muss größer als null sein — die Richtung bestimmt der Button, der den Dialog geöffnet hat, nicht ein Minuszeichen.

  • Description

    Ein optionaler Vermerk auf dem Journaleintrag — „Willkommensbonus“, „Erstattung wegen Ausfall“, „Support-Kulanz“. Dein zukünftiges Ich wird es dir danken.

BeispielDer Neukunde user-842 erhält eine Gutschrift von 100 („Willkommensbonus“). Er rendert 2 500 Videosekunden auf einem Plan mit 1 000 inklusive und 0,02 Metered-Mehrverbrauch → 1 500 × 0,02 = 30 Credits werden automatisch abgezogen. Guthaben: 70.
Gut zu wissen — das Journal lügt nieSalden werden nie direkt bearbeitet. Jede Gutschrift, jeder Abzug und jede automatische Nutzungsabbuchung ist eine neue, dauerhafte Zeile in einem Nur-Anfügen-Journal, die jeweils den Saldo davor und danach festhält — ein lückenloser Prüfpfad, wie ein Kontoauszug. Ein Fehler passiert? Du löschst den Eintrag nicht, du fügst einen ausgleichenden hinzu. Und ein Abzug, der größer ist als das verfügbare Guthaben (das Guthaben abzüglich reservierter Credits), wird rundweg abgelehnt (die API liefert den Fehler „402 unzureichendes Guthaben“) — ein Guthaben kann nicht ins Minus rutschen.
Verbraucht die Nutzung dieses Kunden sein Guthaben?

Frag das Guthaben: credits.balance() antwortet mit usage_draws_credits. true — sein Plan rechnet Nutzung über das Kontingent hinaus ab, aufgezeichnete Nutzung verbraucht also von selbst Credits. false — nur ein ausdrückliches credits.deduct() bewegt es. null — er hat kein aktives Abonnement und keine laufende Testphase.

Kann meine App einen Kunden automatisch aufladen?

MeterFlow sagt deiner App, wann und wie viel; deine App belastet den Kunden und vergibt dann die Credits. Gib einem Webhook-Endpunkt einen Schwellenwert für niedriges Guthaben, und er erhält balance.low, wenn das Guthaben eines Kunden darunter fällt — durch eine Abbuchung oder durch abgerechnete Nutzung — und balance.topped_up, wenn eine Gutschrift es wieder darüber hebt. Setze topup_amount am Abonnement des Kunden, und balance.low liefert ihn als suggested_topup mit. Setze max_topups_per_window, und eine Gutschrift über diese Anzahl im selben Zeitraum hinaus wird mit 409 abgelehnt, damit eine Schleife in deinem Code nicht weiter auflädt.

Kann ich Credits für einen langen Job zurückhalten?

Ja, ab meterflow 0.11.0 (npm) / 0.6.0 (PyPI). credits.reserve() hält einen Teil des Guthabens eines Kunden für ttl_seconds zurück — 5 Minuten, wenn du nichts anderes angibst, höchstens einen Tag. Das Guthaben bewegt sich nicht, aber nichts anderes kann das Zurückgehaltene ausgeben: ein credits.deduct(), abgerechnete Nutzung, ein check(), das abbuchen würde, und eine weitere Reservierung sehen nur die verfügbaren Credits, also das Guthaben abzüglich des Zurückgehaltenen. Ist der Job fertig, nimmt credits.confirmReservation(id, { amount }) die Reservierung ganz oder teilweise als eine normale Abbuchung im Journal und gibt den Rest frei, und credits.releaseReservation(id) gibt sie ganz frei; eine vergessene Reservierung gibt sich beim Ablauf selbst frei. credits.balance() zeigt reserved und available neben dem Guthaben, und zurückgehaltene Credits zählen auch gegen ein Ausgabenlimit.

Zeig deinen Kunden ihr Guthaben

Die gehostete Guthabenseite für einen Kunden: das Guthaben mit der Schaltfläche Buy more, der Plan mit dem Rest jedes Kontingents und die letzten Journalzeilen

MeterFlow hostet eine Seite, die einem deiner Kunden sein eigenes Guthaben zeigt: den Stand, die letzten Journalzeilen dahinter, seinen Plan mit dem, was von jedem abgerechneten Kontingent übrig ist, und was er außerhalb des Plans genutzt hat. Du baust und hostest sie nicht — dein Server gibt dem Kunden einen Link.

Wie ein Kunde dorthin kommt 1. Deine App zeigt einen Button — „Deine Credits“ — der deinen Server aufruft. 2. Dein Server holt bei MeterFlow einen Link und schickt den Kunden zu link.url. Der Link trägt sein eigenes kurzlebiges Token, dein API-Schlüssel verlässt deinen Server also nie. In Python heißt es client.portal.create_session(…), mit denselben Feldern. 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 öffnet topup_url — deine eigene Checkout-Seite, genau so, wie du sie eingetragen hast, ohne Zusätze. Das ist optional: Ohne topup_url, weder am Link noch in den Standardwerten des Projekts, hat die Seite keinen Buy-more-Button. ← Back führt zu return_url, ebenso optional. 4. MeterFlow nimmt nie die Zahlung entgegen: Meldet dein Checkout eine, ruft dein Server credits.grant() auf, und die Seite zeigt das neue Guthaben.
  • Der Link

    Gilt 60 Minuten, sofern du nicht expires_in_minutes setzt — höchstens 24 Stunden — und lässt sich vorher nicht zurückziehen. Er öffnet die Seite eines einzigen Kunden, nur lesend: Er kann nichts ändern und keinen anderen Kunden zeigen. Ein mit einem Testschlüssel (mf_test_…) erzeugter Link zeigt Testdaten, unter einem Badge Test data.

  • Dein Look

    Projekt öffnen → Portal: Firmenname, Logo, helles / dunkles / automatisches Theme, Farben und Eckenradius, dazu die Standardwerte — Buy-more-URL, Back-URL und Gültigkeitsdauer — für Links, die sie weglassen. Ein Häkchen überträgt den Look auf alle Projekte der Organisation.

  • Ein Link von Hand

    In der Tabelle Customers erzeugt die Zeilenaktion Create a portal link ohne Code einen Link für diesen Kunden — ebenso Portal link in seinem Tab Credits.

Nutzungsereignis erfassen Kernkonzept

Ein Nutzungsereignis = „Dieser Kunde hat gerade diese Sache getan, in dieser Menge.“ In Produktion sendet deine Anwendung sie automatisch über das SDK, tausende Male am Tag; der Dialog existiert, damit du eins von Hand einspeisen kannst — für Tests und Demos.

📍 Projekt öffnen → Usage → einen Kunden nachschlagen → „Record event“

  • Event name *

    Muss exakt dem Ereignisnamen eines existierenden, aktiven Meters in diesem Projekt entsprechen (Groß-/Kleinschreibung zählt). Über diese Übereinstimmung weiß MeterFlow, welchen Zähler dieses Ereignis speist. Kein passender Meter → die API lehnt das Ereignis mit 404 ab und nichts wird gespeichert. Die exakte Schreibweise findest du auf der Meters-Seite.

  • Customer ID *

    Welcher deiner Kunden es getan hat — dieselbe frei wählbare ID-Zeichenkette wie bei Abonnements und Credits. Konsistenz ist alles: user-842 und USER-842 sind zwei verschiedene Kunden.

  • Value

    Die Menge — optional. Lässt du sie weg, liest ein Sum-, Max- oder Min-Meter sie aus der Ereigniseigenschaft, die sein Aggregationsfeld benennt (deine App schickt sie unter properties); sonst zählt das Ereignis 1. Die Bedeutung hängt von der Aggregation des Meters ab: Bei einem Count-Meter wird der Wert ignoriert (jedes Ereignis zählt als ein Vorkommen); bei Sum ist es die zu addierende Menge (42 Sekunden, 1 300 Tokens); bei Max/Min der verglichene Messwert; ein Unique count-Meter zählt die verschiedenen Werte seines Aggregationsfelds.

Was nach dem Klick auf „Record“ passiert — die ganze Reise1. Der Ereignisname wird einem Meter zugeordnet — etwa video.rendered → „Video render seconds“. 2. Das Ereignis wird dauerhaft gespeichert (roh — aggregiert wird später, beim Lesen). 3. Im Hintergrund prüft MeterFlow, ob der Kunde ein aktives Abonnement hat und ob dieser Plan ein Limit auf diesem Meter führt. 4. Ist das Limit Metered, werden die Einheiten über dem Inklusivkontingent zum Mehrverbrauchssatz vom Credit-Guthaben des Kunden abgebucht und eine Ledger-Zeile geschrieben — bis zum Ausgabenlimit des Zeitraums, falls das Abonnement eines hat; ist es Hard oder Soft und überschreitet dieses Ereignis als erstes die inkludierten Einheiten im Zeitraum, feuert der Webhook limit.reached einmal. Abgelehnt wird das Ereignis hier nie — ablehnen ist die Aufgabe von check(), in deiner App. 5. Die Nutzungsübersicht auf dieser Seite wird aus den Rohereignissen mit dem Aggregationstyp des Meters neu berechnet.
Ich habe ein Ereignis erfasst und einen Fehler bekommen — warum?

Fast immer liegt es am Ereignisnamen: Er stimmt mit keinem aktiven Meter dieses Projekts exakt überein. Der Fehler sagt es wörtlich — „No active meter found for event '…' in this project.“ Kopiere den Ereignisnamen von der Meters-Seite, statt ihn neu zu tippen. Beachte auch: Meter gelten pro Projekt — ein Meter aus einem anderen Projekt zählt nicht.

Wenn meine App eine Anfrage wiederholt, wird das Ereignis doppelt gezählt?

Nicht bei korrekter SDK-Nutzung: Jeder Schreibvorgang akzeptiert einen Idempotenzschlüssel — eine eindeutige Markierung für „genau diese Aktion“. Kommt derselbe Schlüssel zweimal an (ein Retry nach einem Netzwerkschluckauf), erkennt MeterFlow ihn und liefert das ursprüngliche Ergebnis zurück, statt ein Duplikat zu speichern. Der manuelle Dialog sendet keinen — zweimal von Hand auf Record zu drücken erzeugt also wirklich zwei Ereignisse.

Brauche ich ein Event pro API-Aufruf?

Nein — und meistens solltest du das auch nicht. Value ist eine Menge, und ein Sum-Meter addiert diese Mengen: Ein einzelnes Event mit dem Wert 1 300 ist ein Event auf das Monatskontingent deines Tarifs und 1 300 Einheiten auf dem Meter. Ein Event pro API-Aufruf ist das, was einen Tarif aufbraucht: 1 000 Nutzer mit je 100 Aufrufen pro Tag ergeben rund 3 Millionen Events im Monat.

Aggregiere in deiner eigenen Anwendung über ein Fenster, dessen Verlust du bei einem Absturz verschmerzen könntest — eine Anfrage, ein Job, eine Minute — und erfasse dann ein einziges Event mit der Summe. Sie als Batch zu senden ist nicht dasselbe: Ein Batch von 100 spart HTTP-Anfragen, aber jedes Event bleibt ein eigener Datensatz und zählt weiterhin.

Das gilt für Sum-Meter. Ein Count-Meter ignoriert den Wert und zählt Vorkommnisse — dort braucht jedes Vorkommnis sein eigenes Event. In beiden Fällen ändert sich an niemandes Rechnung etwas: Ein Metered-Limit rechnet pro Einheit ab.

Kann ich Nutzung erfassen, die schon länger zurückliegt?

Nur innerhalb von fünf Minuten. Der timestamp eines Events darf höchstens 5 Minuten in der Vergangenheit und 60 Sekunden in der Zukunft liegen; außerhalb dieses Fensters lehnt die API es mit 422 ab und speichert nichts. Ohne timestamp bekommt das Event den Zeitpunkt seines Eintreffens. Erfasse Nutzung, während sie passiert: Ältere Nutzung lässt sich nachträglich nicht laden.

Neuer Webhook Benachrichtigungen

Ein Webhook ist eine URL auf deinem Server, die MeterFlow aufruft, wenn in deinem Projekt etwas passiert — Credits gutgeschrieben, ein Limit erreicht, ein Guthaben geht zur Neige. Jeder Aufruf ist signiert und wird wiederholt, wenn dein Server nicht antwortet.

📍 Projekt öffnen → Webhooks → der Button im Tabellenkopf

  • Endpoint URL *

    Wohin MeterFlow die Ereignisse sendet, z. B. https://api.acme.dev/meterflow.

  • Events to deliver

    Von welchen Ereignissen dieser Endpunkt erfährt: usage.recorded, credit.granted, credit.deducted (eine Abbuchung oder eine abgerechnete Metered-Nutzung — sein transaction_type sagt, welche), subscription.created, .updated, .renewed und .canceled, limit.reached, cap.reached, balance.exhausted, dazu die beiden unten.

  • Low balance threshold

    Ein Guthaben, in Credits. Setzt du ihn, erhält der Endpunkt auch balance.low, wenn das Guthaben eines Kunden darunter fällt, und balance.topped_up, wenn es wieder darüber steigt; löschst du ihn, enden beide. Die zwei Ereignisse kommen und gehen mit dem Schwellenwert, denn ohne Linie lässt sich einem Endpunkt kein Überschreiten melden.

Aus deinem CodeDeine App kann ihre Endpunkte und deren Zustellbelege über das SDK lesen, um zu sehen, ob ein Ereignis angekommen ist: webhooks.list(), webhooks.deliveries(id) für die neuesten 100 und webhooks.deliveryPage(id) (in Python delivery_page) für jeden Versuch, Seite für Seite, die neuesten zuerst. Das Zustellprotokoll im Dashboard blättert genauso. Endpunkte anlegen und ändern bleibt hier, im Dashboard.

Deinen Zahlungsanbieter verbinden deine Abrechnung

Wenn deine Kunden dich über Paddle, Polar, Lemon Squeezy, Chargebee oder Razorpay bezahlen, lässt ein Connector dieses Konto MeterFlow steuern: Dein Anbieter ruft MeterFlow bei jeder Abo-Änderung und Zahlung auf, und das passende Abonnement oder die passende Credit-Gutschrift erscheint hier — ohne Code in deiner App.

📍 Projekt öffnen → Connectors → der Button im Tabellenkopf

  • Provider *

    Über welchen der fünf deine Kunden zahlen.

  • Which of your accounts

    Live — das Produktivkonto deines Anbieters, das Live-Daten schreibt; Test — seine Sandbox, die Testdaten schreibt. Ein Connector pro Anbieter und Konto.

  • Signing secret *

    Das Geheimnis, mit dem dein Anbieter seine Webhooks signiert — bei Chargebee, das nichts signiert, Benutzername und Passwort, die es stattdessen mitschickt. Es wird bei jedem Aufruf geprüft und nie wieder angezeigt: Die Tabelle zeigt nur seine letzten vier Zeichen.

Sobald er existiert

  • Die Webhook-URL

    Wird angezeigt, sobald der Connector angelegt ist: Füge sie in die Webhook-Einstellungen deines Anbieters ein.

  • Preis → Plan-Zuordnungen

    Welcher Preis deines Anbieters — ein Produkt bei Polar, eine Variante bei Lemon Squeezy, ein Plan bei Chargebee und Razorpay — einen Kunden auf welchen deiner Pläne setzt. Ein Ereignis zu einem Preis ohne Zuordnung wird protokolliert und ändert nichts.

  • Zustellprotokoll

    Jedes Ereignis, das der Connector empfangen hat, mit dem, was er damit tat, in einem Satz: was angewendet wurde und warum der Rest ignoriert wurde.

Mitglieder und Einladungen Team-Zugriff

Die Seite Members deiner Organisation zeigt, wer dazugehört — mit Rolle und wer eingeladen hat — und die noch offenen Einladungen. Ein Owner oder Admin lädt per E-Mail ein; die Person braucht noch kein MeterFlow-Konto.

📍 Members in der Seitenleiste, neben Billing → „Invite member“ (auch als Zeilenaktion bei den Organisationen im Dashboard)

  • Email *

    Wohin die Einladung geht. MeterFlow schickt einen Link, der einmal funktioniert, 7 Tage lang, nur für diese Adresse: Die Person öffnet ihn und tritt bei — mit ihrem Konto oder indem sie über den Link eines anlegt.

  • Role

    Admin — Organisationseinstellungen, Einladungen, API-Schlüssel, Webhooks, Connectoren, Projekte und Abrechnung. Member — wer täglich arbeitet: Meter, Pläne und die Seiten Subscriptions, Usage und Kunde. Viewer — nur lesen. Eine Option „Owner“ gibt es absichtlich nicht: Eigentümerschaft wird nicht per Einladung vergeben.

  • Offene Einladungen

    Stehen auf der Seite Members, bis sie angenommen, widerrufen werden oder ablaufen. Revoke stoppt den Link sofort.

  • Change role · Remove

    In der Zeile jedes Mitglieds, für Owner und Admins. Die Mitgliedschaft des Owners und deine eigene lassen sich dort nicht ändern. Wer entfernt wird, verliert den Zugang; sein Konto und was er angelegt hat, bleiben.

BeispielDu lädst dana@acme.dev als Viewer ein, damit das Finanzteam Nutzung und Salden beobachten kann, ohne Preise ändern zu können.
↑