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

# Connect flow

> What the user sees, what Verso does, and what you receive.

## What the user sees

1. Your app opens the connect link (`https://connect.tryverso.ai/start?token=…`), in the same tab or a new one.
2. The page shows the provider's own login screen inside a hosted browser, under your app's name and logo. There is no consent screen on Verso's side: you ask for consent in your app, before the link.
3. The user logs in as they normally would, including two-factor or verification steps.
4. A short "Connecting your account" loader, then "Connected! Your conversations will sync in the background". The user can close the page.

The whole flow must complete within one hour of opening the link. After that the hosted browser is closed and a new link is needed.

## On mobile

Native apps should use the [Verso SDKs for iOS and Android](/guides/mobile-apps): the provider's login opens inside the app with the device's own keyboard, autofill and sign-in buttons, and the rest of the flow is identical. React Native and Flutter wrappers are next.

The hosted page also works on a phone, for web apps or platforms without an SDK yet. The remote browser is created at the size of the visitor's screen with a phone profile, and the page keeps itself inside the area the keyboard leaves visible. Because the device's keyboard cannot reach the remote browser, the page shows a typing bar under it: the user taps a field in the provider's login, types in the bar and sends. Enter, a clear-field button and a hide-text toggle are provided. Password managers cannot fill the remote login. Open the link in the system's in-app browser, Safari View Controller on iOS or Chrome Custom Tabs on Android, or in the default browser; a bare WebView may block the embedded browser view.

## What Verso does

1. **Verifies and consumes the link** when the page starts the flow. A used or expired link shows an error and nothing else happens.
2. **Creates the user record** for your `(appId, userRef)` if it does not exist, and sends `connect.started`.
3. **Opens a hosted browser session** and navigates it to the provider's login page.
4. **Detects the login** by watching for the provider's session cookie, then checks that the session is usable. Intermediate screens (verification, consent on the provider side) are handled by waiting, not by failing.
5. **Captures the session**: the session credential is encrypted with a key that exists only for this connection, a connection is created, and the hosted browser is released. No conversation is imported at this point.
6. **Sends `connection.created`**, with your `userRef`, the `connectionId`, and `replaces` (see below).
7. **Starts the first sync** within a minute. See [Data management](/guides/data-management) for the sync cadence.

## Reconnecting

When a user connects the same provider account again, Verso does not create a duplicate. The previous connection is folded into the new one: its conversations move to the new connection, sync resumes where it left off, and the old connection becomes `revoked`. The `connection.created` payload lists the old ids in `replaces`. Update any connection id you stored; better, key everything on `userRef` and read connection ids from `GET /api/connections` when you need them.

A user may connect several accounts of the same provider under one `userRef`, for example a personal and a work ChatGPT account. Each account is its own connection, and `GET /api/connections` lists them side by side.

## One account, one user

The reverse is not allowed: a ChatGPT account can be connected by only one user of your app at a time. If a second `userRef` logs into an account that another user of your app already connected, the connect page ends with "This ChatGPT account is already connected to another user of this app" and no connection is created. The link is spent; sign a new one if the user wants to connect a different account. Each connection carries an `accountId` in `GET /api/connections`, stable for one ChatGPT account within your app, so you can recognise the same account across reconnects.

## When the session stops working

Provider sessions eventually expire, or the user changes their password. The next sync detects it: the connection becomes `needs_reauth` and you receive `reauth.needed`. Sign a new connect link for the user; once they log in, the new connection replaces the old one as described above. Nothing is lost in between: the conversations already imported stay readable.

## Branding

The hosted pages show your app's name, logo and primary color, configured at onboarding.

| Setting | Example |
| - | - |
| `appName` | `"Acme"` |
| `logoUrl` | `"https://acme.com/logo.svg"` |
| `primaryColor` | `"#4F46E5"` |

## Importing an export instead

If your app already holds a ChatGPT data export for the user, you can ingest it server-side with `POST /api/ingest-export` instead of, or in addition to, the hosted flow. It needs an existing connection of that user, so the user connects once through the hosted page first. See the [API reference](/api-reference/ingest-export).
