MeterFlow

Cada diálogo de “Nuevo …”, explicado en lenguaje llano

El panel de MeterFlow tiene varios diálogos que crean registros reales en la base de datos — meters, planes, suscripciones, créditos, eventos de uso, claves API. Esta página explica qué hace cada uno, campo por campo, con ejemplos sencillos. No se necesita ningún conocimiento previo de medición ni de facturación por uso.

Empieza aquí: la visión general

MeterFlow responde a una sola pregunta sobre tu producto: “¿quién usó cuánto de qué — y cuánto le cuesta?” Todo lo que ves en el panel existe para responder a esa pregunta.

Tú administrador clienteEl desarrollador o la empresa que usa MeterFlow. Inicias sesión en este panel, defines qué medir y estableces las reglas de precios.
Tu aplicación el SDKTu propio backend, con el SDK de MeterFlow instalado. Envía los eventos de uso automáticamente a medida que tus clientes usan tu producto. Los diálogos del panel para uso/créditos/suscripciones hacen a mano exactamente lo que el SDK hace en código.
Tu cliente ID de clienteEl usuario final de tu producto. Nunca inicia sesión en MeterFlow ni tiene cuenta de MeterFlow — aquí existe solo como una cadena identificadora que tú eliges (p. ej. user-842 o un email).

Cómo encajan las piezas

¿Por qué algunos botones de “Crear” están desactivados?

Cada diálogo desactiva su botón de confirmación hasta que todos los campos obligatorios (marcados con *) estén rellenos — p. ej. “Create plan” sigue desactivado hasta que el plan tenga un Nombre. Si un botón parece atascado, busca un campo obligatorio vacío más arriba.

Nueva organización contenedor

El contenedor más externo — normalmente tu empresa. Todo lo demás (proyectos, meters, planes…) vive dentro de una organización. Recibiste una automáticamente al registrarte.

📍 Dashboard → el botón “New organization” (también se ofrece en el primer inicio de sesión, cuando aún no tienes ninguna)

  • Name *

    El nombre de tu empresa o equipo. Es solo una etiqueta — puedes cambiarla más adelante.

  • Billing email

    Adónde irían las facturas y avisos de facturación de tu cuenta de MeterFlow. Opcional; se valida el formato, pero no se envía nada para verificarlo.

EjemploAcme Robotics crea la organización “Acme Robotics” con el email de facturación finance@acme.dev. Sus dos productos se convertirán en dos proyectos dentro de ella.

Nuevo proyecto contenedor

Un proyecto = un producto o entorno que quieres medir. Cada meter, plan, clave API, saldo de cliente y evento de uso pertenece a exactamente un proyecto — los proyectos nunca ven los datos de los demás.

📍 Dashboard → el botón “New project” en la cabecera de la tabla Projects

  • Organization *

    A qué organización pertenece el proyecto. Preseleccionada si ya tienes una activa.

  • Name *

    El nombre del producto, p. ej. “PixelForge AI”. Se muestra por todo el panel y en el selector de proyectos.

  • Description

    Texto libre para tu propia referencia.

EjemploAcme tiene una herramienta de imágenes y un chatbot. Crea dos proyectos — “PixelForge AI” y “ChatDesk” — para que cada producto tenga sus propios meters, planes y saldos de clientes. El mismo ID de cliente en dos proyectos se trata como dos clientes sin relación.

Generar clave API acceso

La credencial que tu aplicación usa para hablar con MeterFlow. Tu backend se la pasa al SDK; cada evento de uso, operación de créditos y llamada de suscripciones se autentica — y se limita a un solo proyecto — mediante esta clave.

📍 Abre un proyecto → API Keys → el botón en la cabecera de la tabla

  • Key name *

    Una etiqueta para recordar dónde se usa la clave — “Backend de producción”, “Staging”, “Tests de CI”. Sin efecto técnico.

  • Environment

    Las claves Live empiezan por mf_live_, las Test por mf_test_ — y acceden a dos conjuntos de datos totalmente separados dentro del mismo proyecto. Las suscripciones, créditos y uso creados con una clave Test son invisibles para las claves Live (y viceversa), mientras que tus meters y planes se comparten: las pruebas siempre corren contra tu configuración de facturación real. Usa claves Test para desarrollo, staging y CI; las Live solo para el tráfico real de producción.

