Your sub-account is connected. The next step is connecting a Zoom account, which is step 2 below.
The app is installed and the rest of your sub-accounts are ready to use. The ones that did not connect will be retried the first time a workflow runs in them, so this often resolves itself. If it does not, reinstall from the marketplace listing.
Nothing was connected, so there is nothing to undo. Start the install again from the marketplace listing — if it fails a second time, the app's install link may have expired.
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:
minimumMinutes | Marks showed when |
|---|---|
1 (default) | Anyone joined |
5 | Someone stayed five minutes |
15 | Someone 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(fromappointmentIdat creation),matched(found by searching the contact’s appointments), ornone.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.
appointmentIdwas 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
- Update Attendance —
meetingId={{zwa_meeting_ended.meetingId}},minimumMinutes=5,noshowTags=no-show,needs-rebook - Condition —
{{zwa_meeting_ended.attended}}isfalse- Yes: start the rebooking sequence
- No: send the recap email, move the opportunity forward
- Condition —
{{zwa_update_attendance.appointmentUpdated}}isfalse- 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.