Skip to content
FluxMeter
中文

Customer stories

Typical user types and how they integrate FluxMeter Lite — pre-request checks, hierarchy reserve, soft alerts, and billing queries without a warehouse.

AI API infrastructure

TokenBridge

Know if a user still has quota before every LLM call — not when reconciling at month end.

Li Ming · Backend lead

「We sell token packs but the gateway kept forwarding after balance hit zero. One user ran $2,000 of Opus on our dime — Stripe settled T+1, too late to block.」

Challenge

Prepaid token resale with multi-model pricing. Balance lived in a business DB, async from real token burn. Retries caused double-charge disputes.

How they integrate

  1. 1 Deploy Lite (make demo) — Redis + API, no Flink required.
  2. 2 On signup: POST /budget/{userId} with max_rpm. On recharge: POST /budget/{userId}/package.
  3. 3 Optional: POST /budget/{userId}/webhook for BUDGET_WARN at 70%/90% spent (v2.7 Lite).
  4. 4 Optional (v2.8): POST /admin/customers/{id}/apikeys/{key_id}/budget for per-key limits.
  5. 5 Hook 1 (sync): GET /budget/{userId}/check?estimated_cost_usd=… before forwarding to upstream.
  6. 6 If allowed: false → return HTTP 402. If true: call OpenAI / DeepSeek / Qwen, then Hook 2.
  7. 7 Hook 2 (async): POST /ingest with customerId, modelId, tokens, eventId=upstream id for idempotency.
  8. 8 Usage center: proxy GET /usage/customer/{id}/period|day|model/* — do not expose Admin Key to browsers.

Key APIs

  • Pre-flight gate GET /budget/{id}/check
  • Soft alerts POST /budget/{id}/webhook
  • Per-key budget POST /admin/customers/{id}/apikeys/{key_id}/budget
  • Token package GET /budget/{id}/package
  • Post-call metering POST /ingest
  • Developer dashboard GET /usage/customer/{id}/period/{YYYY-MM}

ID mapping

customerId = user_{uuid} (1:1 with your user table). eventId = upstream request id (e.g. chatcmpl-xxx) for dedup.

bash
# Hook 1 — before every upstream LLM call
curl "localhost:8000/budget/user_wang/check?estimated_cost_usd=0.03"
# → allowed: false → return HTTP 402 to developer

# Optional (v2.8): per-key API budget on customer keys
# POST /admin/customers/{id}/apikeys/{key_id}/budget

# Hook 2 — after upstream response (async OK)
curl -X POST localhost:8000/ingest \
  -H 'Content-Type: application/json' \
  -d '{"customerId":"user_wang","modelId":"gpt-4o","inputTokens":500,"outputTokens":150,"eventId":"chatcmpl-abc"}'

# Soft alerts (v2.7 Lite) — BUDGET_WARN at 70%/90% spent
curl -X POST localhost:8000/budget/user_wang/webhook \
  -d '{"webhook_url":"https://api.example.com/hooks/fluxmeter"}'

# On recharge — token package
curl -X POST localhost:8000/budget/user_wang/package \
  -d '{"tokens": 10000000}'

Outcome

Zero platform overdraft losses. Soft alerts before hard cutoff. Developers self-serve day/month/model usage. Gateway adds two hooks — typically live in 3–4 weeks.

Live streaming + AIGC

ClipLive

One live stream, one clip pipeline — show creators and MCNs exactly what AI cost.

Chen Wei · AI pipeline lead

「Each clip hits 4–6 models. We only knew monthly totals. Creators asked “why did this clip cost $3?” and we had no answer.」

Challenge

Multi-step LLM pipelines (ASR → highlight → caption → cover). Costs scattered in logs. Jobs still ran after quota exhausted.

How they integrate

  1. 1 Define IDs: customerId = creator_{slug}, parentSpanId = job_{hex} per clip, optional sessionId = live_{date}_{room}.
  2. 2 Optional hard cap (v2.7): POST /budget/{creatorId}/cap with kind=span, id=job_id, max_cost_usd=…
  3. 3 Optional (v2.8): POST /budget/{creatorId}/reserve?estimated_cost_usd=…&parent_span_id=job_id before the run.
  4. 4 Before enqueue: GET /budget/{creatorId}/check?estimated_cost_usd=0.50&parent_span_id=job_id — reject if not allowed.
  5. 5 Each pipeline step after LLM call: async POST /ingest with parentSpanId = job_id, spanId = job_id:step (Lite aggregates spans from v2.6.2).
  6. 6 On job success: GET /usage/span/{job_id} → write cost_usd back to clip_jobs table and UI.
  7. 7 MCN month-end: GET /usage/customer/{creatorId}/period/{YYYY-MM} for settlement.
  8. 8 Non-token costs (render, CDN) stay in your DB — aggregate in your API for the full “clip total” line.

Key APIs

  • Job gate GET /budget/{id}/check
  • Per-clip cap POST /budget/{id}/cap
  • Hierarchy reserve POST /budget/{id}/reserve?parent_span_id=
  • Per-step metering POST /ingest (parentSpanId)
  • Clip cost card GET /usage/span/{job_id}
  • Creator monthly GET /usage/customer/{id}/period/{YYYY-MM}

ID mapping

customerId = creator_*. parentSpanId = job_* (one clip). spanId = job_*:asr|highlight|caption. sessionId = live_* optional for session rollups.

bash
# Optional hard cap per clip (v2.7)
curl -X POST localhost:8000/budget/creator_liwei/cap \
  -d '{"kind":"span","id":"job_a1b2c3","max_cost_usd":0.50}'

# Optional (v2.8): reserve holds customer + span cap pool together
curl -X POST "localhost:8000/budget/creator_liwei/reserve?estimated_cost_usd=0.50&parent_span_id=job_a1b2c3"

# Before enqueue — gate the clip job
curl "localhost:8000/budget/creator_liwei/check?estimated_cost_usd=0.50&parent_span_id=job_a1b2c3"

# Each pipeline step — same parentSpanId = job id (Lite + Full)
curl -X POST localhost:8000/ingest \
  -H 'Content-Type: application/json' \
  -d '{"customerId":"creator_liwei","modelId":"gpt-4o","parentSpanId":"job_a1b2c3","spanId":"job_a1b2c3:highlight","inputTokens":8000,"outputTokens":400}'

# After job completes — show cost in UI
curl localhost:8000/usage/span/job_a1b2c3
# → {cost_usd: 0.31, call_count: 4, total_tokens: 142000}

Outcome

100% of completed jobs show task-level cost_usd on Lite. Creator disputes down ~70%. Ingest is async — zero added latency on the clip hot path.

AI SaaS · Finance

MarginStack

Monthly board prep: which customers lose money and what pricing move closes the gap.

Sarah Kim · VP Finance

「We had Stripe revenue and a Grafana token dashboard — but no per-customer margin. The board asked why AI gross margin dropped 8 points and we spent a week in spreadsheets.」

Challenge

Usage-based AI SaaS with mixed plans. LLM cost attribution existed in logs; revenue lived in OpenMeter. Finance needed loss alerts and what-if before repricing.

How they integrate

  1. 1 Deploy Lite (make demo) — ingest LLM usage with customerId per tenant.
  2. 2 Overlay revenue: OpenMeter connector or POST /intelligence/revenue/{customer_id} each month.
  3. 3 Monthly close: GET /intelligence/unit-economics?period=YYYY-MM — flag negative-margin customers.
  4. 4 Explain deltas: GET /intelligence/root-cause?period=…&baseline_period=… for driver decomposition.
  5. 5 Before repricing: POST /intelligence/simulate for model-switch or token-grant scenarios.
  6. 6 Board export: GET /intelligence/report?format=markdown — paste into deck or Notion.

Key APIs

  • Unit economics GET /intelligence/unit-economics
  • Root cause GET /intelligence/root-cause
  • What-if POST /intelligence/simulate
  • Board report GET /intelligence/report?format=markdown
  • Revenue overlay POST /intelligence/revenue/{id}

ID mapping

customerId = tenant_* (1:1 with billing account). period = YYYY-MM UTC calendar month.

bash

Outcome

Finance gets per-customer margin and recommendations without a warehouse. Engineering keeps Pillar A guardrails on the same ingest path.

Pattern comparison

Dimension TokenBridge (API gateway) ClipLive (AIGC pipeline)
Core scenario Resell tokens via OpenAI-compatible API Async clip jobs after live streams
Critical path Sync /check on every request Check once before job enqueue
Primary ID customerId = downstream developer customerId = creator
Cost attribution Model / day / month rollups parentSpanId = one clip job
Billing shape Token packages + RPM limits Monthly USD quota / per-clip
Ingest pattern Sync check + async ingest Fully async ingest per step

Full 4-week implementation plans, acceptance checklists, and sequence diagrams: customer-stories-lite.md on GitHub

Quick Start — make demo