Skip to main content

Attendance Analytics API

Author: Josh, Lead Backend Team
Last Updated: 2025-12-11
Version: v1.0

Base URL: https://api.nexgate.com/api/v1

Short Description: The Attendance Analytics API provides comprehensive attendee tracking and analytics for event organizers. This API enables organizers to view attendance statistics with per-day breakdowns, list all checked-in attendees with filters, track absentees by category (full no-shows vs specific-day absences), and view detailed check-in history for individual attendees. The system supports multi-day events with separate tracking per day and provides real-time attendance metrics.

Hints:

  • Organizer Only: All endpoints restricted to event organizers
  • Multi-Day Support: Per-day statistics and filtering
  • Real-Time: Updates instantly after check-ins
  • Absentee Categories: FULL_NO_SHOW, SPECIFIC_DAY_ONLY, ALL
  • Ticket Type Filter: Filter by specific ticket types
  • Search: Search attendees by name/email
  • Pagination: Lists paginated (default 50 per page)
  • Check-In History: Complete per-day check-in records
  • Attendance Patterns: Tracks which days attended/absent

Response Structures

AttendanceStatsResponse

{
  "eventId": "uuid",
  "eventTitle": "East African Tech Summit 2025",
  "totalDays": 3,
  "eventSchedule": [
    {"dayNumber": 1, "dayName": "Day 1 - Opening", "date": "2025-12-15"},
    {"dayNumber": 2, "dayName": "Day 2 - Conference", "date": "2025-12-16"},
    {"dayNumber": 3, "dayName": "Day 3 - Closing", "date": "2025-12-17"}
  ],
  "overallStats": {
    "totalTickets": 500,
    "totalCheckedIn": 462,
    "totalAbsent": 38,
    "attendanceRate": 92.4,
    "byDay": [
      {
        "dayNumber": 1,
        "dayName": "Day 1 - Opening",
        "date": "2025-12-15",
        "totalTickets": 500,
        "checkedIn": 475,
        "absent": 25,
        "attendanceRate": 95.0,
        "status": "COMPLETED"
      }
    ]
  },
  "byTicketType": [
    {
      "ticketTypeId": "uuid",
      "ticketTypeName": "VIP Pass",
      "totalSold": 100,
      "totalCheckedIn": 98,
      "totalAbsent": 2,
      "attendanceRate": 98.0,
      "byDay": [
        {
          "dayNumber": 1,
          "dayName": "Day 1 - Opening",
          "checkedIn": 99,
          "absent": 1,
          "attendanceRate": 99.0
        }
      ]
    }
  ]
}

AttendeeListResponse

{
  "eventId": "uuid",
  "eventTitle": "East African Tech Summit 2025",
  "dayNumber": 1,
  "dayName": "Day 1 - Opening",
  "dayDate": "2025-12-15",
  "ticketTypeId": "uuid",
  "ticketTypeName": "VIP Pass",
  "summary": {
    "totalTicketsForType": 100,
    "checkedInThisDay": 99
  },
  "attendees": [
    {
      "ticketInstanceId": "uuid",
      "attendeeName": "John Doe",
      "attendeeEmail": "john@example.com",
      "attendeePhone": "+255712345678",
      "ticketType": "VIP Pass",
      "ticketSeries": "VIP-0001",
      "bookingReference": "EVT-A3F4B21C",
      "pricePaid": 150.00,
      "checkInTime": "2025-12-15T09:15:00+03:00",
      "checkInLocation": "Main Gate",
      "checkedInBy": "Scanner Operator 1",
      "scannerId": "uuid-string"
    }
  ],
  "pagination": {
    "currentPage": 0,
    "pageSize": 50,
    "totalPages": 2,
    "totalElements": 99,
    "hasNext": true,
    "hasPrevious": false
  }
}

AbsenteeListResponse

