An end-to-end walkthrough of a B2B SaaS platform: the architecture, data flows, feature system, live prototype and integration design that lets one company run its entire loan-processing operation on another’s infrastructure.
A purpose-built CRM that lets Zolve’s loan-processing team run entirely on Nbyula’s infrastructure.
Zolve — a well-funded cross-border neobank — needed a workbench for its loan-processing officers: a place to receive qualified leads, call and message borrowers, collect and validate documents, and hand complete dossiers to lender partners. Rather than build that internal tooling from scratch, the engagement delivers it as a B2B SaaS platform: Zolve owns the customer relationship and brand; Nbyula provides the CRM, per-lead Spaces, voice/messaging infrastructure and AI layer beneath it.
The picture below is the whole system in one frame — three parties, three integration seams, everything else internal to its own lane.
flowchart LR
subgraph Z["ZOLVE · customer-facing"]
Z3["Lead system · gen · qualify · bank-match"]
OFF["Officers + Managers"]
end
subgraph N["NBYULA · SaaS platform (the workbench)"]
G["API Gateway + Auth · SSO/JWT"]
CRM["CRM + per-lead Spaces"]
COM["Comms · SIP · WhatsApp · Email · IG"]
AI["AI layer · Anika · Audit · VAPI · OCR"]
D[("Data · MongoDB · Redis · S3")]
end
subgraph L["LENDERS · banks and NBFCs"]
L1["HDFC Credila · Avanse · ICICI · Prodigy"]
end
Z3 -->|"1 · POST /leads"| G
OFF -->|"log in (SSO)"| G
G --> CRM
CRM --> COM
CRM --> AI
CRM --> D
CRM -->|"2 · POST /applications"| L1
L1 -->|"3 · status webhook"| G
From a qualified lead entering the system to a sanctioned loan flowing back — the flow that works end to end.
Zolve pushes a qualified lead; Nbyula auto-creates a Space and assigns an officer; the officer calls, walks the borrower through lender options, and sends a lender-specific checklist. Documents are collected and validated; the AI agent chases whatever is missing. Once complete, the officer signs off and the dossier is pushed to the chosen lender, whose status flows back over a webhook.
flowchart LR
A["Lead in · POST /leads"] --> B["Space created · officer assigned"]
B --> C["Call · recorded + transcribed"]
C --> D["Lender options + checklist sent"]
D --> E{"Docs complete + valid?"}
E -->|"No · Anika chases"| D
E -->|"Yes"| F["Sign-off · POST /applications"]
F --> G["Lender sanctions · webhook back"]
Stateless services behind a gateway; a queue absorbs anything slow so the officer’s UI never blocks.
Officers use a React workbench served through a CDN. Requests pass an API gateway that terminates authentication (SSO → JWT) and role-based access, then fan out to services. Slow or bursty work — transcription, OCR, AI calls, outbound webhooks — is pushed to queues and handled by background workers.
flowchart TB
U["Officers / Managers · React SPA"] --> CDN["CDN + WAF"]
CDN --> GW["API Gateway · SSO/JWT · RBAC · rate-limit"]
GW --> S_CRM["CRM + Spaces service"]
GW --> S_COM["Comms service · SIP/WA/Email/IG"]
GW --> S_AI["AI orchestration service"]
GW --> S_DOC["Docs + OCR service"]
S_CRM --> Q["Queues · SQS"]
S_COM --> Q
S_AI --> Q
S_DOC --> Q
Q --> WK["Background workers · transcription · OCR · AI · webhooks"]
S_CRM --> DB[("MongoDB")]
S_CRM --> RC[("Redis · sessions + SLA timers")]
WK --> DB
WK --> S3[("S3 · recordings + documents")]
S3 --> CDN2["Signed-URL delivery"]
React SPA + CDN — the officer/manager workbench and per-lead Spaces.
Independently scalable CRM, comms, AI and docs services behind one gateway.
MongoDB for state, Redis for hot data + SLA timers, S3 for encrypted media.
One codebase, two topologies — the commercial fork is a deployment choice, not a rebuild.
On the shared tier, every record is tenant-scoped and the filter is enforced below the API via the JWT, so cross-tenant reads are impossible. The optional dedicated tier gives Zolve its own database, storage, VPC and branded subdomain — physical isolation and full white-label — with the same application code.
flowchart LR
subgraph SH["Shared multi-tenant · included ($19.99/seat)"]
direction TB
APP["Shared app cluster"]
JWT["JWT carries tenant_id=zolve"] -.->|"auto-filters every query"| APP
APP --> DB[("Shared MongoDB · every doc carries tenant_id")]
APP --> S3S[("Shared S3 · tenant-prefixed keys")]
end
subgraph DED["Dedicated white-label · optional (+$300/mo)"]
direction TB
CDN2["crm.zolve.com + own SSL / brand"] --> APP2["Zolve-only app in dedicated VPC"]
APP2 --> DB2[("Zolve-only MongoDB")]
APP2 --> S3D[("Zolve-only S3 bucket")]
end
Twelve capabilities, all live in production, grouped into four working domains.
sequenceDiagram
autonumber
participant O as Officer (in Space)
participant APP as Nbyula app
participant SIP as SIP trunk
participant B as Borrower
participant S3 as Recording vault (S3)
participant W as Transcription worker
O->>APP: Click "Call" in lead Space
APP->>SIP: Originate · caller-ID "Zolve"
SIP->>B: Rings borrower
B-->>SIP: Answers
SIP-->>O: Two-way audio
SIP->>S3: Stream recording
S3->>W: Queue audio when call ends
W-->>APP: Transcript + highlights on lead timeline
flowchart LR
CK["Checklist in Space"] --> UP["Borrower uploads · any channel"]
UP --> OCR["OCR + type validation"]
OCR --> V{"Valid + complete?"}
V -->|"No · Anika re-requests"| UP
V -->|"Yes"| SG["Officer sign-off"]
An orchestrator that delegates, an auditor that watches, and metering that keeps it honest.
Anika is a tool-using LLM planner: an officer delegates in plain language and Anika dispatches scoped sub-agents against a fixed, permission-checked tool API. A separate audit agent reviews every call for compliance. Anika and audit are free; only metered actions (an AI voice call, an AI text) emit billable usage events.
flowchart TB
OF["Officer · 'chase docs from Riya'"] --> AN["Anika orchestrator · LLM planner"]
AN --> T1["Qualification sub-agent"]
AN --> T2["Doc-follow-up sub-agent"]
AN --> T3["Scheduling sub-agent"]
AN --> T4["Outbound-call sub-agent · VAPI"]
T1 --> TOOLS["Permission-checked tool API"]
T2 --> TOOLS
T3 --> TOOLS
T4 --> TOOLS
TOOLS --> SP[("Actions land in lead Space + timeline")]
T4 --> MET["Usage event · metered + billable"]
CALL["Every call transcript"] --> AUD["AI audit agent · compliance verdict"]
AUD --> FEED["Manager daily flagged-call feed"]
Everything Zolve’s engineers build against — two APIs and one webhook, all signed and idempotent.
sequenceDiagram
autonumber
participant ZL as Zolve lead system
participant GW as Nbyula gateway
participant CRM as CRM service
participant SP as Spaces service
ZL->>GW: POST /leads · HMAC-signed · idempotency-key
GW->>GW: Verify signature + tenant
GW->>CRM: Create lead · tenant_id=zolve
CRM->>SP: Auto-create per-lead Space
CRM->>CRM: Assign officer + tag stage
CRM-->>ZL: 201 · lead_id + space_url
sequenceDiagram
autonumber
participant OF as Officer
participant CRM as Nbyula CRM
participant LN as Lender CRM
participant GW as Nbyula webhook endpoint
OF->>CRM: Sign off · all docs validated
CRM->>LN: POST /applications · dossier + docs
LN-->>CRM: 202 Accepted · application_ref
LN->>GW: status webhook · sanction / disbursal
GW->>CRM: Update stage + timeline
CRM-->>OF: Stage advances · notification
Not a mockup: a live CRM dashboard driven by real leads, real call history and real Spaces.
To prove the platform works, the prototype dashboard is wired to production data. It shows the real leads currently assigned to two loan advisors, computes each borrower’s call metrics from actual SIP / AI-dialer history, and deep-links “Open Space” straight to that borrower’s live workspace. The diagram shows how the dashboard is assembled from four production collections.
flowchart LR
subgraph SRC["Nbyula production data · MongoDB"]
C1["counselor_lead_relation · advisor → leads"]
C2["call_history · every SIP / AI call"]
C3["leads_info · name + contact"]
C4["conversations · per-lead Space"]
end
C1 --> AGG["Aggregate · leads per advisor + call stats"]
C2 --> AGG
C3 --> AGG
AGG --> DASH["CRM dashboard · attempts · connected · connect-rate · established"]
C4 --> LINK["Space deep-link per lead"]
LINK --> DASH
DASH --> SPACE["Open Space → nbyula.com/chat/{id}"]
One flat per-seat price, everything included; usage-based AI; optional dedicated infra.
| Line | Basis | Detail |
|---|---|---|
| Per seat / month | $19.99 · all-inclusive | Full platform, unlimited human SIP + WhatsApp calls, recording, transcription, storage, support — on shared infra |
| One-time setup & build | Free | Config, lead-intake API integration, lender connectors, migration, onboarding, QA |
| Dedicated infra + white-label | +$300 / month · optional | Separate DB + storage + VPC, branded subdomain, WhatsApp Business, monitoring |
| AI usage | Metered · pay-as-you-go | AI voice / AI text billed only when used; Anika + AI audit always free |
The engagement produced a complete, self-contained decision package — not a slide deck.
A four-tab web proposal: architecture & scope, the full platform-feature showcase with clickable live demos, the working CRM prototype, and pricing — all self-contained and brand-built.
The engineering companion: reference stack, tenancy model, per-feature designs and the two integration contracts, with diagrams for a walkthrough with Zolve’s engineering team.
A grounded case for buying over building: the hidden subsystem complexity, effort model, and the opportunity-cost argument tailored to Zolve’s funding and roadmap.
A real-data dashboard of leads assigned to two advisors, with call metrics computed from production records and Space deep-links that open genuine borrower workspaces.
flowchart TB
PROB["Zolve · build vs buy internal loan-ops tooling"] --> DECK["Interactive proposal deck · 4 tabs"]
DECK --> ARCH["Architecture brief · engineering depth"]
DECK --> BVB["Build-vs-buy · the commercial case"]
DECK --> PROTO["Live CRM prototype · real data"]
ARCH --> CALL["Engineering walkthrough"]
BVB --> CALL
PROTO --> CALL
CALL --> SIGN["Decision · adopt the platform"]