The Challenge
NetSapiens provisions phone services. Rev.io bills customers. These systems don't synchronize automatically. An extension gets created in NetSapiens, someone opens a ticket to add it to billing, the ticket sits for a day, billing adds it manually. Except sometimes the ticket gets lost. Or the provisioning team forgets to create it. Or billing adds the wrong product.
The gaps compound over time. A customer adds 5 extensions in January, billing only invoices 3 of them. In March, someone ports 2 phone numbers out but billing keeps charging for them. A call center agent gets removed from the queue but stays on the invoice for 6 months. Each discrepancy is small individually, but across hundreds of customers and thousands of services, the leakage adds up.
Manual reconciliation doesn't scale, and it's stale before the audit is even done. Opening spreadsheets, exporting data from both systems, running VLOOKUP formulas — it takes hours, and for larger accounts that add and remove users on a weekly basis, the data is already out of date by the time you finish. Subtle issues like wrong product mappings or quantity mismatches get missed entirely. The team needed continuous automated auditing that surfaces every variance in real time.
The Approach
The platform runs three parallel audits: extensions, phone numbers, and call center agents. Each audit pulls data from NetSapiens and Rev.io, normalizes it into a common format, and compares the two datasets side by side. Discrepancies get flagged and categorized: unbilled items in NetSapiens, orphaned billing in Rev.io, quantity mismatches, product mapping errors.
Extensions audit compares NetSapiens users against Rev.io subscriptions. For each NetSapiens domain, the system fetches all active users and matches them against billing accounts. If a user exists in NetSapiens but has no corresponding billing subscription, it's flagged as unbilled. If a subscription exists but the user is deleted in NetSapiens, it's flagged as orphaned billing.
Phone number audit handles the complexity of number formatting. NetSapiens stores numbers in E.164 format. Rev.io sometimes stores them with or without country codes. The audit normalizes both datasets to 10-digit format for comparison, then flags mismatches.
Call center audit cross-references queue agents. NetSapiens tracks agents, supervisors, and office managers assigned to call queues. Rev.io bills for call center seats using product mappings (e.g., "Call Center Agent" SKU). The audit checks if every active agent in NetSapiens has a corresponding billing subscription. It also validates quantities: if a customer has 10 agents in NetSapiens but is only billed for 7 seats, that's a variance.
Audit Workflow
Ignore Lists & Exclusions
Not everything in NetSapiens should be billed. NetSapiens treats system resources as users — voicemail boxes, auto-attendants, routing users, internal extensions — but a business doesn't bill customers for those. Ignores are actually more important for extensions than phone numbers, because of how many non-billable system users exist in a typical deployment. The platform supports ignore lists at multiple levels:
- Extension-level ignores: Mark specific NetSapiens users as non-billable (voicemail boxes, routing users, test accounts, admin extensions)
- Number range ignores: Exclude entire ranges like toll-free numbers used for internal purposes
- Product mapping exclusions: Some Rev.io products don't have NetSapiens equivalents (e.g., one-time setup fees)
Ignoring an item doesn't make it disappear from the system. It right-sizes the account so the audit flags it as Good rather than throwing a variance. The ignore state persists in the database and syncs across audit runs. When someone marks an item as ignored, the variance count updates immediately via WebSocket. No refresh needed.
Data Flow Diagram
Technical Stack
- Frontend: React 18 with TypeScript, TanStack Query for server state management
- Backend: Express.js with Drizzle ORM for type-safe database queries
- Database: PostgreSQL for audit results, ignore lists, and historical tracking
- Caching: Redis with 15-minute TTL to avoid hammering external APIs
- Real-Time: WebSocket connections for instant UI updates when variances change
- Auth: Azure SAML for enterprise SSO with role-based access control
The Outcome
Every discrepancy surfaces automatically. The dashboard shows unbilled extensions, orphaned phone numbers, call center agent mismatches — everything that doesn't align between NetSapiens and Rev.io. Operations teams log in, see the variance count, and drill into specific domains to investigate. No spreadsheets, no manual exports, no VLOOKUP formulas.
The system is always live. Unlike spreadsheet audits that are stale before they're finished, this runs continuously. When someone creates 3 extensions in NetSapiens but billing only adds 2 subscriptions, the audit flags it within 15 minutes (cache refresh interval). The team sees the variance, creates the missing subscription, and the account flips to Good on the next sync. For larger accounts adding and removing users weekly, that real-time accuracy is the difference between catching leakage and not.
Ignore lists right-size accounts without cluttering the UI. System users like voicemail boxes and routing extensions get marked once and stay excluded permanently. Instead of throwing a variance, those accounts flag as Good. The ignore state persists in the database and syncs across all audit runs. WebSocket updates mean the variance count adjusts immediately when someone marks an item as ignored.
The platform enforces data consistency between systems that were never designed to talk to each other. NetSapiens handles provisioning, Rev.io handles billing, and the reconciliation engine ensures they stay aligned. When they drift, the system surfaces it in real time so the team can fix it before customers notice or revenue gets lost.