Mental health care in India is broken. There are roughly 0.3 psychiatrists per 100,000 people in the country, compared to 16 per 100,000 in the United States. Therapy sessions in urban metros run Rs.2,000 to Rs.5,000 per hour, pricing out the vast majority of the population. And even for those who can afford it, the stigma around seeking help remains a towering barrier. Millions of Indians are suffering in silence, not because solutions do not exist, but because they are inaccessible, unaffordable, or invisible.
That is the context in which a founding team approached CODERCOPS with an ambitious idea: build an anonymous, AI-powered mental wellness platform that connects anyone in distress with a trained listener within minutes, 24 hours a day, 7 days a week, at a fraction of traditional therapy costs. They called it The Venting Spot.
At CODERCOPS, we had 12 weeks to take this from concept to production. This is the story of how we did it, the architectural decisions we made, the problems we hit, and the results we achieved.
Building a mental wellness platform required balancing accessibility, privacy, and real-time communication
The Client Challenge
The founding team had a clear thesis. Mental wellness support does not always require a licensed therapist. Sometimes, people just need someone to listen. Research from the National Institute of Mental Health and Neurosciences (NIMHANS) shows that 60-70% of people seeking mental health support benefit significantly from active listening alone, without clinical intervention.
The product requirements were specific:
| Requirement | Detail |
|---|---|
| Availability | 24/7, no waiting rooms, no appointment scheduling |
| Anonymity | Users should never be required to share real identity |
| Affordability | Listener sessions at Rs.120/hr, therapist sessions at Rs.600/hr |
| Communication modes | Text chat, voice calls, and video calls |
| Matching | AI-powered mood-based matching with compatible listeners |
| Security | End-to-end encryption on all communications |
| Crisis support | Integration with crisis helplines for emergencies |
| Scale target | Support 500+ active listeners within 6 months |
The timeline was non-negotiable. The founding team had secured seed funding with a go-to-market date already committed to investors. We had 12 weeks from kickoff to production deployment.
Discovery and Planning: Weeks 1-2
We spent the first two weeks in deep discovery. Our team conducted stakeholder interviews with the founders, two consulting psychologists, and three individuals who had experience as peer listeners on other platforms. We mapped user journeys for three personas: the person in distress, the trained listener, and the licensed therapist.
The key insight from discovery was that the matching system would make or break the product. A user reaching out at 2 AM during a panic episode needs to be connected with a listener who has experience with anxiety, not someone trained only in relationship counseling. Speed of connection matters, but relevance of connection matters more.
We documented the full system architecture during the second week and presented three options to the client. The selected architecture looked like this:
+----------------------------------------------------------+
| CLIENT LAYER |
| |
| +-------------------+ +-------------------+ |
| | Next.js Web App | | React Native App | |
| | (SSR + ISR) | | (Future Phase) | |
| +--------+----------+ +-------------------+ |
| | |
+-----------+-----------------------------------------------+
|
| HTTPS / WSS
|
+-----------v-----------------------------------------------+
| API GATEWAY |
| Azure API Management |
| +------------------+ +------------------+ |
| | REST API (DRF) | | WebSocket (ASGI) | |
| +--------+---------+ +--------+---------+ |
| | | |
+-------------+---------------------+------------------------+
| |
+-------------v---------------------v------------------------+
| APPLICATION LAYER |
| |
| +---------------+ +---------------+ +----------------+ |
| | Django REST | | Django | | AI Matching | |
| | Framework | | Channels | | Service | |
| | (Auth, CRUD) | | (Real-time) | | (OpenAI API) | |
| +-------+-------+ +-------+-------+ +--------+-------+ |
| | | | |
+----------+------------------+--------------------+-----------+
| | |
+----------v------------------v--------------------v-----------+
| DATA LAYER |
| |
| +----------------+ +--------------+ +------------------+ |
| | PostgreSQL | | Redis | | Azure Blob | |
| | (Users, Matches| | (Sessions, | | Storage | |
| | Payments) | | Pub/Sub) | | (Encrypted Media) | |
| +----------------+ +--------------+ +------------------+ |
| |
+---------------------------------------------------------------+Why Next.js + Django + Azure
Every architecture decision was driven by specific constraints. Here is our reasoning:
Frontend: Next.js 14
The platform needed to serve two very different audiences: users seeking help (who need fast, empathetic, low-friction interfaces) and listeners/therapists (who need dashboard-style admin panels with scheduling and analytics). Next.js gave us server-side rendering for the user-facing pages (critical for SEO and first-load performance on low-bandwidth Indian mobile networks) and client-side interactivity for the real-time chat and dashboard views.
We used the App Router with React Server Components for static content (blog posts, FAQ, pricing pages) and client components for interactive features. This hybrid approach let us achieve a Lighthouse performance score of 94 on the landing page, even on 3G throttle simulations.
Backend: Django + Django REST Framework + Django Channels
We evaluated FastAPI, Express.js, and Django. Django won for three reasons:
- Django Channels provides native WebSocket support through ASGI, which we needed for real-time chat, typing indicators, and presence detection.
- Django REST Framework gave us a mature, well-tested serialization and authentication layer that would hold up under audit for health data compliance.
- Django's ORM and migration system meant we could iterate on our data models rapidly during the 12-week sprint without worrying about schema drift.
The trade-off was performance. Django is not the fastest framework. But for this use case, the WebSocket connections were the bottleneck, not REST API response times. And Django Channels running on Daphne behind Azure's load balancer handled our concurrency targets comfortably.
Cloud: Azure
The client had an existing Azure Enterprise Agreement, which made the cloud choice straightforward. We used:
- Azure App Service for the Django backend (Linux containers)
- Azure Database for PostgreSQL (managed, with automatic backups)
- Azure Cache for Redis (for WebSocket channel layers and session management)
- Azure Blob Storage (for encrypted media files from voice/video sessions)
- Azure API Management (rate limiting, API key management, analytics)
- Azure Key Vault (for encryption key management)
The AI-Powered Mood Matching System
This was the most technically challenging and most impactful feature we built. The matching system needed to accomplish two things simultaneously: understand what the user is feeling and find the most compatible available listener.
How It Works
When a user opens the app and requests a session, they go through a lightweight onboarding flow:
- Mood Selection: The user selects from a visual mood wheel (anxious, sad, angry, confused, lonely, overwhelmed, or custom text input).
- Context Input (Optional): A free-text field where the user can describe what they are going through. This is optional but dramatically improves matching quality.
- Preference Filters: Language preference, gender preference for listener, communication mode (text/voice/video).
The mood selection and context text are sent to our matching service, which makes an API call to OpenAI's GPT-4 model with a carefully engineered system prompt:
MATCHING_SYSTEM_PROMPT = """
You are a mental health triage assistant. Given a user's mood
selection and optional context, produce a structured assessment with:
1. primary_concern: One of [anxiety, depression, relationship,
grief, stress, loneliness, anger, trauma, self_esteem, other]
2. severity_estimate: 1-10 scale (10 = crisis level)
3. recommended_listener_tags: List of relevant expertise tags
4. crisis_flag: Boolean - true if user indicates self-harm,
suicidal ideation, or immediate danger
5. session_type_recommendation: "text", "voice", or "video"
IMPORTANT: If crisis_flag is true, the system will immediately
route to crisis support. Be conservative - flag anything that
could indicate risk.
Return ONLY valid JSON. No explanation.
"""The response feeds into a scoring algorithm that ranks available listeners:
def calculate_match_score(user_assessment, listener_profile):
score = 0.0
# Tag overlap (0-40 points)
user_tags = set(user_assessment['recommended_listener_tags'])
listener_tags = set(listener_profile['expertise_tags'])
overlap = len(user_tags & listener_tags)
score += (overlap / max(len(user_tags), 1)) * 40
# Language match (0-20 points)
if user_assessment.get('language') in listener_profile['languages']:
score += 20
# Rating and experience (0-20 points)
score += min(listener_profile['avg_rating'] * 4, 20)
# Availability and response time (0-10 points)
if listener_profile['is_online']:
score += 5
if listener_profile['avg_response_time_seconds'] < 30:
score += 5
elif listener_profile['avg_response_time_seconds'] < 60:
score += 3
# Severity-experience alignment (0-10 points)
severity = user_assessment['severity_estimate']
if severity >= 7 and listener_profile['sessions_completed'] > 200:
score += 10
elif severity >= 4 and listener_profile['sessions_completed'] > 50:
score += 7
else:
score += 4
return scoreThe system returns the top three matched listeners to the user, who can then choose one or accept the top recommendation. Average time from mood input to connection: 47 seconds.
Crisis Detection and Routing
We built a hard rule into the system: if the AI flags crisis_flag: true, the matching flow halts immediately. The user is shown a crisis support screen with:
- iCall helpline: 9152987821
- Vandrevala Foundation: 1860-2662-345
- AASRA: 91-22-27546669
- An option to still connect with a listener, but with the crisis support information prominently displayed and a disclaimer that listeners are not licensed crisis counselors.
This was non-negotiable. We tested the crisis detection with 500 synthetic inputs crafted by our consulting psychologists, and achieved a 98.4% recall rate on crisis-related content. The 1.6% miss rate consisted of extremely indirect references that even human reviewers disagreed on.
Real-Time Chat: WebSocket Implementation
The real-time communication layer was built on Django Channels with Redis as the channel layer backend. Here is the simplified architecture:
User A (Browser) User B (Browser)
| |
| WSS Connection | WSS Connection
| |
v v
+----+------------------------------------+----+
| Azure Load Balancer |
+----+------------------------------------+----+
| |
v v
+----+--------+ +--------+----+
| Daphne | | Daphne |
| Instance 1 | | Instance 2 |
+----+--------+ +--------+----+
| |
+----------------+-------------------+
|
v
+------+------+
| Redis |
| Pub/Sub |
| Channel |
| Layer |
+------+------+
|
v
+------+------+
| PostgreSQL |
| (Message |
| Archive) |
+-------------+Each chat session creates a unique channel group in Redis. When User A sends a message, it is published to the channel group, and Redis fans it out to all Daphne instances that have subscribers in that group. This means User A and User B can be connected to different Daphne instances and still communicate in real-time.
We implemented several features on top of basic messaging:
| Feature | Implementation |
|---|---|
| Typing indicators | Debounced WebSocket events, 300ms throttle |
| Read receipts | Server-side timestamp on message delivery confirmation |
| Presence detection | Heartbeat ping every 15 seconds, offline after 45 seconds |
| Message queueing | Redis-backed queue for offline message delivery |
| Reconnection | Exponential backoff with jitter, max 30-second retry interval |
Voice and Video Calls
For voice and video, we integrated with a WebRTC-based solution using Twilio Programmable Video. The signaling server runs on Django Channels (same WebSocket infrastructure), while the actual media streams are peer-to-peer through Twilio's TURN/STUN servers. This kept our infrastructure costs manageable while delivering reliable real-time audio and video, even on the patchy mobile networks common in tier-2 and tier-3 Indian cities.
Privacy and Encryption
Building a mental health platform means handling some of the most sensitive data imaginable. We treated security as a first-class architectural concern, not an afterthought.
End-to-End Encryption for Chat
All text messages are encrypted client-side before transmission using the Web Crypto API with AES-256-GCM. The encryption keys are derived from a Diffie-Hellman key exchange performed at session initiation. The server never sees plaintext messages. It stores and relays only encrypted blobs.
Key Exchange Flow:
User A Server User B
| | |
|-- Generate Key Pair --->| |
| |<-- Generate Key Pair --|
| | |
|<--- B's Public Key -----|--- A's Public Key -->|
| | |
|-- Derive Shared Key | Derive Shared Key --|
| (DH Exchange) | (DH Exchange) |
| | |
|== Encrypted Messages ==>|== Encrypted Relay ==>|
|<= Encrypted Messages ===|<= Encrypted Relay ==|The server stores encrypted message blobs in PostgreSQL with a configurable retention policy. By default, messages are purged after 30 days. Users can request immediate deletion at any time.
Anonymity Architecture
User accounts are created with only an email address (which can be a disposable email) and a self-chosen display name. No phone number, no real name, no government ID. Payment is processed through Razorpay, and we store only a hashed payment reference, not card details or UPI IDs.
Listener and therapist accounts, by contrast, require full KYC verification, because the platform needs to ensure they are qualified. But the identity of the listener is never exposed to the user beyond their display name and expertise tags.
Data Residency
All data is stored in Azure's Central India region (Pune). We do not replicate to regions outside India. This was a deliberate decision to comply with the Digital Personal Data Protection Act, 2023, and to assure users that their data does not leave the country.
The Tiered Pricing Model
The Venting Spot operates on a tiered model designed to make mental wellness support accessible while sustaining the platform:
| Tier | Provider | Rate | Qualifications |
|---|---|---|---|
| Listener | Trained peer listener | Rs.120/hr | 40-hour training program, certification |
| Senior Listener | Experienced peer listener | Rs.250/hr | 200+ sessions, 4.5+ rating, advanced training |
| Therapist | Licensed counselor | Rs.600/hr | RCI-registered, minimum 2 years clinical experience |
| Psychiatrist | Licensed psychiatrist | Rs.1,200/hr | MD Psychiatry, prescription authority |
For comparison, the average cost of a therapy session in Bangalore or Mumbai ranges from Rs.2,000 to Rs.5,000. The Venting Spot's most expensive tier is still 40-75% cheaper than market rates.
The platform takes a 30% commission on listener sessions and 20% on therapist/psychiatrist sessions. Listeners earn Rs.84/hr net, which is modest, but many listeners are psychology students or counseling trainees who value the supervised experience hours and platform-provided training.
We implemented Razorpay's subscription API for users who prefer monthly plans, and a pay-per-session model for casual users. The payment flow includes a 5-minute free trial for first-time users, which was the single biggest conversion driver in the first month post-launch.
Technical Challenges and How We Solved Them
Challenge 1: WebSocket Scaling on Azure
Django Channels with Redis Pub/Sub works well at moderate scale, but Azure App Service has a 4-minute idle timeout on WebSocket connections by default. We hit this during load testing when connections were dropping during quiet moments in chat sessions.
Solution: We implemented a server-side heartbeat that sends a ping frame every 30 seconds. On the client side, if no pong is received within 10 seconds, the client initiates a reconnection with exponential backoff. We also configured Azure's load balancer to use session affinity (sticky sessions) to reduce unnecessary reconnections.
Challenge 2: AI Matching Latency
The OpenAI API call for mood assessment added 1.5-3 seconds to the matching flow. For a user in distress, every second of waiting feels like an eternity.
Solution: We implemented a two-phase approach. Phase 1 uses a local rule-based matcher that returns an instant preliminary match based on mood selection alone (no AI). The user sees "Finding your listener..." with a preliminary match ready in under 2 seconds. Phase 2 runs the AI assessment in the background and, if the AI match differs significantly from the rule-based match, offers the user a "better match available" option within 10 seconds.
Challenge 3: Listener Availability at 3 AM
A 24/7 platform is only as good as its 3 AM availability. Early testing showed that listener density dropped to near-zero between 1 AM and 6 AM IST.
Solution: The founding team recruited listeners across multiple time zones, including Indian diaspora in the US, UK, and Middle East. We built a shift scheduling system that shows listeners their availability gaps and offers incentive bonuses (1.5x rate) for late-night and early-morning shifts. Within 3 months, the platform maintained a minimum of 12 active listeners at any given hour.
Challenge 4: Content Moderation
Anonymous platforms attract abuse. We needed to protect listeners from harassment without compromising user anonymity.
Solution: We implemented a three-layer moderation system:
- Real-time AI filter: Messages are scanned client-side (before encryption) against a locally cached list of slurs and threats. Flagged messages trigger a warning to the sender.
- Listener-initiated reports: Listeners can flag a session, which triggers a review by a human moderator who has access to the encrypted session (with the listener's decryption consent).
- Behavioral scoring: Repeated flags, rapid session disconnects, and negative listener feedback contribute to a trust score. Users below a threshold are temporarily suspended.
Deployment and DevOps
We used a CI/CD pipeline built on GitHub Actions:
GitHub Push (main)
|
v
+------+------+
| GitHub |
| Actions |
+------+------+
|
+--- Lint + Type Check (ESLint, mypy)
|
+--- Unit Tests (pytest, Jest)
|
+--- Integration Tests (Playwright)
|
+--- Build Docker Images
|
v
+------+------+ +-------------+
| Azure | | Azure |
| Container +--------->+ App Service |
| Registry | | (Staging) |
+-------------+ +------+------+
|
Manual Approval
|
v
+------+------+
| Azure |
| App Service |
| (Production)|
+-------------+Staging deployments are automatic on every push to main. Production deployments require manual approval in the GitHub Actions workflow, plus a Slack notification to the on-call engineer. Rollbacks are handled by redeploying the previous Docker image tag, which takes under 90 seconds.
Results: First 6 Months
The Venting Spot launched in production on schedule, 12 weeks after our kickoff. Here are the numbers from the first six months:
| Metric | Result |
|---|---|
| Registered users | 14,200+ |
| Active listeners | 520+ |
| Licensed therapists on platform | 38 |
| Sessions completed | 47,000+ |
| Average session duration | 42 minutes |
| Average match time | 47 seconds |
| User satisfaction (post-session) | 4.3/5.0 |
| Crisis interventions routed | 340+ |
| Platform uptime | 99.7% |
| Average API response time | 180ms |
| WebSocket message delivery rate | 99.94% |
The crisis intervention number is the one that matters most. Three hundred and forty people were connected with crisis support when the AI detected they might be at risk. We cannot quantify how many of those interventions prevented tragedy, but even one would justify the entire project.
Performance Benchmarks
We tracked frontend and backend performance rigorously throughout the build:
| Metric | Target | Achieved |
|---|---|---|
| Lighthouse Performance Score | >90 | 94 |
| First Contentful Paint | <1.5s | 1.1s |
| Time to Interactive | <3.0s | 2.4s |
| Core Web Vitals (LCP) | <2.5s | 1.8s |
| API P95 Response Time | <300ms | 220ms |
| WebSocket Connection Setup | <500ms | 340ms |
| Chat Message Delivery Latency | <200ms | 85ms |
Lessons Learned
1. AI is a force multiplier, not a replacement
The AI matching system dramatically improved the quality of listener-user pairings compared to random assignment. But we intentionally kept AI out of the actual conversation. The listeners are human. The empathy is human. The AI just helps the right human find the right human faster.
2. Privacy architecture must be designed upfront
Retrofitting end-to-end encryption into an existing chat system is a nightmare. We designed the encryption layer first and built the chat features on top of it. This added two weeks to the initial development timeline but saved us from a potentially catastrophic redesign later.
3. Accessibility is not optional for health platforms
We invested significant effort in WCAG 2.1 AA compliance, screen reader support, and high-contrast modes. For a mental wellness platform, accessibility is a moral imperative, not a nice-to-have. Users accessing the platform may be in states of high distress where cognitive load is already maxed out. Every unnecessary UI friction point is a potential dropout.
4. Hinglish and cultural context matter for NLP
Our initial mood classification model performed poorly on Indian English expressions. "Tension ho raha hai" (I am feeling tension), "mind kharab hai" (my mind is disturbed), and similar Hinglish expressions were misclassified until we added culturally specific examples to our prompts. If your users are in India, your NLP system must handle code-switching between English and Hindi.
5. The 12-week timeline was tight but achievable
We scoped ruthlessly. The mobile app was deferred to Phase 2. Advanced analytics dashboards for therapists were deferred. Multi-language support beyond English and Hindi was deferred. By being honest about what could ship in 12 weeks and what could not, we delivered a solid, reliable V1 on time.
What Comes Next
The Venting Spot team is now working on Phase 2 with us, which includes:
- React Native mobile apps for iOS and Android
- Multi-language support for Tamil, Telugu, Kannada, Bengali, and Marathi
- AI-powered session summaries for therapists (with user consent)
- Group support sessions for shared-experience communities
- Corporate wellness partnerships for employee mental health programs
Conclusion
Building The Venting Spot reinforced something we believe deeply at CODERCOPS: technology is most meaningful when it serves people who need it most. This project was not about flashy AI demos or bleeding-edge architecture. It was about getting a person in pain connected with a person who can help, safely, affordably, and fast.
The stack (Next.js, Django, Azure, OpenAI) was chosen for reliability, not novelty. The AI was applied surgically, to matching and crisis detection, not sprayed across the product. And the privacy architecture was designed to earn the trust of people sharing their most vulnerable moments.
If you are building a health tech product and want to talk through architecture decisions, security considerations, or AI integration strategies, reach out to us at CODERCOPS. We have been through the trenches and we are happy to share what we have learned.
Comments