This section covers QR code generation, check-in processes, and attendee tracking functionality.
The check-in system provides QR code-based attendance tracking with mobile scanning capabilities and offline fallback support for seamless event management.
{
"id": 1,
"eventId": 1,
"userId": 1,
"rsvpId": 1,
"qrCode": "EVT001-USR001-CHK001",
"qrCodeData": {
"eventId": 1,
"userId": 1,
"rsvpId": 1,
"checksum": "abc123",
"expiresAt": "2024-12-01T23:59:59Z"
},
"checkedIn": true,
"checkedInAt": "2024-12-01T08:45:00Z",
"checkedInBy": {
"id": 2,
"name": "Staff Member",
"role": "STAFF"
},
"checkInMethod": "QR_SCAN", // QR_SCAN, MANUAL, BULK
"location": "Main Entrance",
"deviceId": "scanner-001",
"notes": "VIP guest, special seating",
"validated": true,
"validationErrors": [],
"metadata": {
"scanDuration": 1.2, // seconds
"scanAttempts": 1,
"ipAddress": "192.168.1.100"
}
}Generate QR code for specific user's event check-in.
Headers:
Authorization: Bearer <your-jwt-token>Path Parameters:
eventId(integer): Event IDuserId(integer): User ID (optional, defaults to current user)
Response (200 OK):
{
"success": true,
"data": {
"qrCode": "EVT001-USR001-CHK001",
"qrCodeImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
"qrCodeUrl": "https://api.eventra.com/checkin/EVT001-USR001-CHK001",
"expiresAt": "2024-12-01T23:59:59Z",
"rsvp": {
"id": 1,
"status": "confirmed",
"ticketTier": "General Admission"
}
}
}Scan QR code and check in attendee.
Headers:
Authorization: Bearer <your-jwt-token>Path Parameters:
eventId(integer): Event ID
Request Body:
{
"qrCode": "EVT001-USR001-CHK001",
"location": "Main Entrance",
"deviceId": "scanner-001",
"notes": "VIP guest, special seating"
}Response (200 OK):
{
"success": true,
"data": {
"checkIn": {
// Complete check-in object
},
"attendee": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"ticketTier": "General Admission",
"specialRequests": "Vegetarian meal"
},
"firstTimeCheckIn": true
},
"message": "Check-in successful"
}Error Response (400 Bad Request) - Already Checked In:
{
"success": false,
"error": {
"code": "ALREADY_CHECKED_IN",
"message": "User is already checked in",
"details": {
"checkedInAt": "2024-12-01T08:30:00Z",
"checkedInBy": "Staff Member"
}
}
}Manually check in attendee (fallback for QR issues).
Headers:
Authorization: Bearer <your-jwt-token>Path Parameters:
eventId(integer): Event ID
Request Body:
{
"identifier": "john@example.com", // Email, phone, or name
"location": "Main Entrance",
"reason": "QR code not working",
"notes": "Manual check-in due to technical issues"
}Response (200 OK):
{
"success": true,
"data": {
"checkIn": {
// Check-in object
},
"attendee": {
// Attendee details
},
"matchedBy": "email" // How attendee was identified
},
"message": "Manual check-in successful"
}Get real-time check-in statistics.
Headers:
Authorization: Bearer <your-jwt-token>Path Parameters:
eventId(integer): Event ID
Response (200 OK):
{
"success": true,
"data": {
"overview": {
"totalExpected": 245,
"checkedIn": 180,
"checkInRate": 73.5,
"noShows": 65,
"walkIns": 5
},
"timeline": [
{
"hour": "08:00",
"checkedIn": 15,
"cumulative": 15
},
{
"hour": "09:00",
"checkedIn": 45,
"cumulative": 60
}
],
"byTicketTier": [
{
"tierName": "General Admission",
"expected": 180,
"checkedIn": 135,
"rate": 75.0
},
{
"tierName": "VIP",
"expected": 65,
"checkedIn": 45,
"rate": 69.2
}
],
"byLocation": [
{
"location": "Main Entrance",
"checkedIn": 120,
"percentage": 66.7
},
{
"location": "VIP Entrance",
"checkedIn": 60,
"percentage": 33.3
}
]
}
}Get list of checked-in attendees.
Headers:
Authorization: Bearer <your-jwt-token>Path Parameters:
eventId(integer): Event ID
Query Parameters:
page(integer): Page numberlimit(integer): Items per pagelocation(string): Filter by check-in locationtimeFrom(string): Filter check-ins from this timetimeTo(string): Filter check-ins until this timesearch(string): Search by attendee name or email
Response (200 OK):
{
"success": true,
"data": {
"checkIns": [
{
"id": 1,
"attendee": {
"name": "John Doe",
"email": "john@example.com",
"ticketTier": "General Admission"
},
"checkedInAt": "2024-12-01T08:45:00Z",
"location": "Main Entrance",
"checkedInBy": "Staff Member",
"method": "QR_SCAN"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 180
}
}
}Bulk check-in multiple attendees.
Headers:
Authorization: Bearer <your-jwt-token>Path Parameters:
eventId(integer): Event ID
Request Body:
{
"attendees": [
{
"identifier": "john@example.com",
"location": "Main Entrance"
},
{
"identifier": "jane@example.com",
"location": "Main Entrance"
}
],
"reason": "Pre-registration check-in",
"notes": "Bulk check-in for pre-registered attendees"
}Response (200 OK):
{
"success": true,
"data": {
"successful": 8,
"failed": 2,
"results": [
{
"identifier": "john@example.com",
"success": true,
"checkIn": {
// Check-in object
}
},
{
"identifier": "unknown@example.com",
"success": false,
"error": "Attendee not found"
}
]
},
"message": "Bulk check-in completed"
}Undo check-in (check out attendee).
Headers:
Authorization: Bearer <your-jwt-token>Path Parameters:
eventId(integer): Event IDuserId(integer): User ID
Request Body:
{
"reason": "Left early due to emergency",
"notes": "Family emergency, left at 2 PM"
}Response (200 OK):
{
"success": true,
"message": "Check-in undone successfully"
}Export check-in data to various formats.
Headers:
Authorization: Bearer <your-jwt-token>Path Parameters:
eventId(integer): Event ID
Query Parameters:
format(string): Export format (csv, xlsx, pdf)timeFrom(string): Start time for exporttimeTo(string): End time for exportincludeNoShows(boolean): Include attendees who didn't check in
Response (200 OK):
Content-Type: text/csv
Content-Disposition: attachment; filename="checkin-report-2024-12-01.csv"
Name,Email,Ticket Tier,Checked In,Check-in Time,Location,Staff Member
John Doe,john@example.com,General Admission,Yes,2024-12-01 08:45:00,Main Entrance,Staff Member
Jane Smith,jane@example.com,VIP,Yes,2024-12-01 08:50:00,VIP Entrance,Staff Member
Bob Johnson,bob@example.com,General Admission,No,,,Get list of check-in devices and their status.
Headers:
Authorization: Bearer <your-jwt-token>Path Parameters:
eventId(integer): Event ID
Response (200 OK):
{
"success": true,
"data": {
"devices": [
{
"deviceId": "scanner-001",
"name": "Main Entrance Scanner",
"location": "Main Entrance",
"status": "online",
"lastSeen": "2024-12-01T09:00:00Z",
"checkInsToday": 85,
"operator": {
"id": 2,
"name": "Staff Member"
},
"batteryLevel": 78,
"networkStrength": "strong"
}
],
"summary": {
"totalDevices": 3,
"onlineDevices": 2,
"offlineDevices": 1,
"totalCheckIns": 180
}
}
}QR codes contain encrypted data with the following structure:
{
"eventId": 1,
"userId": 1,
"rsvpId": 1,
"timestamp": 1640995200,
"checksum": "abc123def456",
"version": "v1"
}- QR_SCAN: Standard QR code scanning
- MANUAL: Manual check-in by staff
- BULK: Bulk check-in operation
- WALK_IN: Walk-in attendee (no prior registration)
- AUTO: Automated check-in (geo-fence, NFC, etc.)
- MOBILE_APP: Staff mobile app scanner
- TABLET: Dedicated tablet scanner
- KIOSK: Self-service kiosk
- HARDWARE: Dedicated hardware scanner
- WEB: Web-based scanner
The check-in system supports offline operation:
- Cache attendee list on device
- Store check-ins locally when offline
- Sync when connection restored
- Conflict resolution for duplicate check-ins
- Offline QR validation using cached data
- QR code encryption: All QR codes are encrypted and time-limited
- Device authentication: Check-in devices must be authorized
- Audit logging: All check-in actions are logged
- Rate limiting: Prevents rapid-fire scanning abuse
- Duplicate detection: Prevents multiple check-ins
- Staff permissions: Role-based access to check-in functions
Check-in data is updated in real-time using WebSocket connections:
// WebSocket endpoint for real-time check-in updates
wss://api.eventra.com/events/1/checkin/stream
// Message format
{
"type": "CHECKIN_SUCCESS",
"data": {
"attendee": { /* attendee data */ },
"checkIn": { /* check-in data */ },
"stats": { /* updated stats */ }
}
}| Code | Description |
|---|---|
INVALID_QR_CODE |
QR code is invalid or corrupted |
EXPIRED_QR_CODE |
QR code has expired |
ALREADY_CHECKED_IN |
Attendee is already checked in |
ATTENDEE_NOT_FOUND |
Attendee not found for this event |
INVALID_RSVP_STATUS |
RSVP status doesn't allow check-in |
DEVICE_NOT_AUTHORIZED |
Check-in device is not authorized |
EVENT_NOT_STARTED |
Event hasn't started yet |
EVENT_ENDED |
Event has already ended |
LOCATION_MISMATCH |
Check-in location doesn't match ticket |
DUPLICATE_SCAN |
Same QR code scanned multiple times |