QUIZZERA – Deployment & Integration Guide (Vercel)
This document explains how to deploy QUIZZERA to Vercel and integrate the custom payment gateway and SendPulse notifications.
Quick links:
- Deployment guide:
DEPLOYMENT.md - API reference:
API.md
Overview
This repository includes:
- Next.js app (student + admin)
- Custom payment gateway API
- Bank transfer flow
- SendPulse notifications
- Swagger/ReDoc API docs
For full details, see the linked documents above.
Authentication Testing
Comprehensive auth integration test validates all authentication flows:
Quick Test
npm run test:auth:integration
This automated test validates:
- ✓ User signup with email verification
- ✓ Login blocking for unverified accounts
- ✓ OTP request and verification flow
- ✓ Token-based email verification
- ✓ Forgot password (dual-path: token + OTP)
- ✓ Password reset with token
- ✓ Password reset with OTP
- ✓ Logout with session invalidation
- ✓ Token invalidation after logout
Manual Verification Steps
Some tests require manual intervention for email codes:
-
OTP Verification:
node test-auth-integration.js --otp=123456 -
Reset Password with Token:
node test-auth-integration.js --reset-token=YOUR_TOKEN -
Reset Password with OTP:
node test-auth-integration.js --reset-otp=123456 -
Full Flow with All Codes:
node test-auth-integration.js --otp=123456 --reset-otp=654321
Basic Auth Test Suite
For quick validation of core auth endpoints:
npm run test:auth
Database Seeding
Use MongoDB seed scripts from the project root:
- Safe seed (non-destructive):
npm run seed
- Reset guard check (expected to fail unless forced):
npm run seed:check-reset
- Full reset + reseed (destructive, CI-friendly):
npm run seed:reset
Seed API modes (admin)
- Users seed endpoint:
POST /api/admin/users/seed- Reset mode:
POST /api/admin/users/seed?reset=true&force=true
- Reset mode:
- Exams seed endpoint:
POST /api/admin/exams/seed- Reset mode:
POST /api/admin/exams/seed?reset=true&force=true
- Reset mode:
Reset requests without force=true are rejected by design for safety.
Deployment Guide
Overview
This document provides deployment instructions for the Quizzera application.
Prerequisites
- Node.js 18+
- MongoDB Atlas account
- Vercel account (for hosting)
- SendPulse account (for email)
Environment Variables
Create a .env.local file with the following variables:
# Database
MONGODB_URI=mongodb+srv://<username>:<password>@cluster.mongodb.net/quiz_platform
# Authentication
JWT_SECRET=your-super-secret-jwt-key
NEXTAUTH_SECRET=your-nextauth-secret
# App URL
NEXT_PUBLIC_APP_URL=http://localhost:3000
# SendPulse Email
SENDPULSE_API_KEY=your-sendpulse-api-key
SENDPULSE_SENDER_EMAIL=hello@quizzera.pk
SENDPULSE_SENDER_NAME=QUIZZERA
# Payment Gateway (Switch)
SWITCH_API_KEY=your-switch-api-key
SWITCH_API_SECRET=your-switch-api-secret
SWITCH_API_URL=https://api.switch.com
Build Commands
# Install dependencies
npm install
# Run development server
npm run dev
# Build for production
npm run build
# Start production server
npm start
Deployment Steps
- Push to GitHub: Commit and push your code to a GitHub repository
- Connect to Vercel: Import your repository in Vercel
- Configure Environment Variables: Add all required environment variables in Vercel dashboard
- Deploy: Vercel will automatically build and deploy your application
Database Seeding
To seed the database with initial data:
node scripts/seed-mongodb.js
Troubleshooting
- Ensure all environment variables are set correctly
- Check MongoDB Atlas network access settings
- Verify SendPulse API credentials
- Check Vercel function logs for errors
QUIZZERA API Reference
Overview
Base URL (production): https://quizzera.pk
Base URL (development): http://localhost:9002
All admin endpoints require a valid JWT bearer token and admin authorization.
Authentication
- JWT access token:
Authorization: Bearer <token> - Payment gateway:
x-api-key: <PAYMENT_GATEWAY_API_KEY>
Authorization Header Format
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6...
Demo Mode
For development, you can use demo tokens starting with demo_token_ for admin endpoints.
Authentication APIs
POST /api/auth/login
Headers: Authorization: Bearer <token> (optional for rate limiting)
Request:
{
"email": "user@example.com",
"password": "password123"
}
Response:
{
"success": true,
"data": {
"uid": "user123",
"email": "user@example.com",
"emailVerified": true,
"customToken": "..."
}
}
Error Responses:
401: Invalid credentials400: Validation error
POST /api/auth/signup
Headers: Authorization: Bearer <token> (optional for rate limiting)
Request:
{
"email": "user@example.com",
"password": "password123",
"name": "Full Name",
"role": "student" // or "mentor"
}
Response:
{
"success": true,
"data": {
"uid": "user123",
"email": "user@example.com",
"name": "Full Name",
"role": "student"
}
}
POST /api/auth/forgot-password
Headers: Authorization: Bearer <token> (optional for rate limiting)
Request:
{
"email": "user@example.com"
}
Response:
{
"success": true,
"message": "If an account exists with this email, a password reset link has been sent"
}
POST /api/auth/token
Headers: Authorization: Bearer <access_token>
Get a custom session token for API authentication.
Request: Empty body
Response:
{
"token": "custom_session_token"
}
Admin Users Management
GET /api/admin/users
Headers: Authorization: Bearer <admin token>
Query Parameters:
role- Filter by role:student,mentor,allstatus- Filter by status:Active,Inactive,allsearch- Search by name or emaillimit- Pagination limit (default: 50)offset- Pagination offset (default: 0)
Response:
{
"success": true,
"data": {
"users": [
{
"id": "user123",
"name": "Ahmed Khan",
"email": "ahmed@example.com",
"phone": "+92 300 1234567",
"role": "student",
"status": "Active",
"city": "Karachi",
"country": "createdAt": "Pakistan",
"2024-01-15T10:00:00Z"
}
],
"total": 156,
"offset": 0,
"limit": 50
}
}
POST /api/admin/users
Headers: Authorization: Bearer <admin token>
Request:
{
"name": "New User",
"email": "newuser@example.com",
"phone": "+92 300 1234567",
"role": "student",
"status": "Active",
"city": "Karachi",
"country": "Pakistan"
}
Response:
{
"success": true,
"data": {
"id": "newuser123",
"name": "New User",
"email": "newuser@example.com",
"role": "student",
"status": "Active"
}
}
PUT /api/admin/users
Headers: Authorization: Bearer <admin token>
Request:
{
"id": "user123",
"name": "Updated Name",
"phone": "+92 300 7654321",
"status": "Inactive"
}
DELETE /api/admin/users
Headers: Authorization: Bearer <admin token>
Query Parameter: id (required)
Response:
{
"success": true,
"message": "User deleted successfully"
}
Admin Mentors Management
GET /api/admin/mentors
Headers: Authorization: Bearer <admin token>
Query Parameters:
status- Filter by status:Active,Inactive,allspecialization- Filter by specializationsearch- Search by name, email, or specializationlimit- Pagination limit (default: 50)offset- Pagination offset (default: 0)
Response:
{
"success": true,
"data": {
"mentors": [
{
"id": "mentor123",
"displayName": "Dr. Fatima Ali",
"email": "fatima@example.com",
"phone": "+92 301 2345678",
"specialization": "Mathematics",
"experienceYears": 5,
"hourlyRate": 1500,
"status": "Active",
"rating": 4.8,
"totalStudents": 25,
"totalSessions": 150,
"city": "Lahore",
"country": "Pakistan"
}
],
"total": 42,
"offset": 0,
"limit": 50
}
}
POST /api/admin/mentors
Headers: Authorization: Bearer <admin token>
Request:
{
"email": "newmentor@example.com",
"displayName": "Dr. New Mentor",
"phone": "+92 302 3456789",
"specialization": "Physics",
"experienceYears": 7,
"teachingApproach": "Student-centered learning",
"bio": "Experienced physics teacher...",
"hourlyRate": 2000,
"city": "Islamabad",
"country": "Pakistan"
}
Response:
{
"success": true,
"data": {
"id": "mentor456",
"email": "newmentor@example.com",
"displayName": "Dr. New Mentor",
"specialization": "Physics",
"hourlyRate": 2000,
"status": "Active"
}
}
PUT /api/admin/mentors
Headers: Authorization: Bearer <admin token>
Request:
{
"id": "mentor123",
"displayName": "Prof. Fatima Ali",
"hourlyRate": 1800,
"specialization": "Mathematics & Physics",
"status": "Active"
}
DELETE /api/admin/mentors
Headers: Authorization: Bearer <admin token>
Query Parameter: id (required)
Response:
{
"success": true,
"message": "Mentor deleted successfully"
}
Admin Students Management
GET /api/admin/students
Headers: Authorization: Bearer <admin token>
Query Parameters:
status- Filter by status:Active,Inactive,allgrade- Filter by grade/classsearch- Search by name or emaillimit- Pagination limit (default: 50)offset- Pagination offset (default: 0)
Response:
{
"success": true,
"data": {
"students": [
{
"id": "student123",
"displayName": "Ahmed Khan",
"email": "ahmed@example.com",
"phone": "+92 300 1234567",
"grade": "10th Grade",
"learningGoals": "Want to improve math scores",
"status": "Active",
"city": "Karachi",
"country": "Pakistan",
"subscriptionPlan": "pro",
"totalPractices": 25,
"averageScore": 78.5
}
],
"total": 114,
"offset": 0,
"limit": 50
}
}
POST /api/admin/students
Headers: Authorization: Bearer <admin token>
Request:
{
"email": "newstudent@example.com",
"displayName": "New Student",
"phone": "+92 303 4567890",
"grade": "11th Grade",
"learningGoals": "Prepare for entrance exams",
"city": "Peshawar",
"country": "Pakistan"
}
PUT /api/admin/students
Headers: Authorization: Bearer <admin token>
Request:
{
"id": "student123",
"displayName": "Ahmed Omar Khan",
"grade": "12th Grade",
"status": "Active"
}
DELETE /api/admin/students
Headers: Authorization: Bearer <admin token>
Query Parameter: id (required)
Admin Assignments Management
GET /api/admin/assignments
Headers: Authorization: Bearer <admin token>
Query Parameters:
status- Filter by status:active,completed,cancelled,all
Response:
{
"success": true,
"data": {
"assignments": [
{
"id": "assign123",
"mentorId": "mentor123",
"mentorName": "Dr. Fatima Ali",
"studentId": "student456",
"studentName": "Ahmed Khan",
"status": "active",
"startDate": "2024-01-15",
"endDate": null,
"notes": "Focus on Mathematics",
"sessionsCompleted": 5
}
],
"stats": {
"active": 38,
"completed": 25,
"cancelled": 5
}
}
}
POST /api/admin/assignments
Headers: Authorization: Bearer <admin token>
Request:
{
"mentorId": "mentor123",
"studentId": "student456",
"notes": "Focus on calculus and algebra"
}
Response:
{
"success": true,
"data": {
"id": "assign789",
"mentorId": "mentor123",
"studentId": "student456",
"status": "active",
"startDate": "2024-02-11",
"sessionsCompleted": 0
}
}
PUT /api/admin/assignments
Headers: Authorization: Bearer <admin token>
Request:
{
"id": "assign123",
"status": "completed",
"endDate": "2024-02-11"
}
DELETE /api/admin/assignments
Headers: Authorization: Bearer <admin token>
Query Parameter: id (required)
Admin Exams Management
GET /api/admin/exams
Headers: Authorization: Bearer <admin token>
Response:
{
"success": true,
"data": {
"exams": [
{
"id": "exam123",
"title": "Mathematics Mock Test",
"description": "Practice test for matriculation math",
"timeLimit": 60,
"questionCount": 50,
"isPaid": false,
"createdAt": "2024-01-10T10:00:00Z"
}
],
"total": 15
}
}
POST /api/admin/exams
Headers: Authorization: Bearer <admin token>
Request:
{
"title": "New Mock Test",
"description": "Description of the exam",
"timeLimit": 45,
"mcqs": [
{
"id": "mcq1",
"questionText": "What is 2+2?",
"options": ["3", "4", "5", "6"],
"correctAnswer": 1,
"explanation": "Simple addition"
}
],
"isPaid": false,
"negativeMarking": true,
"negativeMarkValue": 0.25,
"disclaimer": "This is a practice exam"
}
GET /api/admin/exams/:id
Headers: Authorization: Bearer <admin token>
Get exam details with all MCQs.
PUT /api/admin/exams/:id
Headers: Authorization: Bearer <admin token>
Update exam details.
DELETE /api/admin/exams/:id
Headers: Authorization: Bearer <admin token>
Delete an exam.
Admin MCQs Management
GET /api/admin/mcqs
Headers: Authorization: Bearer <admin token>
Query Parameters:
category- Filter by categorytopic- Filter by topicdifficulty- Filter by difficulty:easy,medium,hard
Response:
{
"success": true,
"data": {
"mcqs": [
{
"id": "mcq123",
"questionText": "What is the capital of Pakistan?",
"options": ["Karachi", "Lahore", "Islamabad", "Rawalpindi"],
"correctAnswer": 2,
"category": "Geography",
"topic": "Pakistan",
"difficulty": "easy"
}
],
"total": 1500
}
}
POST /api/admin/mcqs
Headers: Authorization: Bearer <admin token>
Request:
{
"questionText": "What is the capital of Pakistan?",
"options": ["Karachi", "Lahore", "Islamabad", "Rawalpindi"],
"correctAnswer": 2,
"explanation": "Islamabad is the federal capital of Pakistan",
"category": "Geography",
"topic": "Pakistan",
"difficulty": "easy"
}
PUT /api/admin/mcqs/:id
Headers: Authorization: Bearer <admin token>
Update MCQ details.
DELETE /api/admin/mcqs/:id
Headers: Authorization: Bearer <admin token>
Delete an MCQ.
POST /api/admin/mcqs/import
Headers: Authorization: Bearer <admin token>
Content-Type: multipart/form-data
Import MCQs from CSV file.
GET /api/admin/mcqs/export
Headers: Authorization: Bearer <admin token>
Export all MCQs as CSV.
Mentor APIs
GET /api/mentor/profile
Headers: Authorization: Bearer <token>
Query Parameter: uid (required)
Response:
{
"success": true,
"data": {
"profile": {
"uid": "mentor123",
"displayName": "Dr. Fatima Ali",
"email": "fatima@example.com",
"bio": "Experienced mathematics teacher...",
"hourlyRate": 1500,
"specializations": ["Mathematics", "Calculus", "Algebra"],
"rating": 4.8,
"totalReviews": 45,
"totalStudents": 25,
"totalSessions": 150,
"availability": "Mon-Fri, 9AM-5PM"
}
}
}
PUT /api/mentor/profile
Headers: Authorization: Bearer <token>
Request:
{
"uid": "mentor123",
"displayName": "Prof. Fatima Ali",
"bio": "Updated bio...",
"hourlyRate": 1800,
"specializations": ["Mathematics", "Statistics"]
}
GET /api/mentor/stats
Headers: Authorization: Bearer <token>
Query Parameter: uid (required)
Response:
{
"success": true,
"data": {
"stats": {
"totalSessions": 150,
"totalStudents": 25,
"upcomingSessions": 5,
"averageRating": 4.8,
"totalEarnings": 150000,
"monthlyEarnings": 15000,
"completionRate": 95,
"responseTime": 2
}
}
}
GET /api/mentor/bookings
Headers: Authorization: Bearer <token>
Query Parameters:
uid- Mentor UIDstatus- Filter:upcoming,completed,all
Response:
{
"success": true,
"data": {
"bookings": [
{
"id": "booking123",
"studentName": "Ahmed Khan",
"serviceName": "Mathematics Session",
"scheduledDate": "2024-02-12",
"scheduledTime": "10:00 AM",
"duration": 60,
"status": "confirmed",
"price": 1500
}
]
}
}
POST /api/mentor/bookings
Headers: Authorization: Bearer <token>
Request:
{
"mentorId": "mentor123",
"studentId": "student456",
"serviceName": "Mathematics Session",
"scheduledDate": "2024-02-15",
"scheduledTime": "2:00 PM",
"duration": 60,
"price": 1500
}
GET /api/mentor/quizzes
Headers: Authorization: Bearer <token>
Query Parameters:
mentorId- Filter by mentor UIDstatus- Filter:published,draft,allsubject- Filter by subjectlimit- Pagination limitoffset- Pagination offset
Response:
{
"success": true,
"data": {
"quizzes": [
{
"id": "quiz123",
"title": "Calculus Quiz 1",
"subject": "Mathematics",
"grade": "12th",
"difficulty": "medium",
"questionCount": 20,
"isPublished": true,
"totalAttempts": 45,
"averageScore": 72.5,
"createdAt": "2024-01-15T10:00:00Z"
}
],
"total": 10
}
}
POST /api/mentor/quizzes
Headers: Authorization: Bearer <token>
Request:
{
"title": "Algebra Quiz",
"description": "Practice quiz on linear equations",
"subject": "Mathematics",
"grade": "10th",
"difficulty": "easy",
"questions": [
{
"questionText": "Solve for x: 2x + 5 = 15",
"options": ["3", "5", "7", "10"],
"correctAnswer": 1,
"explanation": "Subtract 5 and divide by 2",
"points": 1
}
],
"timeLimit": 30,
"isPublished": false
}
PUT /api/mentor/quizzes
Headers: Authorization: Bearer <token>
Update quiz details.
DELETE /api/mentor/quizzes
Headers: Authorization: Bearer <token>
Query Parameter: id (required)
GET /api/mentor/students
Headers: Authorization: Bearer <token>
Get list of students assigned to mentor.
Response:
{
"success": true,
"data": {
"students": [
{
"id": "student123",
"name": "Ahmed Khan",
"email": "ahmed@example.com",
"totalSessions": 10,
"totalSpent": 15000,
"lastSession": "2024-02-10",
"status": "active"
}
],
"total": 25
}
}
GET /api/mentor/notifications
Headers: Authorization: Bearer <token>
Get mentor notifications.
Student APIs
GET /api/student/stats
Headers: Authorization: Bearer <token>
Response:
{
"success": true,
"data": {
"stats": {
"totalPractices": 50,
"totalMockTests": 10,
"averageScore": 78.5,
"upcomingSessions": 2,
"totalSessionsAttended": 15
}
}
}
GET /api/student/history
Headers: Authorization: Bearer <token>
Query Parameters:
page- Page number (default: 1)limit- Items per page (default: 10, max: 50)status- Filter:all,completed,in-progress
Response:
{
"success": true,
"data": {
"sessions": [
{
"id": "session123",
"examTitle": "Mathematics Mock Test",
"score": 42,
"totalQuestions": 50,
"percentage": 84,
"completedAt": "2024-02-10T15:00:00Z",
"timeTaken": 3600
}
],
"stats": {
"totalPractices": 50,
"totalMockTests": 10,
"averageScore": 78.5,
"highestScore": 95
},
"pagination": {
"page": 1,
"limit": 10,
"total": 60,
"totalPages": 6
}
}
}
Practice Session APIs
POST /api/practice/session/start
Headers: Authorization: Bearer <token>
Start a new practice session with random MCQs.
Request:
{
"category": "mathematics",
"topic": "algebra",
"difficulty": "medium",
"questionCount": 10,
"timeLimit": 15
}
Response:
{
"success": true,
"data": {
"session": {
"sessionId": "session_abc123",
"questions": [
{
"id": "mcq123",
"questionText": "Solve for x: 2x + 5 = 15",
"options": ["3", "5", "7", "10"],
"subject": "Mathematics",
"topic": "Algebra",
"difficulty": "medium"
}
],
"timeLimit": 15,
"startedAt": "2024-02-11T10:00:00Z"
}
}
}
GET /api/practice/session/start
Headers: Authorization: Bearer <token>
Query Parameters:
sessionId- Get specific session
Get user's active practice session.
Response:
{
"success": true,
"data": {
"activeSession": {
"id": "session_abc123",
"category": "mathematics",
"status": "in_progress",
"startedAt": "2024-02-11T10:00:00Z",
"timeLimit": 15
}
}
}
POST /api/practice/session/submit
Headers: Authorization: Bearer <token>
Submit practice answers and get instant results.
Request:
{
"sessionId": "session_abc123",
"answers": [
{
"questionId": "mcq123",
"selectedAnswer": 1,
"timeSpent": 45
}
],
"timeSpent": 600
}
Response:
{
"success": true,
"data": {
"sessionId": "session_abc123",
"results": {
"totalQuestions": 10,
"correctAnswers": 8,
"wrongAnswers": 2,
"unanswered": 0,
"score": 8,
"percentage": 80,
"grade": "B",
"timeSpent": 600,
"answers": [
{
"questionId": "mcq123",
"questionText": "Solve for x: 2x + 5 = 15",
"options": ["3", "5", "7", "10"],
"selectedAnswer": 1,
"correctAnswer": 1,
"isCorrect": true,
"explanation": "Subtract 5 and divide by 2",
"timeSpent": 45
}
]
}
}
}
GET /api/practice/session/submit
Headers: Authorization: Bearer <token>
Query Parameter: sessionId (required)
Get completed session results.
Public Exam APIs
GET /api/exams
Public endpoint - no authentication required
Response:
{
"success": true,
"data": {
"exams": [
{
"id": "exam123",
"title": "Mathematics Mock Test",
"description": "Practice test for matriculation math",
"timeLimit": 60,
"questionCount": 50,
"category": "Pakistan"
}
]
}
}
GET /api/exams/:id
Public endpoint
Get exam details with all MCQs.
Response:
{
"success": true,
"data": {
"exam": {
"id": "exam123",
"title": "Mathematics Mock Test",
"description": "Practice test",
"timeLimit": 60,
"questionCount": 50,
"mcqs": [
{
"id": "mcq1",
"questionText": "What is 2+2?",
"options": ["3", "4", "5", "6"]
}
]
}
}
}
Payment APIs
POST /api/payments/initiate
Headers: x-api-key: <PAYMENT_GATEWAY_API_KEY>
Request:
{
"userId": "uid123",
"planId": "pro",
"amount": 2000,
"currency": "PKR",
"redirectUrl": "https://quizzera.pk/success"
}
Response:
{
"success": true,
"data": {
"paymentUrl": "https://paymentgateway.com/pay?txn=xxx",
"transactionId": "txn_xxx"
}
}
POST /api/payments/callback
Headers: x-api-key: <PAYMENT_GATEWAY_API_KEY>
Request:
{
"transactionId": "txn_123",
"status": "success",
"userId": "uid123",
"planId": "pro",
"amount": 2000,
"currency": "PKR"
}
POST /api/payments/bank-transfer/initiate
Headers: Authorization: Bearer <token>
Content-Type: multipart/form-data
Form Fields:
transactionId(required)amount(required)attachment(optional - bank receipt)
POST /api/payments/switch/initiate
Headers: Authorization: Bearer <token>
Switch subscription plan.
POST /api/payments/switch/callback
Headers: Authorization: Bearer <token>
Handle plan switch callback.
Admin Payment/Invoices
GET /api/admin/payment-requests
Headers: Authorization: Bearer <admin token>
Get pending bank transfer requests.
POST /api/admin/payment-requests/:id/approve
Headers: Authorization: Bearer <admin token>
Approve a payment request.
GET /api/admin/invoice-requests
Headers: Authorization: Bearer <admin token>
Get pending invoice requests.
POST /api/admin/invoice-requests/:id/approve
Headers: Authorization: Bearer <admin token>
Approve and generate invoice.
GET /api/admin/invoices
Headers: Authorization: Bearer <admin token>
List all invoices.
POST /api/admin/invoices
Headers: Authorization: Bearer <admin token>
Create manual invoice.
Request:
{
"userId": "uid123",
"planName": "Pro Plan",
"amount": 2000,
"currency": "PKR",
"dueDate": "2024-03-01",
"notes": "Manual invoice for annual subscription"
}
GET /api/admin/invoices/:id/pdf
Headers: Authorization: Bearer <admin token>
Query: userId=<uid>
Download invoice PDF.
GET /api/student/invoices/:id/pdf
Headers: Authorization: Bearer <token>
Student downloads their invoice PDF.
GET /api/student/certificates/:id/pdf
Headers: Authorization: Bearer <token>
Download certificate PDF.
Blog APIs
GET /api/blog
Public endpoint
List blog posts.
Response:
{
"success": true,
"data": [
{
"id": "post123",
"title": "How to Prepare for NTS",
"slug": "how-to-prepare-for-nts",
"excerpt": "Complete guide...",
"content": "Full content...",
"author": "Education Team",
"publishedAt": "2024-02-10T10:00:00Z",
"category": "Exam Prep",
"tags": ["NTS", "Test Prep"],
"coverImage": "https://..."
}
]
}
GET /api/blog/:slug
Public endpoint
Get single blog post.
GET /api/blog/:slug/comments
Public endpoint
List blog post comments.
POST /api/blog/:slug/comments
Headers: Authorization: Bearer <token>
Request:
{
"content": "Great article! Very helpful.",
"parentId": null
}
FAQ APIs
GET /api/faq
Public endpoint
Response:
{
"success": true,
"data": [
{
"id": "faq1",
"question": "How do I reset my password?",
"answer": "Go to login page and click 'Forgot Password'.",
"category": "Account",
"order": 1
}
],
"categories": ["General", "Billing", "Technical"]
}
Categories APIs
GET /api/categories
Public endpoint
Response:
{
"success": true,
"data": [
{
"id": "cat1",
"name": "Pakistan Exams",
"slug": "pakistan",
"description": "Exams conducted in Pakistan",
"order": 1
}
]
}
Admin Dashboard
GET /api/admin/dashboard
Headers: Authorization: Bearer <admin token>
Response:
{
"success": true,
"data": {
"stats": {
"totalUsers": 500,
"totalMentors": 42,
"totalStudents": 458,
"totalExams": 50,
"totalMcqs": 10000,
"activeSubscriptions": 150,
"pendingPayments": 20,
"totalRevenue": 500000
},
"examsByCategory": {
"Pakistan": 20,
"UAE": 15,
"KSA": 10
}
}
}
GET /api/admin/health
Headers: Authorization: Bearer <admin token>
Response:
{
"success": true,
"data": {
"status": "healthy",
"services": {
"firestore": "connected",
"auth": "connected"
},
"timestamp": "2024-02-11T10:00:00.000Z",
"uptime": 123456.78
}
}
GET /api/admin/settings
Headers: Authorization: Bearer <admin token>
Get platform settings.
PUT /api/admin/settings
Headers: Authorization: Bearer <admin token>
Update platform settings.
Notifications
POST /api/notifications/signup
Headers: Authorization: Bearer <admin token>
Send welcome notification.
Request:
{
"email": "user@example.com",
"name": "New User"
}
POST /api/notifications/result
Headers: Authorization: Bearer <admin token>
Send exam result notification.
POST /api/notifications/invoice
Headers: Authorization: Bearer <admin token>
Send invoice notification.
Rate Limits
| Endpoint Type | Rate Limit | |--------------|------------| | Authentication | 5 requests/minute | | Signup | 5 requests/hour per IP | | Password Reset | 3 requests/hour per IP | | General API | 100 requests/minute | | Admin APIs | 30 requests/minute |
Error Response Format
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message"
}
}
Common Error Codes
| Code | Description |
|------|-------------|
| UNAUTHORIZED | Authentication required |
| INVALID_TOKEN | Invalid or expired token |
| FORBIDDEN | Insufficient permissions |
| NOT_FOUND | Resource not found |
| INVALID_INPUT | Invalid request data |
| RATE_LIMIT_EXCEEDED | Too many requests |
| UPGRADE_REQUIRED | Pro Plan required |
| CONFLICT | Resource already exists |
HTTP Status Codes
| Status | Description | |--------|-------------| | 200 | Success | | 201 | Created | | 400 | Bad Request | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Not Found | | 409 | Conflict | | 429 | Too Many Requests | | 500 | Internal Server Error |
API Documentation
- Swagger UI:
/api-docs/swagger - ReDoc:
/api-docs/redoc - OpenAPI JSON:
/openapi.json
Support
For API-related questions, contact: api-support@quizzera.pk