Platform Overview
AgentHR is an AI-powered HR hiring SaaS platform built by Diploy (Bisht Technologies Private Limited). It enables organizations to create AI agents for automated phone interviews, manage hiring pipelines, bulk-screen CVs, and conduct AI voice interviews at scale.
Core Capabilities
- AI Voice Agents — Create natural-language and flow-based conversational agents powered by ElevenLabs and OpenAI Realtime
- Multi-Engine Telephony — Twilio, Plivo, and SIP trunk support for outbound and inbound calls
- Campaign Engine — Bulk calling with timezone awareness, batch processing, retry logic, and scheduling
- HR Hiring Pipeline — Jobs, candidates, AI screening scores, interview sessions, and pipeline management
- Embeddable Widget — JavaScript widget for company websites enabling instant AI voice interviews
- Multi-Gateway Payments — Stripe, Razorpay, PayPal, Paystack, MercadoPago with credit system and invoicing
- Plugin Architecture — Extensible system with REST API, SIP Engine, and Team Management plugins
- Internationalization — 11+ languages with RTL support via i18next
Architecture Diagram
+-------------------+
| React Frontend |
| (Vite + shadcn) |
+--------+----------+
|
+--------v----------+
| Express Backend |
| (TypeScript) |
+--------+----------+
|
+------------------+------------------+
| | |
+-------v------+ +-------v------+ +-------v------+
| Drizzle | | Engines | | Plugins |
| PostgreSQL | | (Voice, Pay) | | (REST, SIP, |
| | | | | Team Mgmt) |
+--------------+ +------+-------+ +--------------+
|
+--------------+--------------+
| | |
+------v---+ +------v---+ +------v---+
| ElevenLabs| | Twilio | | Plivo |
| OpenAI | | | | |
+-----------+ +----------+ +----------+
Project Structure
AgentHR/
├── client/ # React frontend (Vite)
│ ├── src/
│ │ ├── pages/ # Route-based page components
│ │ ├── components/ # Reusable UI components
│ │ │ ├── ui/ # shadcn/ui base components
│ │ │ ├── landing/ # Public landing page components
│ │ │ └── admin/ # Admin panel components
│ │ ├── contexts/ # React contexts (auth, plugins)
│ │ ├── hooks/ # Custom React hooks
│ │ ├── lib/ # Utilities (API client, formatters)
│ │ └── i18n/ # Internationalization config
│ └── public/ # Static assets
├── server/ # Express backend
│ ├── routes/ # API route handlers
│ ├── services/ # Business logic layer
│ ├── engines/ # Specialized subsystems
│ │ ├── payment/ # Multi-gateway payment engine
│ │ ├── plivo/ # Plivo telephony engine
│ │ ├── twilio-openai/ # Twilio + OpenAI engine
│ │ ├── plivo-elevenlabs/# Plivo + ElevenLabs SIP engine
│ │ └── kyc/ # KYC verification engine
│ ├── infrastructure/ # DB pools, WebSocket, BullMQ
│ ├── middleware/ # Auth, rate limiting, logging
│ ├── storage/ # Data access layer (Drizzle)
│ ├── plugins/ # Plugin loader system
│ ├── demo-mode/ # Demo mode seeding & middleware
│ └── modules/ # Feature modules (widget, etc.)
├── shared/ # Shared between client & server
│ └── schema.ts # Drizzle ORM schema (source of truth)
├── plugins/ # Installable plugins
│ ├── rest-api/ # REST API plugin
│ ├── sip-engine/ # SIP Engine plugin
│ └── team-management/ # Team Management plugin
├── packages/ # Internal libraries
│ └── diploy-core/ # Shared errors, logging, response utils
├── scripts/ # Build, setup, deployment scripts
├── public/ # Server-served static files
├── .env.example # Environment variable template
├── drizzle.config.ts # Drizzle ORM configuration
├── vite.config.ts # Vite build configuration
├── tailwind.config.ts # Tailwind CSS configuration
└── package.json # Dependencies and scripts
Tech Stack
| Layer | Technology | Purpose |
| Frontend Framework | React 18 + TypeScript | UI rendering |
| Build Tool | Vite | Fast HMR, bundling |
| Routing | Wouter | Lightweight client routing |
| Data Fetching | TanStack Query v5 | Server state management |
| UI Components | shadcn/ui (Radix UI) | Accessible component library |
| Styling | Tailwind CSS | Utility-first CSS |
| Icons | Lucide React | Icon library |
| i18n | i18next + react-i18next | Internationalization |
| Backend | Node.js + Express | HTTP server |
| Language | TypeScript | Type safety |
| ORM | Drizzle ORM | Type-safe SQL |
| Database | PostgreSQL 14+ | Primary data store |
| Queue (Optional) | BullMQ + Redis | Background job processing |
| Auth | JWT + bcrypt | Authentication & hashing |
| Voice AI | ElevenLabs, OpenAI Realtime | Conversational AI |
| Telephony | Twilio, Plivo | Phone calls & SMS |
| Payments | Stripe, Razorpay, PayPal, Paystack, MercadoPago | Billing & subscriptions |
Database Schema
All tables are defined in shared/schema.ts using Drizzle ORM. The schema serves as the single source of truth for both backend queries and frontend types.
Core Tables
users
Central user accounts table. Every resource is owned by a user.
| Column | Type | Notes |
| id | varchar (PK, UUID) | Auto-generated |
| email | varchar (unique) | Login identifier |
| password | text | bcrypt hashed |
| name | text | Display name |
| role | text | "user", "admin", "super_admin" |
| planType | text | "free", "pro" |
| planExpiresAt | timestamp | Subscription expiry |
| credits | integer | Available credits balance |
| isActive | boolean | Account enabled |
| isDeleted | boolean | Soft delete flag |
| stripeCustomerId | text | Stripe customer link |
| kycStatus | text | KYC verification status |
| timezone | text | User timezone |
| createdAt, updatedAt | timestamp | Audit timestamps |
agents
AI agent configurations. Each agent belongs to a user and can be of type "incoming" or "flow".
| Column | Type | Notes |
| id | varchar (PK) | UUID |
| userId | varchar (FK → users) | Owner |
| name | text | Agent display name |
| type | text | "incoming" or "flow" |
| telephonyProvider | text | "twilio", "plivo", "elevenlabs" |
| systemPrompt | text | AI system instructions |
| firstMessage | text | Opening greeting |
| llmModel | text | e.g. "gpt-4o-mini" |
| temperature | real | LLM temperature 0-1 |
| language | text | Agent language code |
| elevenLabsAgentId | text | Remote ElevenLabs agent |
| elevenLabsVoiceId | text | Voice selection |
| transferEnabled | boolean | Allow human transfer |
| transferPhoneNumber | text | Transfer destination |
| flowId | varchar (FK → flows) | Linked flow for flow agents |
| knowledgeBaseIds | text[] | Attached KB document IDs |
| config | jsonb | Extended configuration |
| isActive | boolean | Enabled/disabled |
campaigns
Bulk outbound calling campaigns linked to an agent and phone number.
| Column | Type | Notes |
| id | varchar (PK) | UUID |
| userId | varchar (FK → users) | Owner |
| agentId | varchar (FK → agents) | AI agent to use |
| phoneNumberId | varchar (FK → phone_numbers) | Caller ID |
| name, goal, script | text | Campaign metadata |
| status | text | "pending", "active", "completed", "failed" |
| totalContacts | integer | Total leads |
| completedCalls, successfulCalls, failedCalls | integer | Progress counters |
| scheduledFor | timestamp | Delayed start time |
| scheduleTimezone | text | IANA timezone |
| retryEnabled | boolean | Auto-retry failed calls |
contacts
Leads within a campaign. Created by CSV upload.
| Column | Type | Notes |
| id | varchar (PK) | UUID |
| campaignId | varchar (FK → campaigns, CASCADE) | Parent campaign |
| firstName, lastName | text | Contact name |
| phone | text (NOT NULL) | Phone number |
| email | text | Optional email |
| customFields | jsonb | Extra CSV columns |
| status | text | "pending", "completed", "failed", "in_progress" |
calls
Record of every call made through the platform (Twilio/ElevenLabs).
| Column | Type | Notes |
| id | varchar (PK) | UUID |
| userId | varchar (FK → users) | Owner |
| campaignId | varchar (FK → campaigns) | Source campaign |
| contactId | varchar (FK → contacts) | Called contact |
| status | text | "initiated", "ringing", "in-progress", "completed", "failed" |
| callDirection | text | "outbound" or "inbound" |
| duration | integer | Seconds |
| transcript | text | Full conversation text |
| aiSummary | text | AI-generated summary |
| sentiment | text | Call sentiment analysis |
| recordingUrl | text | Audio recording link |
| wasTransferred | boolean | Transferred to human |
flows
Visual conversation flows built with React Flow editor.
| Column | Type | Notes |
| id | varchar (PK) | UUID |
| userId | varchar | Owner |
| name, description | text | Metadata |
| nodes | jsonb | React Flow node array |
| edges | jsonb | React Flow edge array |
| compiledSystemPrompt | text | Compiled LLM prompt |
| compiledStates | jsonb | State machine representation |
| compiledTools | jsonb | Function calling tools |
| isTemplate | boolean | System template flag |
HR Tables: jobs, candidates, interview_sessions, candidate_pipeline_history
| Table | Key Columns | Notes |
| jobs | id, userId (FK), agentId (FK), flowId (FK), title, department, location, type, salaryRange, status | Job postings with optional AI agent assignment |
| candidates | id, jobId (FK), userId (FK), firstName, lastName, email, phone, cvFilePath, cvText, status, aiScreeningScore, aiScreeningEvaluation | Applicants with AI-scored CVs |
| interview_sessions | id, userId, jobId (FK), candidateId (FK), callId (FK), status, overallScore, questionScores (jsonb), aiEvaluation, aiRecommendation | AI interview records with scoring |
| candidate_pipeline_history | id, candidateId (FK), jobId (FK), stage, notes, movedAt, movedBy | Kanban pipeline stage tracking |
Other Tables
| Table | Purpose |
| phone_numbers | Twilio phone numbers owned by users |
| incoming_connections | Phone number → agent mapping for inbound |
| incoming_agents | Dedicated inbound agent config |
| knowledge_base | RAG documents for agent context |
| credit_transactions | Credit purchase/deduction ledger |
| plans | Subscription tier definitions |
| website_widgets | Embeddable voice interview widgets |
| webhook_subscriptions | User-configured webhook endpoints |
| webhook_deliveries | Delivery log for webhook events |
| prompt_templates | Reusable AI prompt library |
| email_templates | Transactional email templates |
| global_settings | Platform-wide configuration KV store |
| seo_settings | SEO meta tags configuration |
| llm_models | Available LLM model definitions |
| eleven_labs_credentials | API key pool for ElevenLabs |
| openai_credentials | API key pool for OpenAI |
| plivo_credentials | Plivo telephony credentials |
| refresh_tokens | JWT refresh token store |
| otp_verifications | Email OTP tracking |
| notifications | In-app notification system |
| api_keys | REST API authentication keys |
| invoices | Generated PDF invoices |
| flow_executions | Runtime state for active flows |
| plivo_calls | Plivo-specific call records |
| twilio_openai_calls | Twilio+OpenAI call records |
| hr_calls | HR module call tracking |
Key Relationships
- Users own all primary resources: agents, campaigns, phone_numbers, flows, jobs, knowledge_base
- Agents belong to Users and link to ElevenLabs/OpenAI credentials
- Campaigns contain many Contacts and generate many Calls
- Contacts cascade-delete with their parent Campaign
- Calls link to Users, Campaigns, Contacts, and Agents
- Jobs have many Candidates, each with Pipeline History entries and Interview Sessions
- Flows are linked to Agents and track runtime via Flow Executions
Authentication & Authorization
Token Flow
Login Request (email + password)
│
▼
Validate credentials (bcrypt.compare)
│
▼
Generate Access Token (JWT, 15min expiry)
Generate Refresh Token (random 64-char, 30-day expiry)
│
├──► Access Token → Response body
└──► Refresh Token → HttpOnly Secure Cookie (SHA-256 hashed in DB)
On API Request:
Authorization: Bearer <access_token>
│
▼
authenticateToken middleware → verify JWT → attach userId + userRole
On Token Expiry:
POST /api/auth/refresh (cookie-based)
│
▼
Validate refresh token hash → Issue new access token
Role Hierarchy
| Role | Access Level | Description |
| user | User dashboard (/app/*) | Standard user with own agents, campaigns, billing |
| admin | Admin panel (/admin/*) + User dashboard | Full platform control: settings, user management, analytics. Primary admin role enforced by server middleware. |
| team_member | Permission-based (/app/*) | Organization member with granular RBAC permissions. Uses session tokens (not JWT). |
| admin_team_member | Permission-based (/admin/*) | Admin staff with section-level permissions (e.g., billing, users). Checked via requireAdminPermission middleware. |
The role field in the users table supports "user" and "admin". Admin-level access is enforced server-side via requireRole('admin') and checkAdminOrTeamMember middleware. Team members use separate 64-character hex session tokens with permission-based access control.
Middleware Chain
Request → Rate Limiter → authenticateToken → checkUserActive → requireRole / requireAdminPermission → Route Handler
| Middleware | File | Purpose |
authenticateToken | server/middleware/auth.ts | Validates JWT, attaches userId to request |
authenticateAnyToken | server/middleware/auth.ts | Accepts user JWT OR admin team session token |
checkUserActive | server/middleware/auth.ts | Ensures account is not suspended/deleted |
requireRole(role) | server/middleware/auth.ts | Checks user has specific role |
checkAdminOrTeamMember | server/middleware/admin-auth.ts | Validates admin or team member access |
requireAdminPermission(section, sub, action) | server/middleware/admin-auth.ts | Granular RBAC for admin team members |
checkActiveMembership | server/middleware/auth.ts | Requires active Pro subscription |
API Reference
Authentication
| Method | Path | Auth | Description |
| POST | /api/auth/send-otp | None | Send email verification OTP for registration |
| POST | /api/auth/verify-otp | None | Verify registration OTP |
| POST | /api/auth/register | None | Register new user account |
| POST | /api/auth/login | None | Login with email/password, returns JWT |
| POST | /api/auth/refresh | Cookie | Refresh access token using cookie |
| POST | /api/auth/logout | Cookie | Invalidate refresh token, clear cookie |
| POST | /api/auth/forgot-password/send-otp | None | Send password reset OTP |
| POST | /api/auth/forgot-password/reset | None | Reset password after OTP verification |
Agents
| Method | Path | Auth | Description |
| GET | /api/agents | JWT | List all user's agents |
| POST | /api/agents | JWT | Create new AI agent |
| GET | /api/agents/:id | JWT | Get agent details |
| PATCH | /api/agents/:id | JWT | Update agent configuration |
| DELETE | /api/agents/:id | JWT | Delete agent and remote resources |
Campaigns & Contacts
| Method | Path | Auth | Description |
| GET | /api/campaigns | JWT | List user's campaigns |
| POST | /api/campaigns | JWT | Create new campaign |
| GET | /api/campaigns/:id | JWT | Get campaign details |
| DELETE | /api/campaigns/:id | JWT | Delete campaign |
| POST | /api/campaigns/:id/contacts/upload | JWT | Upload CSV contacts |
| GET | /api/campaigns/:id/calls | JWT | List campaign calls |
| GET | /api/campaigns/:id/export | JWT | Export results as CSV |
| POST | /api/campaigns/:id/batch/cancel | JWT | Cancel running batch job |
Phone Numbers
| Method | Path | Auth | Description |
| GET | /api/phone-numbers | JWT | List owned + system pool numbers |
| GET | /api/phone-numbers/search | JWT | Search available Twilio numbers |
| POST | /api/phone-numbers/buy | JWT | Purchase number with credits |
| DELETE | /api/phone-numbers/:id | JWT | Release phone number |
Calls & Analytics
| Method | Path | Auth | Description |
| GET | /api/calls | JWT | List calls with pagination |
| GET | /api/calls/:id | JWT | Call details + transcript |
| GET | /api/calls/:id/recording | JWT | Download call recording |
| GET | /api/dashboard | JWT | Dashboard metrics |
| GET | /api/analytics | JWT | Time-series analytics |
| POST | /api/analytics/export-pdf | JWT | Generate PDF analytics report |
Billing & Subscriptions
| Method | Path | Auth | Description |
| GET | /api/plans | None | List subscription plans |
| GET | /api/subscriptions/my-subscription | JWT | Current subscription details |
| GET | /api/credits/transactions | JWT | Credit history |
| GET | /api/billing-profile | JWT | Get billing info |
| PUT | /api/billing-profile | JWT | Update billing info |
Admin Endpoints
| Method | Path | Auth | Description |
| GET | /api/admin/analytics | Admin | Platform-wide analytics |
| GET | /api/admin/settings | Admin | Get platform settings |
| POST | /api/admin/users/:id/credits | Admin | Add/deduct user credits |
| PATCH | /api/admin/users/:id/limits | Admin | Set user limits |
| GET | /api/admin/plugins | Admin | List installed plugins |
AI Agent System
Agents are the core unit of the platform. Each agent is an AI persona configured with voice, personality, and instructions.
Agent Types
| Type | Description | Use Case |
| Natural (Incoming) | LLM-powered free-form conversation | Inbound call handling, customer support |
| Flow | Visual flow editor with branching logic | Structured interviews, surveys, screenings |
Voice Engines
| Engine | Provider Stack | Key Feature |
| ElevenLabs Native | ElevenLabs Conversational AI + Twilio | Ultra-realistic voices, Batch API |
| OpenAI Realtime + Twilio | OpenAI Realtime API + Twilio | GPT-powered real-time conversation |
| OpenAI Realtime + Plivo | OpenAI Realtime API + Plivo | Alternative telephony provider |
| ElevenLabs SIP + Plivo | ElevenLabs + Plivo SIP Trunk | SIP-based integration |
Configuration Options
- Voice: ElevenLabs voice ID, stability, similarity boost, speed
- LLM: Model selection (gpt-4o-mini, gpt-realtime, etc.), temperature
- Behavior: System prompt, first message, language, max duration
- Transfer: Enable human transfer with phone number
- Knowledge Base: Attach documents for RAG context injection
Campaign Execution Engine
Execution Flow
Create Campaign → Upload CSV Contacts → Start Campaign
│
▼
CampaignExecutor validates:
- Agent exists and is configured
- Phone number assigned
- Contacts have valid phone numbers
- User has sufficient credits
│
▼
Route to engine based on telephonyProvider:
├── ElevenLabs → BatchCallingService (ElevenLabs Batch API)
├── Plivo → PlivoBatchCallingService (local concurrency)
└── Twilio → TwilioOpenAIBatchCallingService (local concurrency)
│
▼
Pre-create call records in DB (batch insert)
│
▼
Execute calls with concurrency control
│
▼
Webhooks update call status, transcript, duration
│
▼
Campaign marked "completed" when all contacts processed
Key Features
- Timezone Awareness:
scheduleTimezone field ensures calls happen within allowed hours
- Batch Processing: Contacts loaded in chunks of 500 to prevent memory exhaustion
- Concurrency Control: Global
campaign_batch_concurrency setting limits parallel calls
- Auto-Pause/Resume: Scheduler (30s interval) pauses campaigns outside allowed hours
- Retry Logic: Failed calls retry up to 24 times (hourly) via ElevenLabs migration engine
- BullMQ (Optional): Set
ENABLE_BULLMQ=true + REDIS_URL for distributed queue processing
Key Files
| File | Purpose |
server/services/campaign-executor.ts | Main orchestration and engine routing |
server/services/campaign-scheduler.ts | Timezone-aware scheduling and status polling |
server/services/batch-calling.ts | ElevenLabs Batch API wrapper |
server/infrastructure/bullmq/ | Redis-based distributed queue (optional) |
Flow Builder System
A visual conversation designer built on React Flow. Users create branching conversational logic using drag-and-drop nodes.
Node Types
- Start Node: Entry point with initial greeting
- Message Node: AI speaks a message
- Question Node: Ask a question and branch on response
- Condition Node: Logic branching (if/else)
- Transfer Node: Hand off to human agent
- End Node: Conversation termination
Flow Compilation
When saved, flows are compiled into executable state machines stored in compiledStates, compiledSystemPrompt, and compiledTools fields. The flow compilation is handled by server/services/elevenlabs-flow-compiler.ts (for ElevenLabs agents) and the flow agent service (server/services/flow-agent.ts), which convert visual nodes into LLM-compatible instructions.
Payment Infrastructure
Supported Gateways
| Gateway | Region | Currencies | Features |
| Stripe | Global | USD, EUR, GBP, +135 | Checkout Sessions, Subscriptions, Webhooks |
| Razorpay | India | INR | Orders, Subscriptions, UPI |
| PayPal | Global | USD, EUR, GBP, +20 | REST Orders, Billing Subscriptions |
| Paystack | Africa | NGN, GHS, ZAR, KES, USD | Transactions, Plans, Subscriptions |
| MercadoPago | Latin America | BRL, ARS, MXN, CLP, COP | Preferences, PreApproval Plans |
Credit System
- Credits are the platform's internal currency for telephony usage
- Purchases via any gateway award credits atomically using PostgreSQL advisory locks
- Deductions happen per-call with unique reference IDs to prevent double-charging
- Refunds automatically reverse credit awards if unspent
Invoice Generation
Uses pdfkit to generate branded PDF invoices after completed transactions. Stored in ./data/invoices/ and linked in the invoices table.
HR / Hiring Module
Workflow
Create Job Posting → Upload CVs / Receive Widget Applications
│
▼
AI CV Screening (score + evaluation)
│
▼
Candidates enter Pipeline (stages: Applied → Screening → Interview → Offer → Hired)
│
▼
Schedule AI Phone Interview (via campaign executor or widget callback)
│
▼
Interview Session recorded with scoring, evaluation, recommendation
│
▼
Move through pipeline stages → Hire or Reject
Key Features
- AI CV Screening: Automatic scoring of uploaded resumes against job requirements
- Pipeline Management: Kanban-style candidate tracking through hiring stages
- AI Interviews: Automated phone interviews with scoring and recommendations
- Hiring Widget: Embeddable 6-step application wizard with instant AI voice interviews
- Analytics: Hiring funnel metrics and conversion rates
Webhook System
Users can subscribe to platform events and receive real-time HTTP notifications.
- HMAC-SHA256 Verification: Every delivery is signed with the subscription's secret
- Automatic Retries: Failed deliveries retry with exponential backoff (up to 5 attempts)
- Events: call.completed, campaign.completed, candidate.applied, etc.
- Delivery Logging: Every attempt is recorded in
webhook_deliveries
Knowledge Base (RAG)
Users upload documents that get processed into chunks, embedded, and injected as context into AI agent conversations.
- Document Types: Text, URL, File upload (PDF, DOCX, TXT)
- Processing: Documents are sent to ElevenLabs Knowledge Base API for indexing
- Agent Linking: Multiple KB documents can be attached to a single agent via
knowledgeBaseIds
Client-Side Architecture
Component Structure
client/src/
├── App.tsx # Root component with routing and guards
├── pages/ # Route-based page components
│ ├── LandingPage.tsx # Public landing page
│ ├── LoginPage.tsx # Auth (login + register)
│ ├── Dashboard.tsx # User dashboard
│ ├── Agents.tsx # Agent management
│ ├── JobsPage.tsx # HR job listings
│ ├── CandidatesPage.tsx # Candidate management
│ ├── PipelinePage.tsx # Hiring pipeline
│ ├── FlowBuilderPage.tsx # Visual flow editor
│ ├── FlowsPage.tsx # Flow listing
│ ├── Billing.tsx # Subscription & credits
│ ├── Settings.tsx # User profile
│ ├── AdminDashboard.tsx # Admin panel
│ ├── AdminCampaignDetail.tsx
│ ├── InstallWizard.tsx # First-time setup
│ └── policies/ # Privacy, Terms, Cookies
├── components/
│ ├── ui/ # shadcn/ui primitives
│ ├── landing/ # Landing page sections
│ └── admin/ # Admin-specific components
├── contexts/
│ ├── plugin-registry.tsx # Runtime plugin UI injection
│ └── dynamic-languages.tsx # i18n dynamic loading
├── hooks/ # useToast, useAuth, etc.
├── lib/
│ ├── queryClient.ts # TanStack Query config
│ ├── auth-storage.ts # Token persistence
│ └── formatters.ts # Date, currency formatters
└── i18n/ # Translation files (11 languages)
Routing & Guards
Route Groups
| Prefix | Guard | Sidebar | Access |
/ (public) | None | None (public layout) | Everyone |
/app/* | UserGuard | AppSidebar | Authenticated users |
/app/* (team) | UserGuard | TeamMemberSidebar | Team members (permission-filtered) |
/admin/* | AdminGuard | AdminSidebar | Admin role users |
/admin/* (team) | AdminTeamGuard | AdminTeamMemberSidebar | Admin team members |
Guard Logic
- UserGuard: Validates user JWT or team member session. Redirects to
/login if invalid.
- AdminGuard: Validates user has
role: "admin". Redirects to /app if not admin.
- AdminTeamGuard: Validates admin team session token. Redirects to
/admin/team/login if invalid.
Pages Reference
Public Pages
| Route | Component | Description |
/ | LandingPage | Main marketing page |
/login | LoginPage | User authentication |
/register | LoginPage | User registration |
/features | FeaturesPage | Product features |
/pricing | PricingPage | Plans and pricing |
/use-cases | UseCasesPage | Use case examples |
/contact | Contact | Contact form |
/blog | Blog | Blog index |
/privacy | PrivacyPolicy | Privacy policy |
/terms | TermsOfService | Terms of service |
/team/login | TeamMemberLogin | Team member auth |
/install | InstallWizard | First-time setup wizard |
User Dashboard Pages (/app/*)
| Route | Component | Description |
/app | Dashboard | Main dashboard with metrics |
/app/jobs | JobsPage | Job listings management |
/app/candidates | CandidatesPage | Candidate management |
/app/pipeline | PipelinePage | Hiring pipeline view |
/app/cv-upload | CVUploadPage | Bulk CV upload |
/app/interviews | InterviewsPage | Interview management |
/app/analytics | HRAnalyticsPage | HR analytics |
/app/agents | Agents | AI Agent management |
/app/knowledge-base | KnowledgeBase | RAG document management |
/app/flows | FlowsPage | Automation flows list |
/app/flows/new | FlowBuilderPage | Create new flow |
/app/flows/:id | FlowBuilderPage | Edit existing flow |
/app/phone-numbers | PhoneNumbers | Phone number management |
/app/tools/widgets | WidgetsPage | Hiring widget configuration |
/app/billing | Billing | Subscription & credits |
/app/upgrade | Upgrade | Plan upgrade |
/app/settings | Settings | User profile settings |
Plugin System
Architecture
Plugins are self-contained extensions with their own backend routes, frontend UI, and database migrations.
plugins/
├── my-plugin/
│ ├── plugin.json # Manifest: metadata, entry points, DB requirements
│ ├── index.ts # Backend: Express route registration
│ ├── frontend/
│ │ └── index.tsx # Frontend: UI component registration
│ ├── dist/
│ │ └── bundle.js # Built frontend bundle
│ └── migrations/
│ └── 001_create_tables.sql
Lifecycle
- Discovery:
server/plugins/loader.ts scans /plugins for directories with plugin.json
- Enable Check: Reads
global_settings table for plugin_[name]_enabled = true
- Backend Registration: Imports and calls the
registerFunction from the manifest
- Frontend Loading:
PluginBootstrapper fetches /api/plugins/capabilities, downloads bundles
- UI Injection: Bundles call
window.__AGENTHR_PLUGIN_REGISTRY__ to register tabs and menu items
Plugin Management API
| Method | Path | Description |
| GET | /api/plugins/capabilities | List enabled plugins and bundle URLs |
| GET | /api/plugins/:name/bundle | Serve plugin frontend JS bundle |
| GET | /api/plugins/health | Plugin health diagnostics |
| GET | /api/admin/plugins | Admin: list all plugins with status |
REST API Plugin
Exposes platform data via authenticated REST endpoints with API key management and professional documentation.
| Endpoint Group | Path | Auth |
| Calls | /api/v1/calls | API Key |
| Campaigns | /api/v1/campaigns | API Key |
| Agents | /api/v1/agents | API Key |
| Contacts | /api/v1/contacts | API Key |
| Credits | /api/v1/credits | API Key |
| Analytics | /api/v1/analytics | API Key |
| Webhooks | /api/v1/webhooks | API Key |
| API Keys | /api/user/api-keys | JWT |
| Documentation | /api/docs | Public |
SIP Engine Plugin
Enables custom SIP trunk integration for voice calls, allowing users to bring their own telephony infrastructure.
| Endpoint | Auth | Purpose |
/api/sip/trunks | JWT | Manage SIP credentials |
/api/sip/phone-numbers | JWT | Import SIP phone numbers |
/api/admin/sip | Admin | Global SIP configuration |
/api/openai-sip/webhook | None | OpenAI SIP webhook handler |
Team Management Plugin
Adds RBAC (Role-Based Access Control) and multi-user sub-accounts for organizations.
| Endpoint | Auth | Purpose |
/api/team/auth | Public | Team member login |
/api/team/members | JWT | CRUD team members |
/api/team/roles | JWT | Custom role management |
/api/team/permissions | JWT | Permission configuration |
/api/admin/teams | Admin | Global team oversight |
/api/admin/team | Admin | Admin sub-admin management |
Development Setup
Prerequisites
- Node.js 18.x or 20.x
- PostgreSQL 14+
- npm 8+
- Redis (optional, for BullMQ)
Installation Steps
# 1. Extract the package
unzip AgentHR-v1.0.0-complete.zip
cd AgentHR-v1.0.0
# 2. Copy environment template
cp .env.example .env
# 3. Run setup (auto-generates SESSION_SECRET and JWT_SECRET)
npm run setup
# 4. Edit .env with your configuration
# - Database credentials
# - Twilio / ElevenLabs API keys
# - SMTP settings
# - Payment gateway keys (optional)
# 5. Install dependencies
npm install
# 6. Push database schema
npm run db:push
# 7. Seed system data (plans, models, templates, etc.)
npm run db:seed
# 8. Build plugins (if modifying plugin source)
npm run build:plugins
# 9. Build for production
npm run build
# 10. Start the application
bash scripts/production.sh start
Development Mode
# Start dev server with hot reload
npm run dev
# Server runs on http://localhost:5000
npm Scripts
| Script | Command | Description |
npm run dev | tsx server/index.ts | Development server with HMR |
npm run build | vite build && esbuild ... | Production build |
npm run db:push | drizzle-kit push | Sync schema to database |
npm run db:generate | drizzle-kit generate | Generate migrations |
npm run db:seed | tsx server/seed-all.ts | Seed system data |
npm run build:plugins | node scripts/build-plugins.js | Build plugin frontend bundles |
Environment Variables
Required
| Variable | Description | Example |
DATABASE_URL | PostgreSQL connection string | postgresql://user:pass@host:5432/db |
SESSION_SECRET | Session encryption key (64 chars) | Auto-generated by setup |
JWT_SECRET | JWT signing key (64 chars) | Auto-generated by setup |
APP_URL | Public application URL | https://agenthr.example.com |
APP_DOMAIN | Domain without protocol | agenthr.example.com |
PORT | Server port | 5000 |
Integrations
| Variable | Service | Required |
TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN | Twilio | For calling |
ELEVENLABS_API_KEY | ElevenLabs | For voice AI |
OPENAI_API_KEY | OpenAI | For OpenAI Realtime |
STRIPE_SECRET_KEY, VITE_STRIPE_PUBLIC_KEY | Stripe | For payments |
SMTP_HOST, SMTP_USER, SMTP_PASS | Email | For OTP/notifications |
RAZORPAY_KEY_ID, RAZORPAY_KEY_SECRET | Razorpay | Optional |
PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET | PayPal | Optional |
PAYSTACK_SECRET_KEY | Paystack | Optional |
MERCADOPAGO_ACCESS_TOKEN | MercadoPago | Optional |
Optional
| Variable | Default | Description |
NODE_ENV | development | Environment mode |
LOG_LEVEL | info | Logging verbosity (debug/info/warn/error) |
DEMO_MODE | false | Enable demo account with sample data |
ENABLE_BULLMQ | false | Enable Redis-based job queue |
REDIS_URL | — | Redis connection for BullMQ |
Demo Mode
Demo mode creates a pre-populated demo account for showcasing the platform to visitors.
Activation
# In .env file
DEMO_MODE=true
What Gets Created
| Resource | Count |
| Demo Account | 1 (demo@diploy.in / Demo@123, admin role, pro plan, 1000 credits) |
| AI Agents | 3 (HR Screening, Technical Interview, Candidate Follow-up) |
| Knowledge Base Items | 4 |
| Campaigns | 3 (completed, active, pending) |
| Contacts | 18 |
| Call Records | 11 (with transcripts and summaries) |
| Credit Transactions | 5 |
| Webhook Subscriptions | 2 |
| Website Widget | 1 |
| Jobs | 4 |
| Candidates | 12 |
| Interview Sessions | 4 |
Behavior
- Seeding is idempotent — checks existing data count, skips if complete, cleans and re-seeds if partial
- Admin routes (
/api/admin/*) are blocked with 403 for security
- User-side write operations are allowed so visitors can test features
- Response data is masked (emails, phone numbers, names) for privacy
- Configurable credentials via
DEMO_EMAIL, DEMO_PASSWORD, DEMO_NAME env vars
Key Files
| File | Purpose |
server/demo-mode/index.ts | Middleware, account seeding, data masking |
server/demo-mode/seed-demo-data.ts | Sample data creation for all modules |
server/seed-hr-data.ts | Shared HR data seeder (jobs, candidates) |
Production Deployment
Using Production Script
# Start
bash scripts/production.sh start
# Stop
bash scripts/production.sh stop
# Restart
bash scripts/production.sh restart
# View status
bash scripts/production.sh status
# View logs
bash scripts/production.sh logs
Using deploy.sh
# Full deployment (install, build, restart)
bash deploy.sh
Production Checklist
- Set
NODE_ENV=production
- Use strong, unique
SESSION_SECRET and JWT_SECRET (auto-generated by setup)
- Configure proper
APP_URL and APP_DOMAIN
- Set up SMTP for email OTP verification
- Configure at least one telephony provider (Twilio or Plivo)
- Configure at least one voice AI provider (ElevenLabs or OpenAI)
- Configure at least one payment gateway
- Set up SSL/TLS (required for webhooks and cookie security)
- Enable
STRIPE_WEBHOOK_SECRET for production webhook verification
- Run
npm run db:push && npm run db:seed to initialize database
- Run
npm run build before starting production server
AgentHR Developer Guide v1.0.0
© 2025 Diploy — Bisht Technologies Private Limited
Website: diploy.in | Contact: cs@diploy.in