- Authentication
- Core Session Management APIs
- Device Connection Management APIs
- Real-time Response APIs
- State Management APIs
- Conflict Resolution APIs
- Dashboard & Monitoring APIs
- ArUco Card Management APIs
- Analytics APIs
- System Health & Monitoring APIs
All API endpoints require authentication using one of the following methods:
- Token Authentication:
Authorization: Token <your_token_here> - Session Authentication: Django session cookies
- Basic Authentication: HTTP Basic Auth
Base URL: /api/v2/tiqer/
Common Error Codes:
401 Unauthorized: Missing or invalid authentication403 Forbidden: Insufficient permissions404 Not Found: Resource not found400 Bad Request: Invalid request data500 Internal Server Error: Server error
Endpoint: POST /api/v2/tiqer/sessions/
Purpose: Create a new TiQer live quiz session
Authentication: Required (Teacher role)
Frontend Critical: ⭐ YES - Essential for session creation
Request Body:
{
"session_name": "Grade 8 Chemistry Quiz - Acids and Bases",
"assignment": 145,
"teacher": 23,
"classroom": 67,
"show_live_results": true,
"auto_advance_questions": false,
"question_time_limit": 30,
"allow_teacher_override": true
}Database Mapping:
session_name→TiQerSession.session_name(CharField, max_length=200)assignment→TiQerSession.assignment(ForeignKey to Assignments)teacher→TiQerSession.teacher(ForeignKey to CustomUser)classroom→TiQerSession.classroom(ForeignKey to ClassRooms)
Validation Rules:
- Assignment must have MCQ/True-False questions
- Teacher must have access to the specified classroom
- Session name must be unique per teacher
Success Response (201 Created):
{
"status": "SUCCESS",
"data": {
"id": 89,
"session_token": "TQ_2024_89_ABC123",
"session_name": "Grade 8 Chemistry Quiz - Acids and Bases",
"assignment": 145,
"teacher": 23,
"classroom": 67,
"status": "Pending",
"start_time": null,
"end_time": null,
"current_question": null,
"current_question_number": 0,
"total_questions": 15,
"show_live_results": true,
"auto_advance_questions": false,
"question_time_limit": 30,
"allow_teacher_override": true,
"teacher_name": "John Smith",
"classroom_name": "Grade 8-A",
"assignment_name": "Chemistry Quiz - Acids and Bases",
"current_question_title": null,
"active_students_count": 0,
"created": "2024-07-29T10:30:00Z",
"updated": "2024-07-29T10:30:00Z"
},
"message": "TiQer session created successfully"
}Error Responses:
// 400 Bad Request - Invalid assignment
{
"status": "FAILURE",
"errors": {
"assignment": ["Assignment activity must contain MCQ questions for TiQer sessions."]
}
}
// 403 Forbidden - Teacher access denied
{
"status": "FAILURE",
"errors": {
"non_field_errors": ["Teacher does not have access to this classroom."]
}
}Endpoint: GET /api/v2/tiqer/sessions/{session_token}/
Purpose: Retrieve detailed information about a specific TiQer session
Authentication: Required (Teacher/Student with access)
Frontend Critical: ⭐ YES - Essential for session state
Path Parameters:
session_token(string): Unique session identifier (e.g., "TQ_2024_89_ABC123")
Success Response (200 OK):
{
"id": 89,
"session_token": "TQ_2024_89_ABC123",
"session_name": "Grade 8 Chemistry Quiz - Acids and Bases",
"assignment": 145,
"teacher": 23,
"classroom": 67,
"status": "Active",
"start_time": "2024-07-29T10:35:00Z",
"end_time": null,
"current_question": 1247,
"current_question_number": 3,
"total_questions": 15,
"show_live_results": true,
"auto_advance_questions": false,
"question_time_limit": 30,
"allow_teacher_override": true,
"teacher_name": "John Smith",
"classroom_name": "Grade 8-A",
"assignment_name": "Chemistry Quiz - Acids and Bases",
"current_question_title": "Which of the following is a strong acid?",
"active_students_count": 28,
"created": "2024-07-29T10:30:00Z",
"updated": "2024-07-29T10:35:00Z"
}Endpoint: POST /api/v2/tiqer/sessions/{session_token}/start_session/
Purpose: Start a TiQer session and make it active for student participation
Authentication: Required (Teacher only)
Frontend Critical: ⭐ YES - Essential for session lifecycle
Path Parameters:
session_token(string): Session identifier
Success Response (200 OK):
{
"status": "SUCCESS",
"data": {
"id": 89,
"session_token": "TQ_2024_89_ABC123",
"status": "Active",
"start_time": "2024-07-29T10:35:00Z",
"message": "Session started successfully"
}
}Error Response:
// 400 Bad Request - Already active
{
"status": "FAILURE",
"error_message": "Session is already active"
}Endpoint: POST /api/v2/tiqer/sessions/{session_token}/end_session/
Purpose: End an active TiQer session and finalize results
Authentication: Required (Teacher only)
Frontend Critical: ⭐ YES - Essential for session lifecycle
Success Response (200 OK):
{
"status": "SUCCESS",
"data": {
"id": 89,
"session_token": "TQ_2024_89_ABC123",
"status": "Completed",
"end_time": "2024-07-29T11:15:00Z",
"message": "Session ended successfully",
"session_summary": {
"total_questions_completed": 15,
"total_responses": 420,
"average_accuracy": 78.5,
"session_duration_minutes": 40
}
}
}Endpoint: POST /api/v2/tiqer/sessions/{session_token}/next_question/
Purpose: Advance session to next question during live quiz
Authentication: Required (Teacher only)
Frontend Critical: ⭐ YES - Essential for question navigation
Success Response (200 OK):
{
"status": "SUCCESS",
"data": {
"current_question": 1248,
"current_question_number": 4,
"current_question_title": "What is the pH of pure water?",
"question_content": "What is the pH of pure water at 25°C?",
"options": [
{"id": 4992, "option": "6.0", "option_letter": "A"},
{"id": 4993, "option": "7.0", "option_letter": "B"},
{"id": 4994, "option": "8.0", "option_letter": "C"},
{"id": 4995, "option": "14.0", "option_letter": "D"}
],
"has_more_questions": true,
"message": "Advanced to next question"
}
}Endpoint: GET /api/v2/tiqer/sessions/
Purpose: List TiQer sessions based on user role and access
Authentication: Required
Frontend Critical: ⭐ YES - Essential for session selection
Query Parameters:
status(optional): Filter by session status (Pending/Active/Completed)classroom(optional): Filter by classroom IDdate_from(optional): Filter sessions from date (YYYY-MM-DD)date_to(optional): Filter sessions to date (YYYY-MM-DD)
Success Response (200 OK):
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"id": 89,
"session_token": "TQ_2024_89_ABC123",
"session_name": "Grade 8 Chemistry Quiz - Acids and Bases",
"status": "Active",
"start_time": "2024-07-29T10:35:00Z",
"teacher_name": "John Smith",
"classroom_name": "Grade 8-A",
"active_students_count": 28,
"current_question_number": 4,
"total_questions": 15
}
// ... more sessions
]
}Endpoint: POST /api/v2/tiqer/heartbeat/
Purpose: Send device heartbeat to maintain connection status
Authentication: Required (Student/Teacher)
Frontend Critical: ⭐ YES - Essential for connection monitoring
Request Body:
{
"device_id": "student_device_001",
"session_token": "TQ_2024_89_ABC123",
"response_time_ms": 45,
"device_info": {
"device_name": "Student iPhone 12",
"device_type": "mobile",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)",
"has_camera": true,
"camera_resolution": "1920x1080",
"supports_aruco": true,
"network_type": "wifi",
"signal_strength": 85
},
"firebase_token": "fcm_token_here",
"location_data": {
"current_url": "/tiqer/session/TQ_2024_89_ABC123/question/4",
"last_action": "answer_submitted",
"last_interaction": "2024-07-29T10:45:30Z"
}
}Database Mapping:
device_id→TiQerDeviceSync.device_id(CharField, max_length=100)session_token→TiQerDeviceSync.tiqer_session(ForeignKey lookup)response_time_ms→ Used for connection quality calculationdevice_info→ Multiple fields (device_name, device_type, has_camera, etc.)
Success Response (200 OK):
{
"status": "SUCCESS",
"data": {
"device_id": "student_device_001",
"sync_status": "Connected",
"last_ping": "2024-07-29T10:45:35Z",
"connection_quality": 95,
"heartbeat_interval": 30,
"next_heartbeat_due": "2024-07-29T10:46:05Z",
"server_time": "2024-07-29T10:45:35Z",
"session_info": {
"status": "Active",
"current_question_number": 4,
"time_remaining": 25
},
"firebase_sync": {
"path": "/sessions/TQ_2024_89_ABC123/devices/student_device_001",
"last_sync": "2024-07-29T10:45:35Z"
}
}
}Validation Rules:
- Device ID must be unique per session
- Session must be active to accept heartbeats
- Response time must be positive integer
Error Responses:
// 404 Not Found - Session not found
{
"status": "FAILURE",
"error_message": "Session not found",
"error_code": "SESSION_NOT_FOUND"
}
// 400 Bad Request - Invalid device info
{
"status": "FAILURE",
"error_message": "Invalid device information",
"errors": {
"device_id": ["This field is required."],
"response_time_ms": ["Must be a positive integer."]
}
}Endpoint: GET /api/v2/tiqer/connection-status/
Purpose: Get real-time connection status for device in session
Authentication: Required
Frontend Critical: ⭐ YES - Essential for connection monitoring
Query Parameters:
device_id(required): Device identifiersession_token(required): Session identifier
Success Response (200 OK):
{
"status": "SUCCESS",
"data": {
"device_id": "student_device_001",
"user_name": "Alice Johnson",
"sync_status": "Connected",
"connection_established": "2024-07-29T10:32:15Z",
"last_ping": "2024-07-29T10:45:35Z",
"last_ping_elapsed": 12,
"connection_quality": 95,
"quality_indicators": {
"signal_strength": "Excellent",
"response_time": "Fast",
"missed_heartbeats": 0,
"connection_stability": "Stable"
},
"device_info": {
"device_name": "Student iPhone 12",
"device_type": "mobile",
"has_camera": true,
"supports_aruco": true,
"ip_address": "192.168.1.105"
},
"session_context": {
"session_status": "Active",
"current_question_number": 4,
"total_questions": 15,
"user_responses_count": 3
}
}
}Endpoint: POST /api/v2/tiqer/device-register/
Purpose: Register a new device for TiQer session participation
Authentication: Required
Frontend Critical: ⭐ YES - Essential for session joining
Request Body:
{
"session_token": "TQ_2024_89_ABC123",
"device_id": "student_device_001",
"device_info": {
"device_name": "Student iPhone 12",
"device_type": "mobile",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)",
"has_camera": true,
"camera_resolution": "1920x1080",
"supports_aruco": true
},
"firebase_token": "fcm_token_here",
"firebase_uid": "firebase_uid_here"
}Success Response (201 Created):
{
"status": "SUCCESS",
"data": {
"id": 456,
"device_id": "student_device_001",
"user_name": "Alice Johnson",
"sync_status": "Connected",
"connection_established": "2024-07-29T10:32:15Z",
"session_info": {
"session_token": "TQ_2024_89_ABC123",
"session_name": "Grade 8 Chemistry Quiz - Acids and Bases",
"current_question_number": 4,
"total_questions": 15
},
"firebase_path": "/sessions/TQ_2024_89_ABC123/devices/student_device_001"
},
"message": "Device registered successfully"
}Endpoint: POST /api/v2/tiqer/device-disconnect/
Purpose: Gracefully disconnect device from TiQer session
Authentication: Required
Frontend Critical: ⭐ YES - Essential for proper cleanup
Request Body:
{
"device_id": "student_device_001",
"session_token": "TQ_2024_89_ABC123",
"disconnect_reason": "user_initiated",
"final_stats": {
"total_responses": 3,
"session_duration_seconds": 780,
"last_activity": "2024-07-29T10:45:30Z"
}
}Success Response (200 OK):
{
"status": "SUCCESS",
"data": {
"device_id": "student_device_001",
"sync_status": "Disconnected",
"disconnected_at": "2024-07-29T10:46:00Z",
"session_summary": {
"total_responses": 3,
"session_duration_seconds": 780,
"connection_quality_average": 94
}
},
"message": "Device disconnected successfully"
}Endpoint: POST /api/v2/tiqer/device-reconnect/
Purpose: Handle device reconnection after network interruption
Authentication: Required
Frontend Critical: ⭐ YES - Essential for connection recovery
Request Body:
{
"device_id": "student_device_001",
"session_token": "TQ_2024_89_ABC123",
"last_known_state": {
"last_question_number": 3,
"last_response_time": "2024-07-29T10:44:15Z"
},
"reconnection_info": {
"disconnection_duration_seconds": 45,
"disconnect_reason": "network_interruption"
}
}Success Response (200 OK):
{
"status": "SUCCESS",
"data": {
"device_id": "student_device_001",
"sync_status": "Connected",
"reconnected_at": "2024-07-29T10:46:30Z",
"state_sync": {
"current_question_number": 4,
"questions_missed": 1,
"sync_required": true
},
"catch_up_info": {
"missed_questions": [4],
"current_question": {
"question_number": 4,
"question_content": "What is the pH of pure water?",
"time_remaining": 18
}
}
},
"message": "Device reconnected successfully"
}Endpoint: POST /api/v2/tiqer/response/
Purpose: Submit student response to current quiz question (optimized for 50+ concurrent students)
Authentication: Required (Student role)
Frontend Critical: ⭐ YES - Core functionality for quiz participation
Request Body:
{
"session_token": "TQ_2024_89_ABC123",
"question_id": 1248,
"selected_option": "B",
"response_data": {
"aruco_marker_id": "07",
"aruco_detection_data": {
"marker_corners": [[100, 100], [200, 100], [200, 200], [100, 200]],
"detection_confidence": 0.95,
"image_resolution": "1920x1080"
},
"confidence_score": 8,
"scanned_at": "2024-07-29T10:45:45Z",
"response_time_seconds": 12.5,
"response_type": "aruco_scan"
},
"device_info": {
"device_id": "student_device_001",
"scan_quality": "excellent",
"lighting_conditions": "good"
}
}Database Mapping:
- Creates
CustomActivityAnswersHeaderentry if first response - Creates
CustomActivityAnswersentry with TiQer-specific fields - Updates
TiQerAnalyticswith real-time metrics - Triggers Firebase sync for live results
Success Response (200 OK):
{
"status": "SUCCESS",
"data": {
"response_id": 7892,
"question_id": 1248,
"selected_option": "B",
"is_correct": true,
"points_earned": 10,
"response_time_seconds": 12.5,
"submission_timestamp": "2024-07-29T10:45:45Z",
"aruco_data": {
"marker_id": "07",
"detection_quality": "excellent",
"scan_time": "2024-07-29T10:45:45Z"
},
"live_results": {
"total_responses": 26,
"option_distribution": {
"A": 3,
"B": 18,
"C": 4,
"D": 1
},
"accuracy_so_far": 69.2,
"your_rank": 12
}
},
"message": "Response submitted successfully"
}Performance Optimizations:
- Async card usage updates to prevent blocking
- Cached session and classroom data (60s and 5min intervals)
- Optimized database queries for concurrent access
Error Responses:
// 400 Bad Request - Duplicate response
{
"status": "FAILURE",
"error_message": "Response already submitted for this question",
"error_code": "DUPLICATE_RESPONSE"
}
// 404 Not Found - Invalid session
{
"status": "FAILURE",
"error_message": "Session not found or not active",
"error_code": "SESSION_NOT_FOUND"
}
// 400 Bad Request - ArUco detection error
{
"status": "FAILURE",
"error_message": "Invalid ArUco marker data",
"errors": {
"aruco_marker_id": ["Marker ID '07' not found for this classroom"],
"detection_confidence": ["Detection confidence too low (minimum 0.7)"]
}
}Endpoint: GET /api/v2/tiqer/analytics/
Purpose: Get real-time quiz analytics and results
Authentication: Required (Teacher for full data, Student for limited data)
Frontend Critical: ⭐ YES - Essential for live results display
Query Parameters:
session_token(required): Session identifierquestion_id(optional): Specific question analyticsinclude_individual_responses(optional, default: false): Include student-level data (Teacher only)
Success Response (200 OK):
{
"status": "SUCCESS",
"data": {
"session_token": "TQ_2024_89_ABC123",
"current_question": {
"question_id": 1248,
"question_number": 4,
"question_title": "What is the pH of pure water?",
"analytics": {
"total_responses": 26,
"response_rate": 92.9,
"correct_responses": 18,
"incorrect_responses": 8,
"accuracy_percentage": 69.2,
"average_response_time": 15.3,
"option_distribution": {
"A": {"count": 3, "percentage": 11.5, "is_correct": false},
"B": {"count": 18, "percentage": 69.2, "is_correct": true},
"C": {"count": 4, "percentage": 15.4, "is_correct": false},
"D": {"count": 1, "percentage": 3.8, "is_correct": false}
}
}
},
"session_summary": {
"total_questions_completed": 4,
"session_duration_seconds": 900,
"active_students_count": 28,
"overall_accuracy": 74.8,
"average_response_time": 16.2
},
"participation_insights": {
"highly_engaged": 22,
"moderately_engaged": 4,
"needs_attention": 2
}
}
}Endpoint: GET /api/v2/tiqer/aruco-cards/
Purpose: Get ArUco cards for classroom with display numbers and assignments
Authentication: Required (Teacher/Student with classroom access)
Frontend Critical: ⭐ YES - Essential for card-based participation
Query Parameters:
classroom(required): Classroom IDstatus(optional): Filter by card status (Available/Assigned/In Use/Lost/Damaged)assigned_only(optional): Show only assigned cards (default: false)
Success Response (200 OK):
{
"count": 30,
"results": [
{
"id": 1201,
"card_number": 1,
"display_card_number": "01",
"classroom": 67,
"classroom_student": 891,
"card_type": "Student",
"status": "Assigned",
"physical_card_number": "AR_67_001",
"qr_code_data": "TiQer_Card_67_001",
"print_date": "2024-07-15T00:00:00Z",
"last_used": "2024-07-29T10:45:45Z",
"total_uses": 127,
"assigned_date": "2024-07-20T00:00:00Z",
"assignment_notes": "Assigned to Alice Johnson - Seat 1",
"student_name": "Alice Johnson",
"classroom_name": "Grade 8-A",
"student_roll_number": "2024001"
}
// ... more cards
]
}Database Mapping:
ArUcoCardmodel with classroom-scoped numbering- Auto-generated display numbers (01, 02, 03...)
- QR code data for backup scanning method
Endpoint: POST /api/v2/tiqer/aruco-cards/
Purpose: Create new ArUco cards for classroom
Authentication: Required (Teacher/Admin)
Frontend Critical: 🔷 LIMITED - Admin functionality
Request Body:
{
"classroom": 67,
"card_type": "Student",
"quantity": 5,
"assignment_notes": "Additional cards for new students"
}Success Response (201 Created):
{
"status": "SUCCESS",
"data": {
"cards_created": 5,
"card_numbers": ["31", "32", "33", "34", "35"],
"classroom": 67,
"print_ready": true
},
"message": "ArUco cards created successfully"
}Endpoint: PATCH /api/v2/tiqer/aruco-cards/{card_id}/
Purpose: Assign ArUco card to student
Authentication: Required (Teacher)
Frontend Critical: 🔷 LIMITED - Setup functionality
Request Body:
{
"classroom_student": 891,
"assignment_notes": "Assigned to Alice Johnson - Seat 1"
}Success Response (200 OK):
{
"id": 1201,
"display_card_number": "01",
"status": "Assigned",
"classroom_student": 891,
"student_name": "Alice Johnson",
"assigned_date": "2024-07-29T10:50:00Z",
"assignment_notes": "Assigned to Alice Johnson - Seat 1"
}17. Update Session State: POST /api/v2/tiqer/state/update/ - Updates session state with Firebase sync
18. Validate State: GET /api/v2/tiqer/state/validate/ - Validates session state integrity
19. Get State History: GET /api/v2/tiqer/state/history/ - Retrieves state change history
20. Resolve State Conflict: POST /api/v2/tiqer/state/resolve-conflict/ - Manual state conflict resolution
21. Detect Conflicts: POST /api/v2/tiqer/conflicts/detect/ - Manual conflict detection
22. Resolve Conflict: POST /api/v2/tiqer/conflicts/resolve/ - Automated conflict resolution
23. Get Conflict History: GET /api/v2/tiqer/conflicts/history/ - Conflict resolution history
24. Teacher Override: POST /api/v2/tiqer/conflicts/override/ - Teacher manual override
25. Preview Resolution: GET /api/v2/tiqer/conflicts/preview/ - Preview resolution strategies
26. Teacher Dashboard: GET /api/v2/tiqer/dashboard/teacher/ - Education-focused session monitoring
27. Student Status: GET /api/v2/tiqer/status/student/ - Student connection health
28. Troubleshooting: GET /api/v2/tiqer/troubleshoot/ - Automated troubleshooting assistance
29. Connection Analytics: GET /api/v2/tiqer/analytics/connections/ - Connection performance analytics
30. System Health: GET /api/v2/tiqer/monitoring/health/ - System health status
31. Active Alerts: GET /api/v2/tiqer/monitoring/alerts/ - Current system alerts
32. Performance Metrics: GET /api/v2/tiqer/monitoring/metrics/ - Performance metrics
33. Performance Trends: GET /api/v2/tiqer/monitoring/trends/ - Performance trend analysis
34. Firebase Health: GET /api/v2/tiqer/firebase/health/ - Firebase connectivity status
35. Firebase Init: POST /api/v2/tiqer/firebase/init/ - Manual Firebase initialization
{
"status": "SUCCESS",
"data": { /* response data */ },
"message": "Operation completed successfully"
}{
"status": "FAILURE",
"error_message": "Human readable error message",
"error_code": "ERROR_CODE_CONSTANT",
"errors": {
"field_name": ["Field-specific error messages"]
}
}SESSION_NOT_FOUND: Session does not existACCESS_DENIED: Insufficient permissionsDUPLICATE_RESPONSE: Response already submittedINVALID_ARUCO_DATA: ArUco marker validation failedCONNECTION_TIMEOUT: Device connection timeoutFIREBASE_SYNC_ERROR: Firebase synchronization failedCONFLICT_RESOLUTION_FAILED: Automatic conflict resolution failed
- Heartbeat API: Maximum 2 requests per second per device
- Response API: Optimized for 50+ concurrent submissions
- Analytics API: Cached responses (30 second cache for live data)
- Dashboard API: Cached responses (60 second cache)
- Session Data: 60 second cache
- Classroom Data: 5 minute cache
- Live Analytics: 30 second cache
- Device Status: 15 second cache