Skip to main content

Attendance Analytics API

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

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

Short Description: The Attendance AnalyticsManagement API provides comprehensive attendee tracking and analytics for event organizers. ThisOrganizers API enables organizers tocan view overall attendance statistics with per-day and per-ticket-type breakdowns, browse a unified attendance list all(present, checked-absent, and partially attended in attendeesone view) with filters,rich track absentees by category (full no-shows vs specific-day absences),filtering, and viewdrill detailedinto the full check-in history for any individual attendees.ticket. The system supports multi-day events with separate tracking per single-day and providesmulti-day real-timeevents. attendanceAll metrics.status filtering, day filtering, buyer-type filtering, and search are handled through query parameters on a single list endpoint.

Hints:

  • Organizer Only: All endpoints restricted to the event organizersorganizer
  • Unified List: Present and absent tickets are in one list — filter with ?status=PRESENT|ABSENT|PARTIALLY_ATTENDED
  • Ticket-Based: Each row in the list is one ticket, not one person — one buyer can appear multiple times
  • Attendee Number: Each ticket has a unique attendeeNumber = bookingReference + "-" + ticketSeries (e.g. EVT-A3F4B21C-VIP-0042)
  • Buyer vs Attendee: buyer = who paid, attendee = who holds the ticket — can be different people
  • Buyer Types: SYSTEM_USER = bought online, AT_DOOR = name captured at door (no account)
  • Multi-Day Support: Per-day statisticsfiltering andvia filtering?dayNumber=1 — optional, omit for overall view
  • Real-TimePartial Attendance: UpdatesPARTIALLY_ATTENDED instantly= afterchecked check-ins
  • in
  • Absenteesome Categories:days FULL_NO_SHOW,but SPECIFIC_DAY_ONLY,not ALL
  • all
  • Ticket(multi-day Typeevents Filter: Filter by specific ticket types
  • Search: Search attendees by name/emailonly)
  • Pagination: ListsDefault paginated (default 5020 per page)
  • Check-In History: Complete per-day check-in records
  • Attendance Patterns: Tracks which days attended/absentpage

Response Structures

AttendanceStatsResponseAttendanceSummaryResponse

Returned by GET /summary. Always covers the full event — no filtering.

{
  "eventId": "uuid",
  "eventTitle": "East African Tech Summit 2025"2026",
  "totalDays": 3,
  "eventSchedule": [
    { "dayNumber": 1, "dayName": "Day 1 - Opening",    "date": "2025-2026-12-15" },
    { "dayNumber": 2, "dayName": "Day 2 - Conference", "date": "2025-2026-12-16" },
    { "dayNumber": 3, "dayName": "Day 3 - Closing",    "date": "2025-2026-12-17" }
  ],
  "overallStats": {
    "totalTickets": 500,
    "totalCheckedIn"present": 462,310,
    "totalAbsent"partiallyAttended": 38,45,
    "absent": 145,
    "attendanceRate": 92.4,71.0,
    "byDay": [
      {
        "dayNumber": 1,
        "dayName": "Day 1 - Opening",
        "date": "2025-2026-12-15",
        "totalTickets": 500,
        "checkedIn": 475,400,
        "absent": 25,100,
        "attendanceRate": 95.80.0,
        "status": "COMPLETED"
      },
      {
        "dayNumber": 2,
        "dayName": "Day 2 - Conference",
        "date": "2026-12-16",
        "totalTickets": 500,
        "checkedIn": 355,
        "absent": 145,
        "attendanceRate": 71.0,
        "status": "ONGOING"
      },
      {
        "dayNumber": 3,
        "dayName": "Day 3 - Closing",
        "date": "2026-12-17",
        "totalTickets": 500,
        "checkedIn": 0,
        "absent": 500,
        "attendanceRate": 0.0,
        "status": "UPCOMING"
      }
    ]
  },
  "byTicketType": [
    {
      "ticketTypeId": "uuid",
      "ticketTypeName": "VIP Pass",
      "totalSold": 100,
      "totalCheckedIn"present": 98,75,
      "totalAbsent"partiallyAttended": 2,10,
      "absent": 15,
      "attendanceRate": 98.85.0,
      "byDay": [
        {
          "dayNumber": 1,
          "dayName": "Day 1 - Opening",
          "checkedIn": 99,90,
          "absent": 1,10,
          "attendanceRate": 99.90.0
        }
      ]
    }
  ]
}

AttendeeListResponseAttendanceListResponse

Returned by GET /list. Reflects applied filters. summary always covers the filtered scope. partiallyAttended only appears when no dayNumber filter is set on a multi-day event.

