Auth Surfaces
Configure supports two browser auth surfaces. For products with existing sign-in, use Continue with Configure as the OAuth SSO provider and then place inline Configure inside chat. For products without sign-in, use Configure Link as the lower-friction fallback.
Configure Link is the browser surface for user-present memory consent. It handles phone OTP, profile seeding, access review, and agent token minting inside a secure Configure-owned iframe. Connector and import setup happen on Configure's origin; the parent page receives only the final agent-scoped token.
Continue With Configure
Use Continue with Configure when the host app has an SSO row or account-linking flow:
html
<script src="https://configure.dev/js/configure.js"></script>
<configure-sso-button
client-id="oc_..."
redirect-uri="https://app.example.com/auth/configure/callback"
scopes="profile.read profile.search profile.remember profile.commit"
width="100%">
</configure-sso-button>The callback exchanges the authorization code on the backend and stores Configure OAuth tokens server-side. See Continue with Configure for client creation, PKCE, callback, and token exchange details.
Never expose OAuth access tokens, refresh tokens, client_secret, or sk_ keys in browser JavaScript.
Link Fallback Trigger
Attach Link to an existing host button with data-configure-link. Triggered Link opens an in-page hosted flow and does not mount an iframe inside the button.
html
<script src="https://configure.dev/js/configure.js"></script>
<button
data-configure-link
data-publishable-key="pk_..."
data-agent="your-agent">
Personalize
</button>
<script>
document.addEventListener("configure:linked", (event) => {
fetch("/api/configure/session", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: event.detail.token }),
});
});
</script>For chat inputs, use the hosted Personalization entry point when you want Configure to live beside host-owned Images and Files actions. If the user already completed Continue with Configure, this entry should open as a manage/connect/permissions surface rather than a second sign-in step.
js
Configure.personalizationButton({
el: "#chat-entry",
publishableKey: "pk_...",
agent: "your-agent",
agentName: "Your Agent",
theme: "light",
font: "Inter, -apple-system, BlinkMacSystemFont, sans-serif",
onImage: () => openImagePicker(),
onFile: () => openFilePicker(),
onEvent(event) {
if (event.type === "configure:linked") {
fetch("/api/configure/session", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: event.payload.token }),
});
}
},
});Images and Files remain host-owned. The helper also emits configure:image-select, configure:file-select, configure:personalization-open, and configure:personalization-toggle for apps that want to route those actions themselves.
For settings or onboarding pages, mount Link inline into an explicit container:
html
<div id="configure-link"></div>
<script>
Configure.link({
el: "#configure-link",
publishableKey: "pk_...",
agent: "your-agent",
presentation: "inline",
theme: "light",
});
</script>Options
| Name | Type | Required | Description |
|---|---|---|---|
el | string | Element | No | Container for inline presentation. Omit for modal/triggered Link. |
publishableKey | string | Yes | Publishable key (pk_...) safe for client-side use. |
agent | string | Yes | Public agent handle receiving approved access. |
theme | 'light' | 'dark' | Yes | Hosted iframe theme. Pass it explicitly to avoid OS-theme mismatch with the host app. |
presentation | 'modal' | 'inline' | No | Public presentation mode. Defaults to modal for triggers/no el, inline for non-interactive containers. |
externalId | string | No | Optional app-local user hint for later reconciliation. Does not authorize portable reads. |
token | string | No | Optional browser-safe Configure handoff or Link token for hosted UI. Never pass OAuth access or refresh tokens. |
userId | string | No | Optional Configure user ID hint for hosted UI state. It does not authorize profile reads by itself. |
loginHint | string | No | Optional phone hint to prefill the supported phone flow. |
methods | ['phone'] | No | Optional method constraint. Phone OTP is the v1 default. |
Events
| Event | Detail | Description |
|---|---|---|
configure:linked | { token, userId, tokenUse, approved, agent } | Fired after successful linking. token is agent-scoped. |
configure:error | { code, message } | Fired on auth failure. |
The parent page never receives the user-scoped OTP JWT. New integrations should listen for configure:linked.
Backend Step
Auth surfaces do not put profile data into the model context. After Continue with Configure, use the server-side OAuth access token. After configure:linked, send the agent-scoped token to your backend. Then perform the first profile read before the personalized response and commit after the read-backed turn.
ts
const profile = configure.profile({ token });
const read = await profile.read();
const response = await model.run({
messages: [
{ role: "system", content: read.profile.format({ guidelines: true }) },
...messages,
],
tools: profile.tools(),
executeTool: profile.executeTool,
});
await profile.commit({ messages, response });Follow-On Surfaces
After Link, hosts can launch focused hosted surfaces for repair and enrichment moments:
js
Configure.connections({ presentation: "modal", publishableKey: "pk_...", agent: "your-agent" });
Configure.singleConnector({ presentation: "modal", publishableKey: "pk_...", agent: "your-agent", tool: "gmail" });
Configure.memoryImport({ presentation: "modal", publishableKey: "pk_...", agent: "your-agent", providers: "chatgpt,claude,gemini,grok" });
Configure.profileEditor({ presentation: "modal", publishableKey: "pk_...", agent: "your-agent" });
Configure.accessRequest({ presentation: "modal", publishableKey: "pk_...", agent: "your-agent", tool: "calendar" });Focused surfaces reuse the Configure-origin session created by Continue with Configure or Link. If that session is unavailable, launch Configure.link() first and then open the repair surface.
SDK Methods
WARNING
For production browser linking, use Configure.link() instead of calling these directly. These methods are documented for trusted server-side or headless contexts only.
sendOtp
typescript
auth.sendOtp(phone: string): Promise<OtpStartResponse>Send a one-time password to a phone number via SMS.
verifyOtp
typescript
auth.verifyOtp(phone: string, code: string): Promise<OtpVerifyResponse>Verify a 6-digit OTP code. Returns a JWT token and user ID on success for trusted server/headless contexts.