Importante — se muestra una sola vezLa clave completa se muestra solo una vez, justo después de crearla. MeterFlow guarda únicamente una huella criptográfica (un hash SHA-256) — la clave real no puede volver a mostrarse nunca, ni siquiera por nosotros. Cópiala de inmediato a tu gestor de secretos. Si la pierdes, revócala y genera una nueva.
EjemploCreas “Production backend” / Live, obtienes mf_live_a1b2… una sola vez y la pones en las variables de entorno de tu servidor: new MeterFlow({ apiKey: process.env.METERFLOW_KEY }). La lista del panel mostrará para siempre solo el prefijo y los últimos 4 caracteres.
¿Las claves de test comparten los límites de mi plan de MeterFlow?

No, el modo test tiene los suyos. Los eventos de test tienen una décima parte de la cuota mensual de tu plan de MeterFlow — Drip 5 000 · Flow 20 000 · Stream 70 000 · Torrent 400 000 — y nunca cuentan para la cuota live; los paquetes de eventos solo amplían la cuota live. Pasada la cuota (más el mismo 10 % de margen que en live), las escrituras de uso de test se rechazan con un 403. Las claves de test hacen hasta 60 peticiones por minuto, las live 300. Los datos de test caducan: los eventos de uso de test a los 30 días, y una suscripción de test sin uso durante 90 días, junto con el saldo y el registro de test de ese cliente. La página Billing y el diálogo Usage de tu organización muestran los eventos de test del mes frente a esa cuota, junto a los de producción.

Nuevo meter concepto clave

Un meter es la definición de un contador con nombre: declara una cosa de tu producto que merece medirse, y cómo los eventos en bruto deben convertirse en un número. Piénsalo como crear una nueva columna en un informe de uso antes de que existan los datos.

📍 Abre un proyecto → Meters → el botón en la cabecera de la tabla

  • Name *

    La etiqueta legible que se muestra en el panel — “Imágenes generadas”, “Segundos de render de vídeo”. Solo para ojos humanos.

  • Event name *

    La clave para máquinas — y sí, se guarda en la base de datos y se compara de forma exacta. Cuando tu aplicación reporta uso, envía un nombre de evento; MeterFlow busca en ese proyecto el meter activo cuyo event_name coincide exactamente, mayúsculas y minúsculas incluidas. Si no existe ninguno, el evento se rechaza con un error 404 (“No active meter found for event …”) y no se registra nada. Cada nombre de evento es único dentro de un proyecto. Convención: minúsculas con puntos, p. ej. image.generated.

  • Aggregation type

    Cómo se combinan muchos eventos individuales en un solo número en los resúmenes de uso. Mira la tabla de abajo — es el corazón del meter.

  • Aggregation field

    Obligatorio para Sum, Max, Min y Unique count; se rechaza en Count, que no lee ninguna propiedad. Nombra una propiedad de tus eventos. Para Sum, Max y Min es de donde sale la cantidad cuando tu app omite value — un meter con campo seconds lee properties.seconds; un value enviado por tu app siempre gana, y un evento sin ninguno de los dos cuenta 1. Para Unique count es la propiedad cuyos valores distintos se cuentan — model, para contar los modelos que usó un cliente.

  • Description

    Texto libre para tu equipo.

Los tipos de agregación, con un ejemplo

Supón que el cliente user-842 dispara 4 eventos este mes con valores 3, 10, 2, 10. Se reporta un número por meter — cuál, depende del tipo de agregación:

TipoQué pregunta respondeResultado para 3, 10, 2, 10Uso típico
Count¿Cuántas veces ocurrió? (valores ignorados)4Imágenes generadas, llamadas API, exportaciones
Sum¿Cuánto en total?25Segundos renderizados, tokens consumidos, GB transferidos
Max¿Cuál fue el mayor valor?10Pico de trabajos simultáneos, subida más grande
Min¿Cuál fue el menor valor?2Rara vez para facturar — más bien diagnóstico
Unique count¿Cuántos valores distintos del campo de agregación aparecieron?3  (3, 10, 2)Modelos distintos usados, documentos distintos tocados
Ejemplo — un meter completoName “Video render seconds” · Event name video.rendered · Agregación Sum · Aggregation field seconds.
Tu app termina de renderizar un clip de 42 segundos para user-842 y reporta el evento video.rendered con valor 42. Hazlo unas cuantas veces y la página de uso del cliente mostrará una línea: Video render seconds — 3 eventos — 117.
¿El nombre de evento tiene que coincidir con lo que envía mi app? ¿Qué pasa con una errata?

Sí — exactamente, mayúsculas incluidas. El nombre de evento del meter se guarda en la base de datos y actúa como la etiqueta de dirección de los eventos entrantes. Si tu app envía video.render pero el meter dice video.rendered, la API responde 404 “No active meter found for event 'video.render' in this project” y el evento no se guarda. Es deliberado: una errata silenciosa filtraría para siempre uso sin facturar. Crea primero el meter y luego empieza a enviar eventos con el mismo nombre.

