Skip to content
Home

Unbound Connect

Status: Draft Last Updated: 2026-06-15 Audience: customer

Unbound Connect is the ready-made experience your end users pass through to connect their personal data sources to your app — and to manage those connections afterward. It packages the entire consent-and-setup journey (picking sources, OAuth handoffs, device-app handoffs, the macOS sync agent install, status visibility, and disconnection) into a single hosted flow that Unbound operates, plus a thin piece of code you embed in your app.

The journey is genuinely hard to build well, and it is nearly identical for every app that embeds it. Connect lets you ship it in an afternoon instead of rebuilding source pickers, OAuth state handling, agent install flows, platform detection, and status polling yourself. Improvements and newly supported sources ship centrally and reach your users immediately — with no code change on your side.

Connect is optional. It is built on the same public building blocks (the authorization flow, token exchange, agent setup, and the grants query) that remain fully available if you want to build a custom experience instead. Nothing in the hosted flow is privileged: anything Connect does, a custom integration can do too.

What you get

  • A hosted flow Unbound serves at a stable URL. It owns the complete end-user journey — both connecting new sources and managing existing ones — so you never render or maintain any of that UI yourself.
  • Delivery modes for getting your users into that flow: a full-page redirect, a tiny in-page JavaScript loader, or the raw building blocks if you want full control. All three open the same hosted flow.
  • A consistent trust model: your backend holds your end users’ access tokens, your client secret never touches the browser, and the flow concludes exactly like the standard authorization flow.
  • Status you can rely on: an in-app grants query for pulling current state, plus webhooks that push grant and sync transitions to your backend as they happen.

Two surfaces, one flow

The hosted flow runs in one of two modes, both served from the same place:

  • Connect — the setup journey: pick sources, consent, run each source’s setup, finish. This is what a “Connect your data” button opens.
  • Manage — the post-connect home for a user’s connections inside your app: per-source status, disconnect, reconnect, and add-more-sources. This typically sits behind a “Manage connected data” entry in your app’s settings. Because some sources keep syncing long after the user has walked away, post-connect status visibility is built in from day one rather than bolted on.

How it works

Every delivery mode starts the same way. Your backend creates a short-lived connect session for one end user, then sends that user into the returned URL.

POST /connect/sessions
Authorization: Basic <your client credentials>
Content-Type: application/json
{
"end_user_id": "your-opaque-user-id",
"mode": "connect",
"sources": ["gmail", "imessage"],
"redirect_uri": "https://app.example.test/unbound/callback",
"state": "your-per-request-nonce"
}
200 OK
{
"connect_url": "https://<your-unbound-host>/connect/...",
"expires_in_seconds": 900
}

A few things to know about sessions:

  • No prior connection is required. You can create a session for a brand-new end user who has connected nothing yet — your “Connect” button always mints a fresh session.
  • Short-lived and single-use. A session expires if unused and cannot be re-entered once the flow completes. If a user abandons the flow or the session expires, just mint a new one.
  • Source scoping. sources limits what the flow offers. Omit it to offer every source available to your account. The flow may further constrain by platform — for example, an iMessage setup leg needs a Mac.
  • manage mode needs no redirect_uri or state (there’s no authorization code to deliver); it operates on the user’s existing connections and exits back to your app.

When the user finishes connecting, the flow delivers a one-time authorization code (with your state) to your registered redirect_uri, or hands it to your in-page callback when you use the JavaScript loader. Your backend exchanges that code for the end-user access token — the same exchange the authorization flow describes.

The end-user journey

In connect mode the user moves through three steps:

  1. Pick sources. The flow shows the sources your session offered, each with a plain-language description of what it grants. Your branding (name and logo) is visible so the user knows who is asking. Selecting a source is the consent act for it. Sources that can’t run on the user’s current device (for example, iMessage when they’re on a phone) appear with an explanation and a handoff option rather than being hidden.
  2. Set up each source. Each selected source runs its own setup — an OAuth redirect, a device handoff, or the macOS agent install. A failure or abandonment in one source never loses progress on the others.
  3. Finish. When the selected sources are connected — partial success still counts as success — the flow completes and reports exactly what connected and what is still syncing. The user can leave with confidence even while a long first sync continues in the background.