{
  "eventId": "uuid",
  "eventTitle": "East African Tech Summit 2025"2026",

  "appliedFilters": {
    "ticketTypeId": "uuid",
    "ticketTypeName": "VIP Pass",
    "status": "ALL",
    "dayNumber": 1,
    "dayName": "Day 1 - Opening",
    "dayDate"buyerType": "2025-12-15"ALL",
    "ticketTypeId"search": "uuid",null
  "ticketTypeName": "VIP Pass"},

  "summary": {
    "totalTicketsForType"totalTickets": 100,
    "checkedInThisDay"present": 9990,
    "absent": 10,
    "partiallyAttended": null,
    "attendanceRate": 90.0
  },

  "attendees": [
    {
      "ticketInstanceId": "uuid",
      "attendeeNumber": "EVT-A3F4B21C-VIP-0042",
      "ticketTypeId": "uuid",
      "ticketType": "VIP Pass",
      "ticketSeries": "VIP-0042",

      "attendeeName": "John Doe",
      "attendeeEmail": "john@example.com",
      "attendeePhone": "+255712345678",

      "buyer": {
        "buyerName": "Jane Doe",
        "buyerEmail": "jane@example.com",
        "buyerId": "uuid",
        "buyerType": "SYSTEM_USER"
      },

      "bookingReference": "EVT-A3F4B21C",
      "pricePaid": 150.00,

      "attendanceStatus": "PRESENT",
      "checkInTime": "2026-12-15T09:15:00+03:00",
      "checkInLocation": "Main Gate",
      "checkedInBy": "Scanner Operator 1",
      "scannerId": "uuid-string"
    },
    {
      "ticketInstanceId": "uuid-2",
      "attendeeNumber": "EVT-B5D2E12F-GENE-0101",
      "ticketType": "General Admission",
      "ticketSeries": "GENE-0101",

      "attendeeName": "Ali Hassan",
      "attendeeEmail": null,
      "attendeePhone": null,

      "buyer": {
        "buyerName": "Ali Hassan",
        "buyerEmail": null,
        "buyerId": null,
        "buyerType": "AT_DOOR"
      },

      "bookingReference": "EVT-B5D2E12F",
      "pricePaid": 50.00,

      "attendanceStatus": "ABSENT",
      "checkInTime": null,
      "checkInLocation": null,
      "checkedInBy": null,
      "scannerId": null
    }
  ],

  "pagination": {
    "currentPage": 0,
    "pageSize": 20,
    "totalPages": 5,
    "totalElements": 100,
    "hasNext": true,
    "hasPrevious": false
  }
}

AttendeeDetailResponse

Returned by GET /attendees/{ticketInstanceId}. Full per-day check-in history for one ticket.

{
  "ticketInstanceId": "uuid",
  "attendeeNumber": "EVT-A3F4B21C-VIP-0042",
  "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"PARTIALLY_ATTENDED",
  "daysAttended": 3,2,
  "daysTotal": 3,
  "checkInsByDay": [
    {
      "dayNumber": 1,
      "dayName": "Day 1 - Opening",
      "dayDate": "2025-2026-12-15",
      "status": "CHECKED_IN",
      "checkInTime": "2025-2026-12-15T09:15:00+03:00",
      "checkInLocation": "Main Gate",
      "checkedInBy": "Scanner Operator 1",
      "scannerId": "uuid-string"
    },
    {
      "dayNumber": 2,
      "dayName": "Day 2 - Conference",
      "dayDate": "2025-2026-12-16",
      "status": "CHECKED_IN"NOT_CHECKED_IN",
      "checkInTime": "2025-12-16T08:45:00+03:00",null,
      "checkInLocation": "VIP Entrance",null,
      "checkedInBy": "Scanner Operator 2",null,
      "scannerId": "uuid-string"null
    },
    {
      "dayNumber": 3,
      "dayName": "Day 3 - Closing",
      "dayDate": "2025-2026-12-17",
      "status": "CHECKED_IN"UPCOMING",
      "checkInTime": "2025-12-17T09:00:00+03:00",null,
      "checkInLocation": "Main Gate",null,
      "checkedInBy": "Scanner Operator 1",null,
      "scannerId": "uuid-string"null
    }
  ]
}

Endpoints

1. Get Attendance StatsSummary

Endpoint: GET /attendance/{eventId}/statssummary

Access: 🔒 Event Organizer Only

Path Parameters:

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

Success Response: Returns AttendanceStatsResponseAttendanceSummaryResponse

Success Response Message: "Attendance statssummary retrieved"

Behavior:

  • Validates organizer owns the event
  • CalculatesReturns overall attendance metrics across all tickets
  • Breaks down by day (multi-dayall events)events, including single-day)
  • Breaks down by ticket type with per-day stats
  • Real-timepresent from= check-checked in datafor all days, partiallyAttended = some days, absent = none
  • attendanceRate includes both present and partiallyAttended tickets

Errors:

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

2. Get AttendeesAttendance List

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