¿Puedo cambiar el tipo de agregación más adelante?

No — tras la creación solo se pueden editar el nombre, la descripción y el estado activo. La agregación define qué significa el histórico guardado, así que cambiarla retroactivamente reescribiría el pasado. Si necesitas otro cálculo, crea un meter nuevo con un nombre de evento nuevo.

¿Cuándo es obligatorio “Aggregation field”?

Depende del tipo. El formulario solo lo muestra para Sum, Max, Min y Unique count, y el servidor rechaza una creación que lo deje vacío para esos tipos. En un meter Count el formulario lo oculta y el servidor lo rechaza si se envía: un conteo no lee ninguna propiedad, así que el campo nombraría algo que nada lee.

Nuevo plan concepto clave

Un plan es un nivel de precios — “Free”, “Pro a 29 $/mes”… Combina un precio recurrente con un conjunto de límites de meter que dicen cuánto de cada función medida está incluido y qué pasa más allá. Los clientes se vinculan a un plan mediante una suscripción.

📍 Abre un proyecto → Plans → el botón en la cabecera de la tabla

  • Name *

    El nombre del nivel — “Free”, “Pro”, “Enterprise”. Obligatorio; el botón de crear sigue desactivado hasta que se rellena.

  • Description

    Texto libre, p. ej. el eslogan de marketing del nivel.

  • Price / Currency / Billing period

    La cuota recurrente de la suscripción: Price es el importe (0 vale para un nivel gratuito), Currency un código como USD, y Billing period la frecuencia — mensual, anual, semanal o pago único. Fijos tras la creación — editar el plan después no puede cambiarlos (crea un plan nuevo en su lugar, para que las condiciones de los suscriptores actuales no cambien en silencio).

  • Trial days

    Días gratis al inicio de cada nueva suscripción. Con 14, un nuevo suscriptor pasa 2 semanas en estado “trialing” antes de que empiece el periodo de pago. 0 = sin prueba.

  • Published

    Si el plan existe para tus clientes. Si lo dejas apagado es un borrador: puedes fijar su precio, sus límites y sus claves de función en varias sesiones y tus claves de API nunca lo ven — no aparece en la lista de planes del SDK, un id filtrado responde 404 y nadie puede suscribirse a él. Los planes nuevos nacen publicados; apágalo para preparar uno con calma y enciéndelo cuando salga a la venta. Volver a apagarlo después cierra la puerta a nuevos suscriptores sin tocar a los que ya están.

  • Features

    Las ventajas de tipo sí/no que incluye el plan — claves cortas que tú inventas, como sso o priority-support (minúsculas, dígitos, - y _). Tu app pregunta al SDK entitlements.check(customerId, 'sso') y obtiene sí solo para clientes suscritos a un plan que lista esa clave. Editables en cualquier momento, en planes nuevos y existentes; para lo que se cuenta usa en su lugar un límite de meter más abajo.

Límites de meter — la sección “+ Add limit”

Cada fila de límite conecta este plan con un meter y responde: ¿cuánto de esa cosa está incluido, y qué pasa más allá?

  • Meter *

    A qué magnitud medida se aplica este límite. El desplegable lista los meters que creaste en este proyecto — ni más, ni menos. No es un catálogo fijo: cualquier nueva capacidad del producto solo necesita antes un meter nuevo, y aparece aquí de inmediato.

  • Included units

    La cantidad incluida en el precio del plan, por periodo de facturación. “Pro incluye 500 imágenes al mes” → 500. En una fila Hard o Soft la cifra es obligatoria antes de crear el plan — una cantidad vacía no limitaría nada — salvo que marques Unlimited abajo para decir que eso era lo que querías. En una fila Metered el vacío ya es una respuesta: pago por uso desde la primera unidad.

  • Unlimited

    Solo en las filas Hard y Soft, y es la forma explícita de decir “sin tope en este meter”. Al marcarlo, Included units se desactiva y se vacía; si lo dejas sin marcar, esa cifra sigue siendo obligatoria. Las filas Metered no tienen el interruptor, porque allí el vacío ya significa algo.

  • Overage rate

    El precio en créditos por unidad cuando el cliente supera las unidades incluidas — 0.5 significa que cada unidad extra cuesta medio crédito de su saldo. Solo pertenece al tipo Metered: el formulario lo pide en una fila Metered y lo oculta en Hard y Soft, y la API rechaza una tarifa en una fila Hard o Soft (422). Una fila Metered sin unidades incluidas ni tarifa rechazaría cada unidad, así que la API también rechaza esa fila (422).

  • Limit type

    Lo que responde entitlements.check() del SDK cuando se agotan las unidades incluidas — la llamada que tu app hace antes de hacer el trabajo. Hard (bloquear) — check() responde no (hard_limit_reached) y tu app rechaza la acción; el cliente choca con un muro hasta el siguiente periodo o una mejora de plan. Soft (avisar) — check() sigue respondiendo sí, marcado como soft_limit_exceeded, así que tu app lo deja pasar y anima al cliente a mejorar de plan. Metered (cobrar) — check() responde sí mientras los créditos del cliente cubran las unidades extra, y cada unidad extra se cobra de su saldo a la tarifa de exceso; cuando el saldo no alcanza, la respuesta es no (insufficient_credits). Metered es la opción “pago por uso” y la única que mueve dinero (créditos) por sí sola. Un límite Metered se rechaza en un meter Max o Min (422): un valor máximo o mínimo no se puede cobrar por unidad. En una fila Metered, un tope de gasto en la suscripción del cliente puede hacer que check() responda no antes de que se agote el saldo (spend_cap_reached). Hard y Soft disparan el webhook limit.reached una vez por periodo de facturación, la primera vez que se cruza la línea. En todos los casos MeterFlow sigue registrando los eventos que tu app envía — la puerta es check(), en tu código.

