Skip to main content
These are the callbacks you pass to open(), and three of them to resume(). All six are optional. If you supply none, the flow still works and you learn the outcome from your webhooks. onSuccess and onExit are mutually exclusive. Whichever arrives first is the outcome. onClose arrives right after either. It arrives on its own in two cases: the user closes the popup window in the popup mode (the package checks the window every half second), or the user presses the overlay’s close button or Escape. See The package never dismisses your surface. Nothing inside the flow produces it alone. onOpen can arrive more than once, for example after the embedded page reloads, so make the handler safe to run twice. If no callback arrives at all, When you receive nothing lists the cases. Each is a real outcome, not an error. A launch has one ending. If you keep the surface up after onSuccess and the user connects another provider, you get onConnection for it but no second onSuccess. Call open() again if you want a fresh outcome.

onSuccess means the user came back

onSuccess means the user came back, not that a connection was made. It fires when the user presses the button on the success screen (Done in the iframe; in a popup or tab, Return to followed by your name as configured in Catena), which happens after the connection already exists. A user who connects and then closes the surface, or just leaves the tab, never produces onSuccess, and their connection is still real.
Treat onSuccess as “they are done and heading back to you”, and treat your connection webhooks as the record of what was actually established. connectionIds lists the connections this session made, less any the fleet deleted before finishing, and is best effort for the same reason.

onConnection is the connection being made

It fires as each provider is connected, while the flow is still running. Do not dismiss your surface on it, because the user may be about to add another provider. It exists mainly for the iframe mode, where the user is already looking at your page and may never press the button that produces onSuccess. The same connectionId can arrive twice if a user re-authorizes a provider twice in one session. As with connectionIds, treat it as a prompt to check, and your webhooks as the record. Two reason values mean the flow could not load the invitation at all. Both arrive straight after onOpen, followed by onClose. Behind them the flow shows an error screen, so if you take your surface down on onClose the user never sees it. Show your own message instead. Every attempt to load an invite link counts as a view of that invitation, and your invitation.viewed webhook fires for each one. That includes an attempt that ends in invitation_unavailable, so a retry can produce a second webhook.

onConnectionDeleted is a connection going away

The flow lets the fleet delete a connection, and this fires when it does, with the deleted connection’s connectionId. Like onConnection, it is not an ending and the flow keeps running. If you stored an id from an earlier onConnection, drop it here instead of waiting for your webhooks to catch up. The connection may be one made before this session, so an id you have never seen is normal. onOpen, onConnection and onConnectionDeleted do not fire on every path. The redirect mode navigates away before the flow reports itself ready, and has no channel to deliver any of them.

The package never dismisses your surface

The package never removes anything on its own: not the overlay, not the iframe and not the popup window. onClose means the flow is finished with the surface. Call destroy() on the handle open() returned, or tear down your own container or modal when it suits you. The overlay has a close button in its top-right corner, and Escape does the same while focus is on the overlay’s own controls. Escape pressed inside the flow goes to the flow’s page, which the package cannot hear. Either one ends the launch and calls onClose. No onSuccess or onExit comes before it unless the flow had already sent one, and nothing comes after it. The flow comes off the overlay at once, but the overlay itself stays up until you call destroy(), so an onClose handler that does nothing leaves the user looking at an empty overlay. The close button cannot be turned off. The overlay sits above everything on your page and takes the rest of it out of the tab order, so a control of your own could not be reached while it is up. If you want your own close control, or any other chrome around the flow, pass a container and build the modal yourself. A container gets no close button and no Escape handling, so call destroy() from your own control.