Access: 🔒 Event Organizer Only

Path Parameters:

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

Query Parameters:

Parameter Type Required Description
statusenumNoPRESENT, ABSENT, PARTIALLY_ATTENDED — omit for all
dayNumber integer Multi-day: YesNo DayFilter numberfor a specific day (1, 2, 3...) — omit for overall view
ticketTypeId string (UUID) No Filter by ticket type
buyerTypeenumNoSYSTEM_USER, AT_DOOR — omit for all
search string No Search by name/emailattendee name, email, or phone (partial, case-insensitive)
page integer No Page number (0-indexed, default: 0)0)
size integer No Items per page (default: 50)20)

Success Response: Returns AttendeeListResponseAttendanceListResponse with pagination

Success Response Message: "AttendeesAttendance list retrieved"

Behavior:

  • ListsReturns checked-inone attendeesrow per ticket (not per person)
  • One buyer can appear multiple times if they purchased multiple tickets
  • attendeeNumber = bookingReference + "-" + ticketSeries (unique per ticket)
  • When dayNumber is set: attendanceStatus is PRESENT or ABSENT for specifiedthat specific day
  • FiltersWhen bydayNumber ticketis typeomitted: ifattendanceStatus providedreflects overall across all days (PARTIALLY_ATTENDED possible)
  • Searchessummary byblock name/emailalways ifreflects providedthe current filter scope (not the full event)
  • PaginatedpartiallyAttended results
  • Shows check-in detailssummary is null when a dayNumber filter is active

Validation:

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

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:

ParameterTypeRequiredDescription
eventIdstring (UUID)YesEvent identifier

Query Parameters:

ParameterTypeRequiredDescription
dayNumberintegerMulti-day: YesDay number (1, 2, 3...)
ticketTypeIdstring (UUID)NoFilter by ticket type
categoryenumNoALL, FULL_NO_SHOW, SPECIFIC_DAY_ONLY (default: ALL)
searchstringNoSearch by name/email
pageintegerNoPage number (0-indexed, default: 0)
sizeintegerNoItems per page (default: 50)

Success Response: Returns AbsenteeListResponse with pagination

Success Response Message: "Absentees retrieved"

BehaviorErrors:

  • Lists403 NOTFORBIDDEN: checked-inNot attendeesevent for specified dayorganizer
  • Categories:404
    • ALLNOT_FOUND: EveryoneEvent not checked-infound for/ thisinvalid day
    • FULL_NO_SHOW:number Never/ checked-inticket any day
    • SPECIFIC_DAY_ONLY: Attended other days buttype not this one
  • Shows attendance patterns
  • Paginated results

Absentee Breakdown:

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

4.3. 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 TicketIndividual ticket instance identifier

Success Response: Returns AttendeeDetailResponse

Success Response Message: "Attendee detail retrieved"

Behavior:

  • ShowsReturns completethe full check-in history for one specific ticket across all event days
  • Per-overallStatus computed from all days
  • checkInsByDay lists every event day with its status (CHECKED_IN,and NOT_CHECKED_IN,check-in UPCOMING)details
  • Overall attendanceDay status
  • Check-inreflects detailswhether (time,the location,day scanner)has passed, is today, or is upcoming

Overall StatusErrors:

  • FULLY_ATTENDED403 FORBIDDEN: Checked-inNot allevent daysorganizer
  • PARTIALLY_ATTENDED404 NOT_FOUND: Checked-inEvent someor days
  • ticket
  • NOT_ATTENDED:not Never checked-infound

AbsenteeKey Categories ExplainedConcepts

ALLAttendee (Default)Number

Every ticket has a unique attendeeNumber formatted as:

{bookingReference}-{ticketSeries}

WhoExample: EveryoneEVT-A3F4B21C-VIP-0042

Use this as the primary human-readable identifier for a ticket on the attendance list — safer than ticketInstanceId (UUID) for display and manual lookup.


Buyer vs Attendee

These are two different people on the same ticket:

FieldWho
attendeeName / attendeeEmailThe person who didn'twill checkattend (holds the ticket)
buyer.buyerName / buyer.buyerEmailThe person who paid

Example: Jane buys 3 VIP tickets. She is the buyer on all 3. The attendees are John, Ali, and herself.

One buyer can appear multiple times 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'sonce missingper todayticket they purchased.


FULL_NO_SHOWBuyer Types

Who

ValueMeaning
SYSTEM_USERBought online — has a platform account, buyerId is populated
AT_DOORWalk-in sale — only name captured at door, buyerEmail and buyerId are null

Attendance Status

forANYeventday

specific
ValueMeaningWhen
PRESENTChecked inWith dayNumber: Ticketschecked in that day. Without: checked in all days
ABSENTNot checked inWith dayNumber: not that day. Without: never checked-checked in
PARTIALLY_ATTENDED Checked