Ejemplo — un plan Pro realistaPro · 29 $ USD · Mensual · 14 días de prueba · Published ✓
Límite 1: meter Imágenes generadas, incluidas 500, tipo Hard → tras 500 imágenes, check() responde no y tu app deja de generar hasta el mes siguiente o una mejora de plan.
Límite 2: meter Segundos de render de vídeo, incluidos 1 000, exceso 0,02, tipo Metered → pasados los 1 000 segundos, cada segundo extra cuesta en silencio 0,02 créditos del monedero del cliente.
¿Por qué “+ Add limit” está desactivado?

Porque el proyecto aún no tiene meters — un límite siempre es un tope sobre un meter, así que con cero meters no hay nada a lo que asociarlo. El diálogo muestra la pista “Create meters first to attach limits to this plan.” Ve a Meters → New meter, crea al menos uno y vuelve a abrir este diálogo.

¿Por qué el desplegable de Meter muestra solo unas pocas opciones? ¿Y si mi producto tiene algo nuevo?

El desplegable es simplemente tus propios meters del proyecto seleccionado. En los datos de demostración resultan ser “Images generated”, “Video render seconds”, “Upscales processed”, “Peak GPU memory” y “Active prompters” — pero esa lista es tuya y puede crecer. No restringe lo que los clientes pueden hacer: los clientes nunca eligen meters; tú defines meters para lo que sea que haga tu producto. ¿Una función nueva mañana? Crea un meter para ella y aparecerá aquí.

Un cliente ha superado un límite Hard — ¿por qué se siguen registrando sus eventos?

Porque MeterFlow nunca decide por tu producto lo que un usuario puede hacer — lo decide tu app, llamando a entitlements.check() antes de la acción. Un límite Hard hace que esa llamada responda no; si tu app se salta la llamada y hace el trabajo igualmente, el evento de uso se acepta y se guarda de todos modos, para que tu historial y cualquier cargo metered sigan siendo honestos. Piensa en el límite como la regla y en check() como el portero de la puerta: MeterFlow escribe la regla, tu código está en la puerta.

¿Qué responde check() cuando MeterFlow no responde?

Desde meterflow 0.10.0 (npm) / 0.5.0 (PyPI), el SDK sigue respondiendo. Reutiliza cada respuesta durante los 15 segundos que permite la API, y un registro de uso, un abono o una deducción para un cliente deja obsoletas las respuestas de ese cliente. Si no se puede contactar con MeterFlow — un error de red, un timeout, o un 5xx o 429 tras los reintentos —, check() da la última respuesta, marcada stale: true; si no hay ninguna, el valor por defecto que defines por funcionalidad en entitlementDefaults ('allow' o 'deny', '*' para el resto), con reason: 'offline_default'; sin ninguno de los dos, lanza un error. Tu hook onError se entera primero. Un 401, 403, 404 o 422 es una respuesta real y nunca se oculta.

¿Por qué no puedo editar el precio o los límites de un plan existente?

Es por diseño: los suscriptores actuales contrataron bajo esas condiciones, así que el precio, la moneda, el periodo de facturación y los límites de meter quedan congelados al crear. Editar un plan solo puede cambiar su nombre, descripción, días de prueba, estado de publicación, estado activo y claves de funcionalidades. Para cambiar precios, crea un plan nuevo (p. ej. “Pro 2026”) y lleva allí a los nuevos clientes.

Nueva suscripción vincula cliente ⇄ plan

