---
name: livestorm-event-attendance-reconciliation
description: Reconcile who registered for a Livestorm event or session against who actually attended, flagging no-shows, early leavers, late joiners and data mismatches, as a read-only analysis. Use when the user asks who showed up, who registered but never joined, attendance rates, no-show follow-up lists, or whether registrations match attendance for a webinar or session.
---

# Reconcile registrations against attendance

The question is **who said they would come, who came, and where the two disagree**. This is analysis only. Its output is a list the user can act on later, not a change to the people database. Tagging and bulk registration belong to a different job; if the user wants those actions, say so and stop at the list.

## 1. Pin down the event and the session

Start with `livestorm_get_current_user` and `livestorm_get_organization` to confirm which account and workspace you are reading. Then identify the target with `livestorm_list_events` (search by name or date) and `livestorm_get_event`. Many events have several sessions: list them with `livestorm_list_event_sessions` and decide the scope:

- **One session** (the usual case for a recurring webinar): reconcile that session.
- **All sessions of one event**: attendance is per session, so a person can register once and attend a different session. Reconcile session by session, then merge the people across sessions.

If the user gives a vague name that matches several events, list the candidates and ask which one. Do not guess between a live event and its replay or a duplicate draft.

## 2. Pull both sides of the comparison

Two lists are needed, and they answer different questions:

- **Registrants:** `livestorm_list_event_people` for the event, or per session where that is the available scope. Use the filters and pagination the tool provides rather than fetching everything unfiltered.
- **Attendees:** `livestorm_get_session_person` (or `livestorm_get_event_person` for a single person) gives per-person detail, including join and leave data where the tool returns it. For many people, check first whether a list-style call returns attendance directly before calling per person. Fetching detail for every registrant one by one is slow and usually unnecessary.

Record the counts before analysing anything: registered, attended, and anyone with no attendance record at all. Keep these numbers; the output template needs them and they catch pagination mistakes. If the attendee count looks suspiciously round (exactly a page size), you have probably truncated. Paginate until the result is exhausted.

## 3. Classify each registrant

Sort everyone into one bucket. Use these definitions and state them in the report so the user can challenge them:

| Bucket | Rule |
|---|---|
| **Attended, full** | Joined and stayed for most of the session. |
| **Attended, partial** | Joined, left well before the end. Report the rough share of the session if join and leave times allow it. |
| **Late joiner** | Joined after the start. Matters for webinars that run a poll or Q&A at the opening. |
| **No-show** | Registered, no attendance record. |
| **Unregistered attendee** | Attended but is not in the registrant list. Usually a forwarded link, a different email, or a typo. Flag it. |

Do not treat "attended, partial" as a failure. Many people leave early for valid reasons. Their value is as a list for follow-up, not as a verdict.

## 4. Flag mismatches, then look for the cause

The findings that matter are the disagreements. Check each category before concluding anything:

- **Same person, two records.** Compare names and emails. Someone who registered as `jo@corp.com` and joined as `jo.smith@corp.com` is one attendee, not a no-show and an unregistered attendee. Merge them in the report and say that you did.
- **Case and whitespace differences** in emails are not real differences. Normalise before comparing.
- **Clusters of no-shows** tell a story. A whole company or domain absent suggests an invitation or firewall problem, not individual disinterest. Note the pattern.
- **Attendance with no registration** after a public link went out is expected. Flag the count, do not alarm on it.

## 5. Check the data itself before trusting it

Reconciliation is only as good as the timestamps. Before reporting attendance rates, check:

- The session's scheduled start and end, and whether the join/leave times fall inside that window. Times far outside it mean a time zone or session-selection error.
- Whether the session was cancelled, rescheduled or ran twice. A rescheduled session may have registrants tied to the old time.
- Whether the event is a replay. Replay viewers are not live attendees, and mixing them skews the rate.

If the data is inconsistent, report that first. A clean-looking rate built on bad timestamps is worse than no rate.

## Common patterns and traps

- **Calling a no-show a non-attendee without checking the session.** The person may have attended a different session of the same event.
- **Treating the registrant count as the audience size.** Registrants are the sign-up pool; attendance is what happened. Report both and the ratio.
- **Duplicate people records** inflate the no-show count. Resolve duplicates before counting.
- **Pagination truncation** is the most common silent error. Watch for round numbers and for totals that do not match the page-by-page sum.
- **Overreading partial attendance.** A 6-minute join at the end of a 60-minute session is a no-show in effect, not a partial attendee. Use a threshold you state, such as under a quarter of the session, and let the user change it.
- **Personal data in the output.** The list is contact data. Keep the report to what the user needs and do not copy it into other places.

## Output

```
Event: <name> | Session: <date, time zone> | Scope: <one session | all sessions>
Registered: <n>   Attended: <n>   Attendance rate: <n>%
  Attended, full: <n>   Attended, partial: <n>   Late joiners: <n>
  No-shows: <n>   Unregistered attendees: <n>

Duplicates merged: <n> (list below if any)
Data checks: <time window OK / issues found>

No-shows (for follow-up)
- name <email> — registered <date>
Partial attendees (under <threshold>)
- name <email> — joined <time>, left <time>
Unregistered attendees
- name <email> — joined <time>, likely reason

Patterns: <domains, clusters, timing>
Not established: <what could not be verified, e.g. join/leave data missing>
```

## Rules

- This job is read-only. Do not create, update, delete or tag any person, registration or session. If the user wants a follow-up tag or a bulk registration applied to the no-show list, present the exact list and wait for the user's explicit yes before calling any write tool.
- Switching the active account or workspace is itself a change of context. Wait for the user's explicit yes before switching, and confirm the workspace again afterwards.
- Never send messages to attendees or registrants from this job, even if a tool would allow it.
- Do not report attendance rates from unverified timestamps or an incomplete pagination run.
- Keep the personal data in the report to what the user needs. Never paste full contact lists into a summary unless asked.

## Done when

- The event and session are confirmed, and the account and workspace are stated.
- Counts for registered, attended and each bucket are given, and they add up to the registrant total.
- Duplicates are merged and stated, and the timestamp checks are reported.
- Every no-show and mismatch is listed or counted, with the threshold used stated.
- The "Not established" line says plainly what could not be checked.
