Link
Link is the embedded authentication UI. Your product opens Link, the user picks a Connector, completes OAuth (or pastes an API key), lands back in your app. The result is a credential stored against their Registered User - Agent Handler holds it; your code never sees it.
This page covers Link in your product. For email-driven flows or any context where you can’t render a React component, use Magic Link instead.
When Link runs
Two trigger patterns; pick one or both.
Pre-flight, from a settings page. The user clicks “Connect Slack” in your UI before the agent ever runs. Most B2B products do this - users prefer setting up integrations once rather than being interrupted mid-conversation. Your backend mints a link token; your frontend opens Link.
At agent runtime. The agent calls a tool the user hasn’t authenticated. The Connector returns an authenticate_meta tool result with a link_token. Your frontend catches it, opens Link, the user authenticates, the original tool call retries. No separate “missing auth” UI needed.
Generate a link token
Backend call. Mint one link token per Link session. Tokens are single-use and expire after 30 minutes.
The Connector field is the Connector slug - lowercase with hyphens, like google-drive, microsoft-teams, salesforce. The full list is in the Connector catalog.
If you want the user to pick from a list of Connectors instead of locking to one, omit Connector from the request body. Link will show the picker for every Connector configured on the Tool Pack.
Open Link from your frontend
Install the React component:
Open Link with the token your backend just minted:
isReady flips to true once the component has loaded the token and is ready to open. Disable your button until then to avoid no-op clicks.
For projects without React, the same UI is reachable via a hosted URL: https://ah.merge.dev/link/<LINK_TOKEN>. Open it in a popup or redirect; on success, your redirect_uri (configured in Link customization) gets hit with the result.
The runtime trigger pattern
When the agent calls a tool the user hasn’t authenticated, Agent Handler returns a special authenticate_meta payload instead of failing the call:
Your frontend should intercept the streamed tool-call result, detect the authenticate_meta shape, and open Link with the embedded token. After onSuccess fires, retry the user’s original prompt - the agent’s next call to the same tool will succeed because credentials are now stored.
Pattern in TypeScript, against an Anthropic-style stream:
Then render <ConnectButton linkToken={pendingLinkToken} onSuccess={() => resumeAgent()} />.
Callback URLs and CORS
Link redirects through the third party’s OAuth consent screen and back. The URL the third party redirects to has to be on Agent Handler’s allow-list - that’s a security check.
In Settings → API Keys → Allowed callback origins, add every domain that hosts your frontend. The match is exact - app.example.com and staging.example.com need separate entries. Localhost ports for development need entries too.
If you skip this, you’ll see “unauthorized origin” on the callback. See Troubleshooting → Allowed callback origin error.
Common errors
Customizing what Link looks like
Logo, colors, header copy, redirect URL, allowed Connectors - all configurable per organization at Configure → Link. See Link customization for the asset specs and what end users see if you configure nothing.
Next
For email and mobile flows where you can’t render a React component, use Magic Link instead.