Pre-fill Onboarding with Brand Data
Reduce friction in your sign-up flow by auto-populating company information the moment a user enters their email or domain.
The Problem
Users abandon onboarding forms that ask too many questions. Company name, logo, industry, website — every field is a drop-off point.
The Solution
Use Orsa to pre-fill brand data automatically:
- User enters their work email
- You extract the domain and call Orsa
- Pre-fill company name, logo, colors, and industry
- User confirms and continues
Architecture
User enters email → Extract domain → Orsa API → Pre-fill form
↓ ↓
ceo@stripe.com stripe.com Title: "Stripe"
Logo: ✓
Colors: ✓
Industries: ["Fintech"]Implementation
Step 1: Fetch on email blur
Call retrieveSimplified when the user finishes typing their email. This minimal endpoint returns just what you need to pre-fill a card.
// On email blur/change (debounced ~300ms)
async function onEmailBlur(email: string) {
if (!isBusinessEmail(email)) return;
const domain = email.split('@')[1];
try {
const profile = await client.brand.retrieveSimplified({ domain });
setCompanyName(profile.title);
setCompanyLogo(profile.logo);
setPrimaryColor(profile.primaryColor);
setIndustries(profile.industries ?? []);
} catch (err) {
// 404 just means we haven't seen this domain — silently skip the pre-fill.
// The user can still type the company name manually.
}
}retrieveSimplified returns { domain, title, description, logo, primaryColor, industries } — exactly what a confirmation card needs.
Step 2: Let the user confirm
Show the pre-filled data with an option to edit. Most users will just click “Continue.”
<OnboardingForm>
<CompanyCard
name={companyName}
logo={companyLogo}
color={primaryColor}
editable
/>
<p>Is this your company?</p>
<Button>Yes, continue</Button>
<Button variant="ghost">Edit details</Button>
</OnboardingForm>Step 3 (optional): Fetch the rich profile after confirmation
If your onboarding goes deeper — picking an industry from a curated list, showing socials in the sidebar — pull the full record after the user confirms:
async function onSubmit(email: string) {
const domain = email.split('@')[1];
const brand = await client.brand.retrieveByEmail({ email });
// Use brand.industries, brand.socialLinks, brand.pageLinks for the rest of onboarding.
}Full Example (Next.js Server Action)
Keep the API key server-side. The form invokes a Server Action that uses the SDK from Node.
'use server';
import Orsa, { OrsaAPIError } from '@orsa.dev/sdk';
const orsa = new Orsa({ apiKey: process.env.ORSA_API_KEY! });
export async function prefillFromEmail(email: string) {
const domain = email.split('@')[1];
try {
const profile = await orsa.brand.retrieveSimplified({ domain });
return {
ok: true as const,
data: {
name: profile.title,
domain: profile.domain,
logo: profile.logo,
color: profile.primaryColor,
industries: profile.industries ?? [],
},
};
} catch (err) {
if (err instanceof OrsaAPIError && err.status === 404) {
return { ok: false as const, reason: 'no_brand_cached' };
}
throw err;
}
}Credit Cost
| Step | Endpoint | Credits |
|---|---|---|
| Pre-fill on email blur | GET /v1/brand/retrieve-simplified | 10 |
| Rich profile on submit (optional) | GET /v1/brand/retrieve-by-email | 10 |
| Total per sign-up | 10–20 credits |
Repeated calls for the same domain hit the cache and don’t deduct further credits.
Tips
- Debounce the email-blur call. You don’t want to fire an API request for every keystroke.
- Handle free email domains gracefully. Gmail, Yahoo, etc. won’t have meaningful brand data — show a “Please use your work email” message before calling the SDK at all.
- Cache brand data in your database after the first lookup to avoid repeat charges for the same company across sign-ups.
- Wrap the call in a Server Action / route handler so your API key never ships to the browser.