Una suscripción vincula a uno de tus clientes con un plan. Desde ese momento su uso se juzga contra los límites de meter de ese plan. En producción, tu backend normalmente la crea vía SDK en el instante en que alguien elige un nivel al pagar — el diálogo hace lo mismo a mano.

📍 Abre un proyecto → Subscriptions → el botón en la cabecera de la tabla

  • Customer ID *

    Tu propio identificador del cliente final — cualquier cadena que elijas: un ID de usuario de tu base de datos (user-842), un email, un slug de tenant. MeterFlow nunca lo valida contra nada; lo que envíes es a quien pertenece la suscripción. Usa el mismo ID en todas partes (suscripciones, créditos, uso) o las piezas no conectarán.

  • Plan *

    En qué nivel de precios está — el desplegable lista los planes de este proyecto. Si el plan tiene días de prueba, la suscripción empieza en “trialing”; si no, en “active”.

EjemploEl cliente user-842 pulsa “Mejorar a Pro” en tu app → tu backend llama a subscriptions.create({ customer_external_id: 'user-842', plan_id: … }). Cada evento de uso de user-842 se contrasta ahora con los límites de Pro.
¿Y si un cliente no tiene suscripción — se pierden sus eventos?

No. Los eventos siempre se guardan y siempre aparecen en los resúmenes de uso. Sin una suscripción activa o en prueba no se cobra nada, y entitlements.check() responde no con no_subscription — así que una app que pregunta antes no dejará pasar la acción. La lógica de facturación se activa en cuanto existe una suscripción.

¿Puedo limitar lo que gasta un cliente en un periodo?

Sí — define spend_cap, en créditos, en la suscripción mediante el SDK o la API; vacío significa sin tope. Cuando el gasto del periodo lo alcanza, el uso registrado deja de consumir créditos, un credits.deduct() que lo supere se rechaza con un 409, entitlements.check() responde no con spend_cap_reached antes de que una acción medida lo cruce, y el webhook cap.reached se dispara una vez en el periodo.

Un cliente canceló — ¿puede volver?

Sí, en la misma suscripción. Vuelve a poner su estado en active — subscriptions.update(id, { status: 'active' }), o Reactivate en su fila. Si el periodo anterior terminó, empieza uno nuevo ahora, con los créditos del periodo del plan; una prueba cancelada antes de su fin se reanuda como prueba. Un plan desactivado o despublicado desde entonces no readmite a nadie (409), y una suscripción que gestiona el conector de tu proveedor de pagos vuelve a través del proveedor, no aquí.

¿Puedo encontrar la suscripción de un cliente en una lista larga?

Sí. La página Subscriptions tiene un filtro por cliente y chips de estado, y el SDK acepta los mismos dos: subscriptions.list({ q, status }). q encuentra cualquier ID de cliente que lo contenga; status es uno de active, trialing, past_due, paused, canceled o expired. El servidor filtra antes de cortar la página, así que cada página contiene solo coincidencias. En el SDK desde meterflow 0.9.0 (npm) / 0.4.0 (PyPI). Desde 0.12.0 / 0.7.0 acepta también sort — created_at (por defecto), customer_external_id o status — y order, desc o asc; pasa los mismos dos con cada next_cursor.

La página del cliente un cliente, al completo

Cada cliente para el que tu app ha escrito algo — una suscripción, un saldo de créditos o un evento de uso — es una fila en la página Customers. Ábrelo y su página tiene toda la historia: quién es, en qué plan está y cuatro pestañas.

📍 Abre un proyecto → Customers → la fila del cliente

  • Credits

    Su saldo y cada línea del libro que lo forma, con Grant y Deduct — los diálogos se explican más abajo.

  • Usage

    Lo que usó, meter por meter.

  • Subscription

    El plan en el que está y su estado, con Cancel o Reactivate.

  • Entitlements

    Lo que concede su plan, funcionalidad por funcionalidad: cuánto queda de cada allowance medida y el motivo por el que se rechaza una funcionalidad, tal como lo daría entitlements.check().

Abonar / Deducir créditos el monedero

Los créditos son un saldo prepagado por cliente (por proyecto) — piensa en un monedero o una tarjeta recargable. Tú decides cuánto vale un crédito en tus precios. El exceso “metered” se descuenta de este monedero automáticamente; los dos diálogos mueven créditos a mano.

📍 Abre un proyecto → Customers → la fila del cliente → pestaña Credits → “Grant” / “Deduct”

  • Amount *

    Cuántos créditos añadir (Grant) o quitar (Deduct). Debe ser mayor que cero — la dirección la decide el botón que abrió el diálogo, no un signo menos.

  • Description

    Una nota opcional guardada en la línea del registro — “Bono de bienvenida”, “Reembolso por la incidencia”, “Cortesía de soporte”. Tu yo del futuro te lo agradecerá.