{
  "eventId": "uuid",
  "eventTitle": "East African Tech Summit 2025",
  "dayNumber": 1,
  "dayName": "Day 1 - Opening",
  "dayDate": "2025-12-15",
  "ticketTypeId": null,
  "ticketTypeName": null,
  "summary": {
    "totalTicketsForType": 500,
    "absentThisDay": 25,
    "absenteeRate": 5.0,
    "breakdown": {
      "fullNoShow": 10,
      "specificDayOnly": 15
    }
  },
  "absentees": [
    {
      "ticketInstanceId": "uuid",
      "attendeeName": "Jane Smith",
      "attendeeEmail": "jane@example.com",
      "attendeePhone": "+255723456789",
      "ticketType": "General Admission",
      "ticketSeries": "GENER-0042",
      "bookingReference": "EVT-B5D2E12F",
      "pricePaid": 50.00,
      "statusForThisDay": "NOT_CHECKED_IN",
      "attendancePattern": {
        "totalEventDays": 3,
        "daysAttended": 2,
        "daysAbsent": 1,
        "attendedDayNumbers": [2, 3],
        "absentDayNumbers": [1],
        "category": "SPECIFIC_DAY_ONLY"
      }
    }
  ],
  "pagination": {
    "currentPage": 0,
    "pageSize": 50,
    "totalPages": 1,
    "totalElements": 25,
    "hasNext": false,
    "hasPrevious": false
  }
}

AttendeeDetailResponse

{
  "ticketInstanceId": "uuid",
  "attendeeName": "John Doe",
  "attendeeEmail": "john@example.com",
  "attendeePhone": "+255712345678",
  "ticketType": "VIP Pass",
  "ticketSeries": "VIP-0001",
  "bookingReference": "EVT-A3F4B21C",
  "pricePaid": 150.00,
  "overallStatus": "FULLY_ATTENDED",
  "daysAttended": 3,
  "daysTotal": 3,
  "checkInsByDay": [
    {
      "dayNumber": 1,
      "dayName": "Day 1 - Opening",
      "dayDate": "2025-12-15",
      "status": "CHECKED_IN",
      "checkInTime": "2025-12-15T09:15:00+03:00",
      "checkInLocation": "Main Gate",
      "checkedInBy": "Scanner Operator 1",
      "scannerId": "uuid-string"
    },
    {
      "dayNumber": 2,
      "dayName": "Day 2 - Conference",
      "dayDate": "2025-12-16",
      "status": "CHECKED_IN",
      "checkInTime": "2025-12-16T08:45:00+03:00",
      "checkInLocation": "VIP Entrance",
      "checkedInBy": "Scanner Operator 2",
      "scannerId": "uuid-string"
    },
    {
      "dayNumber": 3,
      "dayName": "Day 3 - Closing",
      "dayDate": "2025-12-17",
      "status": "CHECKED_IN",
      "checkInTime": "2025-12-17T09:00:00+03:00",
      "checkInLocation": "Main Gate",
      "checkedInBy": "Scanner Operator 1",
      "scannerId": "uuid-string"
    }
  ]
}

Endpoints

1. Get Attendance Stats

Endpoint: GET /attendance/{eventId}/stats

Access: 🔒 Event Organizer Only

Path Parameters:

Parameter Type Required Description
eventId string (UUID) Yes Event identifier

Success Response: Returns AttendanceStatsResponse

Success Response Message: "Attendance stats retrieved"

Behavior:

  • Validates organizer owns event
  • Calculates overall attendance metrics
  • Breaks down by day (multi-day events)
  • Breaks down by ticket type
  • Real-time from check-in data

Errors:

  • 403 FORBIDDEN: Not event organizer
  • 404 NOT_FOUND: Event not found

2. Get Attendees

Endpoint: GET /attendance/{eventId}/attendees?dayNumber=1&ticketTypeId=uuid&search=john&page=0&size=50

Access: 🔒 Event Organizer Only

Path Parameters:

Parameter Type Required Description
eventId string (UUID) Yes Event identifier

Query Parameters:

Parameter Type Required Description
dayNumber integer Multi-day: Yes Day number (1, 2, 3...)
ticketTypeId string (UUID) No Filter by ticket type
search string No Search by name/email
page integer No Page number (0-indexed, default: 0)
size integer No Items per page (default: 50)

