Add Configure to onboarding
Use the Quickstart integration in onboarding, settings, or a first-run screen. Follow steps 2, 3, and 5 for the connection button, redirect, and callback. In this guide, the callback displays connected sources and prefills the next screen. The credential, refresh, commit, and tool requirements remain the same.
Implement these two helpers in your app:
ts
import { Configure } from "configure";
export const configure = new Configure({ apiKey: process.env.CONFIGURE_API_KEY, agent: process.env.CONFIGURE_AGENT });
export const profileFor = (userId: string) => configure.profile({ externalId: userId }); // one handle per user, keyed by your id
// The daily read, also run once on the return. Returns null until the user has connected.
export async function refreshContext(userId: string) {
const read = await profileFor(userId).read({ sections: ["identity", "preferences", "summary", "integrations"] });
if (!read.profile.linked) return null;
const text = read.profile.format();
await store(userId, text); // `store` is your database: one string per user
return text;
}Add the connection button and callback
Add a connection button to the onboarding screen. The button links to a server route that creates a connection URL with returnUrl. Configure redirects the user to that callback URL after they complete the hosted flow.

The callback route reads imported context and app connection status, caches the profile (Quickstart, step 6), and displays a confirmation screen.
ts
const RETURN_URL = "https://yourapp.com/onboarding/return"; // a constant, never from the request
const APPS = { gmail: "Gmail", calendar: "Google Calendar", drive: "Google Drive", notion: "Notion", sheets: "Google Sheets", outlook: "Outlook" };
// The onboarding step's chip links here.
app.get("/onboarding/connect", async (req, res) => {
const connect = await profileFor(req.user.id).connect({ returnUrl: RETURN_URL });
res.redirect(connect.connect_url); // Configure's page, then back; a user who already connected comes straight back
});
// Configure sends the user here when they finish.
app.get("/onboarding/return", async (req, res) => {
const { profile } = await profileFor(req.user.id).read({
sections: ["identity", "imports", "integrations"],
});
if (!profile.linked) return res.redirect("/onboarding?step=2¬ice=not-connected"); // they closed Configure's page early
const brought = [
...Object.values(profile.imports)
.filter((source) => source.memory_count)
.map((source) => `${source.memory_count} memories from ${source.name}`),
...Object.entries(profile.integrations)
.filter(([, app]) => app.connected)
.map(([id]) => `${APPS[id] ?? id} connected`),
];
await refreshContext(req.user.id); // their first chat starts with their context
res.render("welcome", { name: profile.identity.given_name, brought, next: "/onboarding?step=3" });
});imports is keyed by assistant, such as { chatgpt: { name: "ChatGPT", memory_count: 9 } }. integrations is keyed by app, such as { gmail: { connected: true } }. For Nova Sandbrook, the sandbox user, brought is ["9 memories from ChatGPT", "Gmail connected", "Google Calendar connected"].

Apply these callback requirements:
returnUrlmust behttps, even while you develop, and it is a constant, never built from the request. Configure sends the user there without a click when the browser'sRefererorigin matches it, which the default policy sends, or when its host is inallowed_return_hostson your developer account. Otherwise the user sees a button that names the host. That list is separate fromnpx configure add origin, which registers an OAuth callback and has no effect here.- Check
profile.linkedin the callback route. A request to the callback URL does not prove that the user connected.
New imports can take a few minutes to process. The first callback read may return incomplete context.
Fill in the next step
Use approved profile fields to prefill the next onboarding screen.

What you can fill in, from read({ sections: ["identity", "summary", "integrations"] }):
| Field | Where it comes from |
|---|---|
identity.given_name, identity.family_name, identity.email | The account the user signed in with. identity.email_verified says whether Configure verified it. |
identity.role, identity.occupation, identity.location, identity.company_website | Derived from saved context. Missing values are null. Let the user review and correct populated values. |
integrations.gmail.connected, and the same for calendar, drive, notion, sheets | App connection status. Display connected apps as connected. |
summary | One paragraph on who the user is and how they like to work. |
If a field is still null, ask for it on the next screen. A user who skips this step can connect later from the connection button in your app (Quickstart, step 2).

Refresh the profile daily even if the connection button appears only during onboarding. Other connected agents and apps can update context after sign-up. Follow Quickstart step 6.
Next
- The complete chat integration: Quickstart.
- Configure's own buttons for this step: Components.