Characteristics:

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

Use Case: Identify completely unused tickets for follow-up

SPECIFIC_DAY_ONLY

Who: Attendedin some days but NOTnot thisall

Only possible without dayNumber filter, on multi-day events

Day Status (in detail view)

ValueMeaning
CHECKED_INScanned on that day
NOT_CHECKED_INDay has passed, was not scanned
UPCOMINGDay has not happened yet

Attendance Rate Calculation

attendanceRate = ((present + partiallyAttended) / totalTickets) × 100

Rounded to 2 decimal places.

CharacteristicsPer-day rate:

  • Checked-(in onsummary other event days
  • Partial attendance
  • Shows attendance pattern

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

ExamplebyDay):

3-Dayrate Festival:
- Ticket A: Attended Day 1, 2, 3 → FULLY_ATTENDED
- Ticket B: Attended Day 1, 3= (missed Day 2) → SPECIFIC_DAY_ONLYcheckedIn for Daythat 2day -/ TickettotalTickets) C:× Never attended → FULL_NO_SHOW for all days100

Multi-Day Event Logic

Day NumberFilter RequirementsBehaviour

dayNumberStatus scope
Provided (e.g. ?dayNumber=2)Status = did this ticket check in on Day 2? (PRESENT or ABSENT only)
OmittedStatus = overall across all days (PRESENT, ABSENT, or PARTIALLY_ATTENDED)

Single-Day Events:

number
  • 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

Validationvalidation:

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

Per-Day Tracking

Statistics:

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

Day Status:

  • COMPLETEDevents: Day has passed
  • ONGOING: DaydayNumber is today
  • always
  • UPCOMING:optional. DayOmitting hasn'tit started
  • gives
the

Example:same result as ?dayNumber=1.

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}/summary

Use: top-of-page stats card
Shows: -overall Overallrate, attendance rate
- Per-per-day breakdownbreakdown, - Per-per-ticket-type breakdown
-
Real-time

Full metricsAttendance Table

GET /attendance/{eventId}/list

Use: default organizer table view — all tickets, all statuses

Check Who Attended Today (Day 2)

GET /attendance/{eventId}/list?dayNumber=2&status=PRESENT

Shows: tickets checked in on Day 2

Who Missed Today

GET /attendance/{eventId}/attendees?list?dayNumber=12&status=ABSENT

Shows: -tickets Allthat checked-didn't check in attendees foron Day 12 -(regardless Check-inof timesother and locations
- Searchable and filterabledays)

FindAt-Door No-ShowsWalk-Ins Only

GET /attendance/{eventId}/absentees?dayNumber=1&category=FULL_NO_SHOWlist?buyerType=AT_DOOR

Shows: -all Ticketstickets thatsold wereat neverthe used
- For follow-up or refund processingdoor

TrackPartially PartialAttended Attendance(Multi-Day)

GET /attendance/{eventId}/absentees?dayNumber=2&category=SPECIFIC_DAY_ONLYlist?status=PARTIALLY_ATTENDED

Shows: -tickets Whothat attended Daysome 1days but missednot Dayall
2Requires: -no UsefuldayNumber forfilter
understanding
engagement

Search patternsby Name

GET /attendance/{eventId}/list?search=john

Matches: attendee name, email, or phone containing "john"

Individual Ticket History

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

Shows: -full Completeper-day check-in historyrecord -for Whichone days attended/missed
- Check-in details per dayticket

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 requestSuccess
  • 401 UNAUTHORIZED: AuthenticationNot requiredauthenticated
  • 403 FORBIDDEN: Not the event organizer
  • 404 NOT_FOUND: Event/Event / ticket / day number not found

Attendance Status Values

  • FULLY_ATTENDED:PRESENT All— attended (all days checked-inif no day filter)
  • ABSENT — did not attend
  • PARTIALLY_ATTENDED: Some— attended some days checked-in
  • (multi-day,
  • NOT_ATTENDED:no Neverday checked-infilter)

Day Status Values

  • COMPLETED: Day— day has passed
  • ONGOING: Day— day is today
  • UPCOMING: Day hasn'tday has not started

AbsenteeBuyer CategoriesType Values

  • ALL:SYSTEM_USER All absenteesonline forpurchase, thishas dayplatform account
  • FULL_NO_SHOW:AT_DOOR Never attendedwalk-in, anyname day
  • only,
  • SPECIFIC_DAY_ONLY:no Missed this day onlyaccount

Default

Conclusion

Pagination

The

    Attendance Analytics API provides comprehensive tracking with:

    Real-Time Stats

  • page: Instant0 attendance(first metrics
    page)
  • Multi-Day Support
  • size: Per-day20 breakdowns
    items per Absenteepage
  • 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