Success Response: Returns AttendeeListResponse with pagination

Success Response Message: "Attendees retrieved"

Behavior:

  • Lists checked-in attendees for specified day
  • Filters by ticket type if provided
  • Searches by name/email if provided
  • Paginated results
  • Shows check-in details

Validation:

  • Multi-day events require dayNumber
  • Ticket type must belong to event
  • Day number must be valid (1 to totalDays)

3. Get Absentees

Endpoint: GET /attendance/{eventId}/absentees?dayNumber=1&ticketTypeId=uuid&category=FULL_NO_SHOW&search=jane&page=0&size=50

Access: 🔒 Event Organizer Only

Path Parameters:

Parameter Type Required Description
eventId string (UUID) Yes Event identifier

Query Parameters:

Parameter Type Required Description
dayNumber integer Multi-day: Yes Day number (1, 2, 3...)
ticketTypeId string (UUID) No Filter by ticket type
category enum No ALL, FULL_NO_SHOW, SPECIFIC_DAY_ONLY (default: ALL)
search string No Search by name/email
page integer No Page number (0-indexed, default: 0)
size integer No Items per page (default: 50)

Success Response: Returns AbsenteeListResponse with pagination

Success Response Message: "Absentees retrieved"

Behavior:

  • Lists NOT checked-in attendees for specified day
  • Categories:
    • ALL: Everyone not checked-in for this day
    • FULL_NO_SHOW: Never checked-in any day
    • SPECIFIC_DAY_ONLY: Attended other days but not this one
  • Shows attendance patterns
  • Paginated results

Absentee Breakdown:

  • Full no-shows: Tickets never used
  • Specific day only: Partial attendance

4. Get Attendee Detail

Endpoint: GET /attendance/{eventId}/attendees/{ticketInstanceId}

Access: 🔒 Event Organizer Only

Path Parameters:

Parameter Type Required Description
eventId string (UUID) Yes Event identifier
ticketInstanceId string (UUID) Yes Ticket instance identifier

Success Response: Returns AttendeeDetailResponse

Success Response Message: "Attendee detail retrieved"

Behavior:

  • Shows complete check-in history
  • Per-day status (CHECKED_IN, NOT_CHECKED_IN, UPCOMING)
  • Overall attendance status
  • Check-in details (time, location, scanner)

Overall Status:

  • FULLY_ATTENDED: Checked-in all days
  • PARTIALLY_ATTENDED: Checked-in some days
  • NOT_ATTENDED: Never checked-in

Absentee Categories Explained

ALL (Default)

Who: Everyone who didn't check in for the specified day

Includes:

  • Full no-shows (never attended any day)
  • Specific-day absentees (attended other days)

Use Case: Complete list of who's missing today

FULL_NO_SHOW

Who: Tickets never checked-in for ANY event day

Characteristics:

  • Purchased ticket but never attended
  • 0% attendance rate
  • Wasted tickets

Use Case: Identify completely unused tickets for follow-up

SPECIFIC_DAY_ONLY

Who: Attended some days but NOT this specific day

Characteristics:

  • Checked-in on other event days
  • Partial attendance
  • Shows attendance pattern

Use Case: Identify who skipped specific days (e.g., missed keynote)

Example:

3-Day Festival:
- Ticket A: Attended Day 1, 2, 3 → FULLY_ATTENDED
- Ticket B: Attended Day 1, 3 (missed Day 2) → SPECIFIC_DAY_ONLY for Day 2
- Ticket C: Never attended → FULL_NO_SHOW for all days

Multi-Day Event Logic

Day Number Requirements

Single-Day Events:

  • dayNumber optional (defaults to 1)
  • Only one day to track

Multi-Day Events:

  • dayNumber REQUIRED
  • Must specify which day (1, 2, 3...)
  • System returns error if missing

Validation:

Event has 3 days → dayNumber must be 1, 2, or 3
Request dayNumber=5 → Error: "Invalid day 5. Valid: 1-3"

Per-Day Tracking