EjemploEl nuevo registro user-842 recibe un abono de 100 (“Bono de bienvenida”). Renderiza 2 500 segundos de vídeo en un plan con 1 000 incluidos y exceso metered de 0,02 → 1 500 × 0,02 = 30 créditos deducidos automáticamente. Saldo: 70.
Conviene saberlo — el registro nunca mienteLos saldos nunca se editan directamente. Cada abono, deducción y cargo automático por uso es una línea nueva y permanente en un registro de solo-añadir, que anota el saldo antes y después — una pista de auditoría completa, como un extracto bancario. ¿Un error? No borras la línea; añades una compensatoria. Y una deducción mayor que los créditos disponibles (el saldo menos los retenidos) se rechaza de plano (la API devuelve un error “402 saldo insuficiente”) — un monedero no puede quedar en negativo.
¿Gastará el uso de este cliente su saldo?

Pregúntaselo al saldo: credits.balance() responde con usage_draws_credits. true — su plan cobra el uso por encima de lo incluido, así que el uso registrado consume créditos por sí solo. false — solo un credits.deduct() explícito lo mueve. null — no tiene una suscripción activa o en prueba.

¿Puede mi app recargar a un cliente automáticamente?

MeterFlow le dice a tu app cuándo y cuánto; tu app cobra al cliente y luego concede los créditos. Dale a un endpoint de webhook un umbral de saldo bajo y recibirá balance.low cuando el saldo de un cliente baje de él — por una deducción o por uso medido — y balance.topped_up cuando una concesión lo vuelva a subir por encima. Define topup_amount en la suscripción del cliente y balance.low lo incluye como suggested_topup. Define max_topups_per_window y una concesión por encima de ese número en un mismo periodo se rechaza con un 409, así que un bucle en tu código no puede seguir recargando.

¿Puedo reservar créditos para un trabajo largo?

Sí, desde meterflow 0.11.0 (npm) / 0.6.0 (PyPI). credits.reserve() retiene parte del saldo de un cliente durante ttl_seconds — 5 minutos si no indicas otra cosa, un día como máximo. El saldo no se mueve, pero nada más puede gastar lo retenido: un credits.deduct(), el uso medido, un check() que cobraría y otra retención ven solo los créditos disponibles, el saldo menos lo retenido. Al terminar el trabajo, credits.confirmReservation(id, { amount }) toma toda la retención o parte de ella como una deducción normal en el registro y libera el resto, y credits.releaseReservation(id) la libera entera; una retención olvidada se libera sola al caducar. credits.balance() muestra reserved y available junto al saldo, y los créditos retenidos también cuentan para el tope de gasto.

Muestra a tus clientes su saldo

La página de saldo alojada para un cliente: el saldo con el botón Buy more, el plan con lo que queda de cada cuota y las últimas líneas del registro

MeterFlow aloja una página que muestra a uno de tus clientes sus propios créditos: el saldo, las últimas líneas del registro que lo forman, el plan en el que está con lo que queda de cada allowance medida, y lo que usó fuera del plan. No tienes que construirla ni alojarla — tu servidor le da al cliente un enlace.

Cómo llega un cliente 1. Tu app muestra un botón — “Tus créditos” — que llama a tu servidor. 2. Tu servidor pide a MeterFlow un enlace y envía al cliente a link.url. El enlace lleva su propio token de corta duración, así que tu clave API nunca sale de tu servidor. En Python es client.portal.create_session(…), con los mismos campos. 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 abre topup_url — tu propia página de pago, tal como la escribiste, sin nada añadido. Es opcional: sin topup_url, ni en el enlace ni en los valores por defecto del proyecto, la página no tiene botón Buy more. ← Back lleva a return_url, opcional del mismo modo. 4. MeterFlow nunca cobra el pago: cuando tu checkout informa de uno, tu servidor llama a credits.grant() y la página muestra el nuevo saldo.
  • El enlace

    Dura 60 minutos salvo que indiques expires_in_minutes — 24 horas como máximo — y no se puede retirar antes. Abre la página de un solo cliente, de solo lectura: no puede cambiar nada ni mostrar a otro cliente. Un enlace creado con una clave de prueba (mf_test_…) muestra datos de prueba, bajo una etiqueta Test data.

  • Tu imagen

    Abre un proyecto → Portal: el nombre de tu empresa, el logo, el tema claro / oscuro / automático, los colores y el radio de las esquinas, y los valores por defecto — URL de Buy more, URL de Back y duración — para los enlaces que no los indican. Una casilla aplica la imagen a todos los proyectos de la organización.

  • Un enlace a mano

    En la tabla Customers, la acción de fila Create a portal link crea un enlace para ese cliente sin código — igual que Portal link en su pestaña Credits.

