> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connection flow

> Open Connect UI in a popup or redirect flow, and capture the connection identifier.

# Connection flow

After your backend has obtained a **connect token** (typically by exchanging an **access token** during [token exchange](./token-exchange)), you open the Connect UI so the user can authorize an app. The Connect UI URL includes the app as a path segment and the connect token as a `token` query parameter. Optionally, pass a `theme` parameter to apply partner-specific branding to the Connect UI. There are two approaches.

## Option 1: Popup with `postMessage`

Open the Connect UI URL in a popup window and listen for a message back with the connection ID.

```js theme={null}
const ZAPIER_CONNECT_BASE_URL = "https://connect.zapier.com";

function connectApp(token, app, theme) {
  const url = new URL(`${ZAPIER_CONNECT_BASE_URL}/to/${app}`);
  url.searchParams.set("token", token);
  if (theme) url.searchParams.set("theme", theme);

  const popup = window.open(url, "zapier-connect", "width=980,height=700");

  window.addEventListener("message", (event) => {
    if (event.origin !== ZAPIER_CONNECT_BASE_URL) return;

    if (event.data.type === "authenticationSuccess") {
      popup.close();
      onConnected(event.data.authId); // numeric connection ID
    }
    if (event.data.type === "authenticationError") {
      popup.close();
      onError(event.data.error);
    }
  });
}
```

## Option 2: Redirect

Navigate the current window to the Connect UI URL with a `redirect_uri`. After the user authorizes, Zapier redirects back to your URL with the result as query parameters.

```js theme={null}
const ZAPIER_CONNECT_BASE_URL = "https://connect.zapier.com";

function connectApp(token, app, theme) {
  const url = new URL(`${ZAPIER_CONNECT_BASE_URL}/to/${app}`);
  url.searchParams.set("token", token);
  if (theme) url.searchParams.set("theme", theme);
  url.searchParams.set("redirect_uri", window.location.origin + "/callback");

  window.location.href = url.toString();
}
```

When Zapier redirects back, your callback URL receives:

### On success

```text theme={null}
https://your-app.com/callback?authentication_id=12345&service=SlackAPI
```

### On error

```text theme={null}
https://your-app.com/callback?error=access_denied&service=SlackAPI
```

Use `authentication_id` as the connection identifier with your access token.

## Reconnecting

To reconnect an existing connection (e.g. after it expires), add the `reconnect_id` parameter to the Connect UI URL. This tells Zapier to re-authorize the same connection instead of creating a new one. The value is the connection’s ID.

```js theme={null}
url.searchParams.set("reconnect_id", authenticationId);
```

Everything else — popup vs redirect, theme, postMessage handling — works exactly the same as a new connection.

## Handling popup close

The user may close the popup before completing the flow. Since no `postMessage` is sent in that case, poll the popup’s `closed` property to detect this and reset your UI.

```js theme={null}
const poll = setInterval(() => {
  if (popup.closed) {
    clearInterval(poll);
    onCancelled();
  }
}, 500);
```