Statistics:

  • Total tickets (same for all days)
  • Checked-in (varies per day)
  • Absent (varies per day)
  • Attendance rate (varies per day)

Day Status:

  • COMPLETED: Day has passed
  • ONGOING: Day is today
  • UPCOMING: Day hasn't started

Example:

3-Day Event (Dec 15-17), Today: Dec 16

Day 1: status=COMPLETED, checkedIn=475
Day 2: status=ONGOING, checkedIn=450
Day 3: status=UPCOMING, checkedIn=0

Attendance Rate Calculations

Overall Attendance Rate

Rate = (Unique Tickets Checked-In / Total Tickets) × 100

Example:

  • Total tickets: 500
  • Tickets with at least one check-in: 462
  • Rate: 92.4%

Per-Day Attendance Rate

Rate = (Checked-In This Day / Total Tickets) × 100

Example:

  • Total tickets: 500
  • Checked-in Day 1: 475
  • Rate: 95.0%

Per-Ticket-Type Rate

Rate = (Checked-In for Type / Total Sold for Type) × 100

Example:

  • VIP tickets sold: 100
  • VIP checked-in: 98
  • Rate: 98.0%

Search Functionality

Searches:

  • Attendee name (case-insensitive)
  • Attendee email (case-insensitive)

Match: Partial match (contains)

Examples:

  • Search "john" → Matches "John Doe", "Johnny Smith", "john@example.com"
  • Search "@gmail" → Matches all Gmail addresses
  • Search "255712" → Matches phone numbers containing this

Use Cases

Dashboard Overview

GET /attendance/{eventId}/stats

Shows:
- Overall attendance rate
- Per-day breakdown
- Per-ticket-type breakdown
- Real-time metrics

Check Who Attended Today

GET /attendance/{eventId}/attendees?dayNumber=1

Shows:
- All checked-in attendees for Day 1
- Check-in times and locations
- Searchable and filterable

Find No-Shows

GET /attendance/{eventId}/absentees?dayNumber=1&category=FULL_NO_SHOW

Shows:
- Tickets that were never used
- For follow-up or refund processing

Track Partial Attendance

GET /attendance/{eventId}/absentees?dayNumber=2&category=SPECIFIC_DAY_ONLY

Shows:
- Who attended Day 1 but missed Day 2
- Useful for understanding engagement patterns

Individual Ticket History

GET /attendance/{eventId}/attendees/{ticketInstanceId}

Shows:
- Complete check-in history
- Which days attended/missed
- Check-in details per day

Best Practices

For Organizers

✅ Monitor attendance in real-time during event
✅ Follow up with full no-shows post-event
✅ Track partial attendance patterns
✅ Export attendee lists for post-event communications
✅ Use absentee data to improve future events

For Developers

✅ Require dayNumber for multi-day events
✅ Show attendance rate with 1 decimal (92.4%)
✅ Implement export to CSV functionality
✅ Cache stats (refresh every 5 minutes)
✅ Display check-in times in event timezone


Quick Reference

HTTP Status Codes

  • 200 OK: Successful request
  • 401 UNAUTHORIZED: Authentication required
  • 403 FORBIDDEN: Not event organizer
  • 404 NOT_FOUND: Event/ticket not found

Attendance Status

  • FULLY_ATTENDED: All days checked-in
  • PARTIALLY_ATTENDED: Some days checked-in
  • NOT_ATTENDED: Never checked-in

Day Status

  • COMPLETED: Day has passed
  • ONGOING: Day is today
  • UPCOMING: Day hasn't started

Absentee Categories

  • ALL: All absentees for this day
  • FULL_NO_SHOW: Never attended any day
  • SPECIFIC_DAY_ONLY: Missed this day only

Conclusion

The Attendance Analytics API provides comprehensive tracking with:

✅ Real-Time Stats: Instant attendance metrics
✅ Multi-Day Support: Per-day breakdowns
✅ Absentee Tracking: Full no-shows vs partial attendance
✅ Search & Filter: By ticket type, day, name/email
✅ Individual History: Complete check-in records
✅ Attendance Patterns: Understand engagement