/

How it fits together

What is tied to what — and why a Zoom call knows which booking it belongs to when Zoom itself has never heard of your calendar.

One sub-account, one Zoom account

The app connects one Zoom account to one sub-account. That pairing is the thing everything else hangs off.

Every meeting created for that sub-account is hosted by the Zoom user you signed in as. Every Zoom event on that account — including calls nobody created through a workflow — is offered to that sub-account’s triggers.

Installing into a second sub-account is a completely separate install with its own connection, its own daily allowance, and no visibility of the first.

If your team round-robins calls

A single connected Zoom account means a single host. If calls need to land on different reps’ Zoom accounts, the honest answer today is one install per rep’s sub-account, or a shared scheduling account that reps join as participants.

The hostEmail field on every trigger is there for the related case: when several people share one Zoom account, it tells a workflow which of them actually ran the call, so follow-up can be routed to the right person.

How a call knows its booking

Zoom has never heard of your calendar. When a meeting ends, Zoom tells us a meeting id, some timestamps and a list of participants — nothing that identifies an appointment.

The link is made at creation and remembered:

  1. Create Meeting records the correlation. When you map {{appointment.id}} into appointmentId, the app stores that alongside the Zoom meeting id and the contact.
  2. Meeting Ended looks it up. The webhook arrives with a meeting id; the app resolves the appointment and contact from its own record.
  3. Update Attendance writes to it by primary key.

This is why appointmentId matters more than it looks. Without it, step 2 has to fall back to searching the contact’s appointments and matching one on start time. That works and is used every day, but it is inference rather than a fact — and it is the reason appointmentSource on Update Attendance reports how the booking was found: provided, recorded, matched, or none.

Meetings the app did not create

Triggers fire for everything on the connected Zoom account, not only for calls made through a workflow. A rep who books a call directly in Zoom’s own interface produces a Meeting Created event exactly like one from a workflow.

That is deliberate and it is a large part of the value: those calls never reach the CRM otherwise.

It has one consequence to design around. A meeting the app did not create has no booking and no contact behind it, so contactId arrives empty and attendance has nothing to write to. Such a call still produces perfectly good trigger data — topic, times, attendance, recordings — it simply cannot be attached to a CRM record that was never involved.

The loop hazard

Because Meeting Created fires for calls the app creates too, a workflow triggered by Meeting Created whose action is Create Meeting will create a meeting, hear about it, and create another one. Indefinitely.

Every Meeting Created and Webinar Created payload carries createdByThisApp for exactly this reason. Gate the workflow on it being false.

The event is reported rather than filtered out on your behalf, because reacting to app-created meetings is a legitimate thing to want — and swallowing those events silently would make it impossible with no way to work out why.

How a person is identified

Zoom identifies participants poorly by default. Someone who joins a meeting from a shared link is whatever name they typed into the box, and participantEmail is empty unless they happened to be signed in to Zoom.

Registration is what fixes this. A registrant gets their own join link, and Zoom then names them on every event about that meeting. This is why attendance on a registered meeting is a fact and attendance on an open-link meeting is a reasonable guess.

Registration and join links covers how to turn it on.

Where registration is not in play, match on the contact the meeting was created for — which the app already knows — rather than on participantEmail.

Recurring meetings

Zoom reuses one meetingId across every occurrence of a recurring meeting. It issues a distinct meetingUuid per occurrence.

So meetingUuid is the only safe key for distinguishing the Tuesday session from the Wednesday one. Every trigger publishes both.

What the app stores

Enough to do the correlation above: the Zoom meeting id, the appointment id and contact id it was created for, and the account connection itself. Attendance is computed from Zoom’s webhook events as they arrive.

Host start links are a deliberate exception — they are returned once, at creation, and never stored in a form the app will hand back. A retry that resolves to an existing meeting returns an empty startUrl rather than re-serving a credential.