Connect flows
connect() covers the common case: your agent runs outside the user’s browser (a CLI, an IDE plugin, a server-side worker), shows the user a short code, and waits while they authorize. This page covers everything around that: driving the prompt yourself, keeping a stable install identity, and the non-blocking primitives for agents that can’t wait.
Drive the prompt yourself
Section titled “Drive the prompt yourself”By default the SDK prints the code and URL to stdout and opens the OS browser. If you have your own UI, pass onUserPrompt:
const connection = await client.connect({ onUserPrompt: ({ code, url }) => { myUi.show(`Code: ${code}`); myBrowser.open(url); },});The code is what binds the consent flow to the device the user is actually on. Always show it; the user types it on the connect screen.
Reuse the install identity
Section titled “Reuse the install identity”deviceKey identifies the install across reconnects. Persist it if you want the same user and machine to appear as the same install instead of a fresh one every time:
// First runconst conn = await client.connect();saveSomewhere(conn.deviceKey);
// Laterconst client2 = new WireClient({ agentId: 'my-agent', deviceKey: loadSomewhere(),});const conn2 = await client2.connect();Local file, OS keychain, secrets manager, your call.
Non-blocking connects
Section titled “Non-blocking connects”connect() holds a promise open while the user acts. Chat surfaces and turn-based harnesses often can’t do that: the agent wants to show the code, end its turn, and pick the flow back up later. Use the primitives underneath instead:
// Turn 1: start the handshake, show the code and URL, persist the handleconst pending = await client.beginConnect({ label: 'my-laptop' });myUi.show(`Code: ${pending.userCode}. Open: ${pending.url}`);save(pending); // plain JSON, safe to stash anywhere
// Any later turn: a single poll, no waitingconst connection = await client.checkConnection(load());if (connection) { save(connection);}beginConnect() returns a PendingConnection handle: the user code, the connect-screen URL, and everything the SDK needs to resume, including the device key. It survives a JSON round-trip, so persist it however you persist anything else.
checkConnection(pending) polls exactly once. It returns the Connection when the user has picked a container, null while they haven’t yet, and throws NONCE_EXPIRED once the handshake lapses (pending.expiresAt tells you when, about 10 minutes).
connect() is just these two composed with a prompt and a 2-second poll loop, so the two styles behave identically once connected.
From a browser app
Section titled “From a browser app”When your agent runs in the user’s browser (a webapp, an in-browser assistant, an extension), there is no second device to bind and no code to type. connectInBrowser() sends the user through Wire’s authorization screen, where they sign in if needed and pick a container, then returns them to your page with the connection ready:
// Starting the flow (any page of your app):await client.connectInBrowser({ redirectUri: 'https://my-app.com/callback' });
// Or keep your page open with popup mode, which resolves in place:const connection = await client.connectInBrowser({ redirectUri: 'https://my-app.com/callback', popup: true,});
// On your callback page (safe to call on every page load):const connection = await client.completeConnectInBrowser();if (connection) { // same Connection shape as connect()}Register your redirect URIs on the agent in the Wire dashboard first; the flow only redirects to URIs on that allowlist. In redirect mode your callback page finishes the connect with completeConnectInBrowser(); in popup mode the same call on the popup’s page relays the result back to your open tab and closes the popup.
Browser connections return the same Connection as the device flow and behave identically afterward (getStatus, claim, disconnect, revocable from the container’s connected-agents panel). The one difference: there is no deviceKey, since the authorization itself is the identity. See examples/browser-connect/ in the SDK repo for a runnable page.