Registrar evento de uso concepto clave

Un evento de uso = “este cliente acaba de hacer esta cosa, en esta cantidad.” En producción, tu aplicación los envía por el SDK automáticamente, miles de veces al día; el diálogo existe para inyectar uno a mano, para pruebas y demostraciones.

📍 Abre un proyecto → Usage → busca un cliente → “Record event”

  • Event name *

    Debe coincidir exactamente con el nombre de evento de un meter existente y activo en este proyecto (distingue mayúsculas). Esa coincidencia es cómo MeterFlow sabe a qué contador alimenta este evento. Sin meter coincidente → la API rechaza el evento con un 404 y no se guarda nada. Consulta la página Meters para la grafía exacta.

  • Customer ID *

    Cuál de tus clientes lo hizo — la misma cadena de ID libre usada en suscripciones y créditos. La coherencia lo es todo: user-842 y USER-842 son dos clientes distintos.

  • Value

    La cantidad — opcional. Si la omites, un meter Sum, Max o Min la lee de la propiedad del evento que nombra su campo de agregación (tu app la envía en properties); si no, el evento cuenta 1. Su significado depende de la agregación del meter: en un meter Count el valor se ignora (cada evento cuenta como una ocurrencia); en Sum es la cantidad a sumar (42 segundos, 1 300 tokens); en Max/Min es la medida que se compara; un meter Unique count cuenta los valores distintos de su campo de agregación.

Qué pasa al pulsar “Record” — el recorrido completo1. El nombre de evento se empareja con un meter — p. ej. video.rendered → “Video render seconds”. 2. El evento se guarda permanentemente (en bruto — la agregación ocurre después, al leer). 3. En segundo plano, MeterFlow comprueba si el cliente tiene una suscripción activa y si ese plan tiene un límite sobre este meter. 4. Si el límite es Metered, las unidades por encima de las incluidas se cobran a la tarifa de exceso del saldo de créditos del cliente y se escribe una línea en el libro — hasta el tope de gasto del periodo, si la suscripción tiene uno; si es Hard o Soft y este evento es el primero en cruzar las unidades incluidas en el periodo, el webhook limit.reached se dispara una vez. Aquí el evento nunca se rechaza — rechazar es trabajo de check(), en tu app. 5. El resumen de uso que ves en esta página se recalcula desde los eventos en bruto usando el tipo de agregación del meter.
Registré un evento y recibí un error — ¿por qué?

Casi siempre es el nombre de evento: no coincide exactamente con ningún meter activo de este proyecto. El error lo dice literalmente — “No active meter found for event '…' in this project.” Copia el nombre de evento desde la página Meters en lugar de reescribirlo. Recuerda también que los meters son por proyecto: un meter de otro proyecto no cuenta.

Si mi app reintenta una petición, ¿el evento se contará dos veces?

No, si usas el SDK correctamente: cada escritura acepta una clave de idempotencia — una etiqueta única para “esta acción concreta”. Si la misma clave llega dos veces (un reintento tras un fallo de red), MeterFlow la reconoce y devuelve el resultado original en lugar de guardar un duplicado. El diálogo manual no la envía, así que pulsar Record dos veces a mano sí crea dos eventos.

¿Necesito un evento por cada llamada a la API?

No — y normalmente no deberías. Value es una cantidad, y un meter Sum suma esas cantidades: un solo evento con valor 1 300 es un evento frente al límite mensual de tu plan y 1 300 unidades en el meter. Un evento por llamada a la API es lo que agota un plan: 1 000 usuarios con 100 llamadas al día son unos 3 millones de eventos al mes.

Agrega dentro de tu propia aplicación durante una ventana que pudieras permitirte perder si se cayera — una petición, un trabajo, un minuto — y registra después un único evento con el total. Enviarlos en batch no es lo mismo: un batch de 100 ahorra peticiones HTTP, pero cada evento sigue siendo su propio registro y sigue contando.

Esto sirve para meters Sum. Un meter Count ignora el valor y cuenta ocurrencias, así que allí cada ocurrencia sí necesita su propio evento. En cualquier caso no cambia la factura de nadie: un límite Metered cobra por unidad.

¿Puedo registrar un uso que ocurrió hace tiempo?

Solo dentro de cinco minutos. El timestamp de un evento puede estar como mucho 5 minutos en el pasado y 60 segundos en el futuro; fuera de esa ventana la API lo rechaza con un 422 y no guarda nada. Si omites timestamp, el evento lleva la hora en que llega. Registra el uso mientras ocurre: un uso más antiguo no se puede cargar después.

