Meter
Intermedia usage, billed straight into ConnectWise.
Billing automation that moves telecom usage into customer invoices, replacing manual reconciliation.
Who it helps: The MSP running Meter uses it to make Intermedia-to-ConnectWise billing practical. Without it, an operator re-keyed line items account by account.
At a glance
- language
- Python 3.11 (FastAPI), React 18 (TypeScript)
- sync engine
- 27 modules, idempotent ConnectWise sync
- ingest
- Selenium (Intermedia exposes no billing API)
- deploy
- Fly.io, 2-process (app + scheduler)
- ownership
- Requirements from operators through production
- in production
- An MSP billing cycle; longest-running system in the portfolio
- repo
- Private production repo; walkthrough available on a screen share
The problem
I built Meter for an MSP that was re-keying Intermedia line items into ConnectWise during each billing cycle. Charges could be misassigned and retries could create duplicates, so I made the cycle idempotent and added reconciliation against real customer billing.
How it’s built
-
Idempotency for a system with no safe retry
I designed DB-level per-account locks to stop concurrent syncs from double-billing. When ConnectWise returns an ambiguous 5xx, I query back within a 15-minute window and match a content hash to confirm whether the charge posted. The operator gets a confirmed outcome instead of a duplicate charge or a silent failure. -
Edge cases turned into code
ConnectWise rejects additions dated before an agreement billing start. An effective-date handler detects that exact error, fetches the start date, adjusts, and retries, removing a class of manual corrections. -
Preview-before-sync and reconciliation audits
Operators can diff what the system would send against what ConnectWise already holds, with comparison keys that normalize display-string drift so it does not surface as a false mismatch. The reconciliation audit exposed a tax-row identity bug across affected accounts.
By the numbers
- 202: Basis: December 2025 incident snapshot: 931 audited work items and 634 mismatching billing cycles. It describes audit blast radius, not steady-state volume.
Where this stands today
I maintain Meter in production as the portfolio’s longest-running system. A December 2025 reconciliation audit caught a tax-row identity bug. Its figures and basis are above.
The production repo stays private. I can walk you through the sync engine, scheduler, reconciliation path, and tests on a screen share. The public architecture post covers the retry decision.