/

Attendance writeback

Your calendar knows a call was booked. Only Zoom knows whether it happened. This is the part that carries that fact back.

The shape of it

Two steps, and the second one takes a single field.

Trigger: Meeting Ended. Action: Update Attendance, with meetingId mapped to {{zwa_meeting_ended.meetingId}}.

Everything else is optional. The interesting facts — who joined, for how long, which booking this was — are already ours, and asking you to map them back from trigger variables would be asking you to hand us our own data.

When the call ends, the booking is set to showed or noshow.

What counts as attendance

By default, anyone joining at all counts. minimumMinutes defaults to 1.

Raise it to filter out the attendee who dials in, sees an empty room and leaves:

minimumMinutesMarks showed when
1 (default)Anyone joined
5Someone stayed five minutes
15Someone stayed a quarter of an hour

It measures the longest single attendance, not the total across people. Two people staying twenty minutes each is a twenty-minute meeting, not forty. That is almost always what you want — it answers “did a real conversation happen” rather than “how much collective time was spent”.

The three views

Meeting Ended publishes attendance three ways, so the strictness lives in your workflow rather than frozen into our contract:

  • attended — did anyone join. The blunt instrument, and often enough.
  • attendedMinutes — the longest single attendance. Use it when a two-minute call is not a call.
  • attendeeCount — how many distinct people. Use it for group sessions: fewer than three, reschedule.

Rejoins after a dropped connection count once, so a flaky line does not inflate the count.

One caveat on attendedMinutes

It is exact only when the Zoom app subscribes to the participant left event. Without that there is no leave time, so the figure is computed from the join time to the end of the meeting — an upper bound, which reads as “stayed to the end” for someone who dropped off after five minutes.

If you are going to make a consequential decision on this number, confirm that event is subscribed first. attended and attendeeCount are unaffected.

Overriding the verdict

status defaults to auto, which writes what the attendance data says. You can force it instead:

new, confirmed, cancelled, showed, noshow, invalid.

These exist because a meeting outcome is not always a fact about attendance. A discovery call that ran four minutes is a no-show to one agency and a win to another. If your definition differs from ours, branch on the trigger data yourself and write the status you mean.

Tagging the contact

showedTags and noshowTags take comma-separated tag names and apply them to the contact alongside the appointment update.

Useful when your reporting runs off tags rather than appointment status, or when you want a durable record on the contact that survives someone editing the booking later.

skipAppointmentUpdate turns off the calendar write entirely and applies only tags — for teams who drive their calendar from somewhere else and want the attendance signal without us touching their bookings.

When it cannot find the booking

This is the failure mode this action has, and it is worth understanding because it is quiet by design.

Update Attendance returns success with a warning rather than failing. A workflow step that errors stops the entire run, and “we could not find the appointment” should not stop the follow-up email going out.

So check these outputs if you want to know what really happened:

  • appointmentUpdated — whether the calendar write actually happened.
  • appointmentSource — how the booking was found: provided (you supplied the id), recorded (from appointmentId at creation), matched (found by searching the contact’s appointments), or none.
  • warning — empty when everything worked; otherwise a sentence explaining what did not.

A condition on appointmentUpdated being false is how you find out that the loop is silently open.

Why it might not find one

  • The meeting was not created by a workflow. A call booked directly in Zoom has no appointment behind it. Nothing is wrong; there is simply nothing to write to.
  • appointmentId was not mapped at creation. Fall back matching searches the contact’s appointments and matches on start time, which fails if the booking was moved after the meeting was created without the app being told.
  • The appointment was deleted between the call being booked and it ending.

The first is expected. The second is worth fixing: map {{appointment.id}} into Create Meeting’s appointmentId and the resolution becomes a primary-key lookup instead of a search.

A complete example

Trigger: Meeting Ended

  1. Update AttendancemeetingId = {{zwa_meeting_ended.meetingId}}, minimumMinutes = 5, noshowTags = no-show,needs-rebook
  2. Condition{{zwa_meeting_ended.attended}} is false
    • Yes: start the rebooking sequence
    • No: send the recap email, move the opportunity forward
  3. Condition{{zwa_update_attendance.appointmentUpdated}} is false
    • Yes: notify the ops channel, because a call happened that the calendar does not know about

Step 3 is the one people leave out and later wish they had.