Nuevo webhook notificaciones

Un webhook es una URL en tu servidor a la que MeterFlow llama cuando pasa algo en tu proyecto — créditos concedidos, un límite alcanzado, un saldo que se agota. Cada llamada va firmada y se reintenta si tu servidor no responde.

📍 Abre un proyecto → Webhooks → el botón en la cabecera de la tabla

  • Endpoint URL *

    Adónde envía MeterFlow los eventos, p. ej. https://api.acme.dev/meterflow.

  • Events to deliver

    De qué eventos se entera este endpoint: usage.recorded, credit.granted, credit.deducted (una deducción, o un uso Metered cobrado — su transaction_type indica cuál), subscription.created, .updated, .renewed y .canceled, limit.reached, cap.reached, balance.exhausted, y los dos de abajo.

  • Low balance threshold

    Un saldo, en créditos. Defínelo y el endpoint también recibe balance.low cuando el saldo de un cliente baja de él y balance.topped_up cuando vuelve a superarlo; bórralo y ambos se detienen. Los dos eventos llegan y se van con el umbral, porque sin una línea no se puede avisar a un endpoint de que se cruzó.

Desde tu códigoTu app puede leer sus endpoints y sus recibos de entrega con el SDK, para saber si un evento llegó: webhooks.list(), webhooks.deliveries(id) para los 100 más recientes, y webhooks.deliveryPage(id) (en Python delivery_page) para cada intento, una página cada vez, empezando por el más reciente. El registro de entregas del panel se pagina igual. Crear y cambiar endpoints sigue aquí, en el panel.

Conecta tu proveedor de pagos tu facturación

Si tus clientes te pagan a través de Paddle, Polar, Lemon Squeezy, Chargebee o Razorpay, un conector deja que esa cuenta dirija MeterFlow: tu proveedor llama a MeterFlow en cada cambio de suscripción y cada pago, y la suscripción o la concesión de créditos correspondiente aparece aquí — sin código en tu app.

📍 Abre un proyecto → Connectors → el botón en la cabecera de la tabla

  • Provider *

    Con cuál de los cinco te pagan tus clientes.

  • Which of your accounts

    Live — la cuenta de producción de tu proveedor, que escribe datos live; Test — su sandbox, que escribe datos de prueba. Un conector por proveedor y cuenta.

  • Signing secret *

    El secreto con el que tu proveedor firma sus webhooks — para Chargebee, que no firma nada, el usuario y la contraseña que envía en su lugar. Se comprueba en cada llamada y nunca se vuelve a mostrar: la tabla solo enseña sus cuatro últimos caracteres.

Una vez creado

  • La URL del webhook

    Se muestra en cuanto se crea el conector: pégala en los ajustes de webhooks de tu proveedor.

  • Asignaciones precio → plan

    Qué precio de tu proveedor — un producto en Polar, una variante en Lemon Squeezy, un plan en Chargebee y Razorpay — pone a un cliente en cuál de tus planes. Un evento de un precio sin asignación se registra y no cambia nada.

  • Registro de entregas

    Cada evento que recibió el conector, con lo que hizo en una frase: qué se aplicó y por qué se ignoró el resto.

Miembros e invitaciones acceso del equipo

La página Members de tu organización lista quién pertenece a ella — con su rol y quién lo invitó — y las invitaciones aún pendientes. Un owner o un admin invita por email; la persona todavía no necesita una cuenta de MeterFlow.

📍 Members en la barra lateral, junto a Billing → “Invite member” (también como acción de fila en las organizaciones del Dashboard)

  • Email *

    Adónde va la invitación. MeterFlow envía un enlace que funciona una vez, durante 7 días, solo para esa dirección: la persona lo abre y se une — desde su cuenta, o creando una a través del enlace.

  • Role

    Admin — ajustes de la organización, invitaciones, claves API, webhooks, conectores, proyectos y facturación. Member — quien trabaja a diario: meters, planes y las páginas Subscriptions, Usage y de cliente. Viewer — solo lectura. A propósito no hay opción “owner”: la propiedad no se entrega con una invitación.

  • Invitaciones pendientes

    Aparecen en la página Members hasta que se aceptan, se revocan o caducan. Revoke desactiva el enlace al instante.

  • Change role · Remove

    En la fila de cada miembro, para owners y admins. La membresía del owner y la tuya no se pueden cambiar ahí. Quitar a alguien le retira el acceso; su cuenta, y lo que creó, se quedan.

EjemploInvitas a dana@acme.dev como Viewer para que el equipo de finanzas pueda observar el uso y los saldos sin poder cambiar los precios.
↑