Per-source setup

  • Google sources (Gmail, Google Calendar, Google Contacts). The user is taken to Google’s standard consent screen and grants access there. When a session offers more than one Google source, they’re presented as a single “Connect Google” action so the user consents once for all of them, rather than seeing repeated consent screens.
  • macOS sources (iMessage, Apple Contacts). The user downloads and installs a small, notarized macOS sync agent, grants it Full Disk Access when macOS asks, and the agent connects. The flow shows live setup progress and lets the user leave once setup succeeds — the agent’s first sync can run for minutes to hours on a large message history, and the flow treats “connected, still syncing” as a real, durable state. Apple Contacts is read by the same agent, so it comes along with the iMessage setup.
  • Android SMS. The flow walks the user through Google’s Data Portability export on their Android device and shows the source as connected once the export lands.
  • Cross-device handoff. If a source needs a device the user isn’t on, the flow offers a QR code and a send-me-a-link option that resumes the same session on the right device. The originating tab keeps watching and flips to connected the moment the other device finishes — no manual refresh.

Every error state explains what happened in plain language and offers a way forward (retry, start over, skip this source, or get help). Expired sessions route the user back to start over from your app — never a dead end.

Managing connections

In manage mode the user sees, per source: connection and sync status, when it was granted, when it last synced, and how far back its data goes. They can disconnect a source (with a plain-language explanation of what that means, after confirmation), reconnect or add sources without leaving the surface, and re-run setup for a macOS agent that has stopped reporting.

Source coverage

Connect supports Gmail, Google Calendar, Google Contacts, iMessage, Apple Contacts, Android SMS, and local file uploads. Which of these your users see is controlled by your account configuration and by the sources you scope each session to. See the data sources reference for the identifier strings, what each source provides, the end-user experience, and time-to-data per source.

Delivery modes

All modes open the same hosted flow. They differ only in how you present it and how completion returns to your app.

  • Full-page redirect. Your backend creates a session and sends the user to connect_url. Completion redirects back to your redirect_uri with code and state. This works on every platform with zero frontend code, and it’s the only mode that email and QR links can use.
  • JavaScript loader (in-page popup). A tiny, dependency-free script opens the flow in a popup so the user stays on your page, and relays a small event stream back to you (open, source_connected, success, exit, error). It falls back to a full-page redirect where popups can’t open (typically mobile web). See the JS loader guide for the embed snippet, the event vocabulary, and the origin-pinning security model.
  • Raw building blocks. The fully custom path: compose the authorization flow, token exchange, agent setup, and the grants query yourself. Connect adds nothing these can’t do — it’s a permanently supported path, not a deprecation target.

To get started quickly, the Connect starter kit is a copyable backend-for-frontend plus example front end that mints sessions, exchanges codes, and verifies webhooks for you.

Theming

Connect renders your display name, logo, and accent color on a neutral Unbound-styled flow — enough that it feels at home inside your app. These values come from your account configuration; there’s nothing to wire up per session. Custom CSS, fonts, or layout control aren’t offered. On every screen, the flow also identifies Unbound as the operator of the consent step, so the end user always knows whom they’re trusting.

Knowing the status

Connection status reaches you through three channels, in order of immediacy:

  1. In the flow. The hosted flow polls and renders live status during asynchronous setup, and shows the truth on every load — a user who refreshes or returns later sees real state, not stale UI memory.
  2. In your app (pull). Query the grants surface for current status — what’s connected, when it was granted, and read-side counts — to render your own status chips. See Authentication for how your end-user token authenticates these queries.
  3. Webhooks (push). Unbound notifies your backend of grant and sync transitions that complete asynchronously — at minimum a grant activating, a grant being revoked, and a source’s initial sync completing or failing. This matters because a first sync can land long after the user has left the flow. Deliveries are HMAC-signed; see the webhooks guide for the event schema, signature verification, and deduplication.

Because a source can finish connecting after the user is gone, treat the durable grant and sync state — via the grants query or webhooks — as the source of truth, rather than assuming data exists the moment the flow returns.

Versioning

The hosted flow and the JavaScript loader are versioned, and their contracts evolve compatibly: visual and flow improvements ship continuously, while the parts you depend on (session semantics and the loader’s event vocabulary) only grow within a version. One flow serves every customer and platform — your variation is data (branding, offered sources), never a forked codebase you have to keep current.

  • JS Loader — The in-page popup loader: the embed snippet, the event vocabulary, and the origin-pinning security model.
  • Webhooks — The push channel for grant and sync transitions that complete after the user leaves the flow, including signature verification.
  • Data Sources — Per-source identifiers, the end-user experience, and time-to-data for every source Connect supports.
  • Authorization Flow — The consent loop and code-to-token exchange that Connect’s completion follows.
  • Authentication — How the end-user token you receive authenticates data and grants queries.
  • Quickstart — The fastest path from zero to a first connected source.