Skip to content

DTC Onboarding Flow

The DtcOnboardingFlow component renders the traditional (non-instant-offer) questionnaire, matching the DTC flow on opendoor.com. It presents 17 pages of questions — one per screen — with a two-column layout on desktop and stacked layout on mobile. It handles navigation, validation, conditional page skipping, and fires onSubmit when the user completes the flow.

DtcOnboardingFlow component

Basic usage

import { DtcOnboardingFlow } from '@opendoor/partner-sdk-client-react';
import { OpendoorClient } from '@opendoor/partner-sdk-client-js-core';
const client = new OpendoorClient({ baseURL: '/api/opendoor/v1' });
function App({ address }) {
return (
<DtcOnboardingFlow
address={address}
appearance={{ theme: 'minimal' }}
partnerLogoUrl="/your-logo.svg"
onSubmit={async (answers) => {
const offer = await client.createOffer({ address, ...answers });
}}
onClose={() => console.log('User closed the flow')}
/>
);
}

DtcOnboardingFlow does not require <OpendoorProvider>. It manages its own state internally.

Props

PropTypeDefaultDescription
addressAddressRequiredThe selected property address
onSubmit(answers) => voidRequiredCalled when user completes all pages
partnerLogoUrlstring-Partner logo URL (shown before the Opendoor logo in header)
appearanceOpendoorAppearance{ theme: 'minimal' }Visual theme configuration
initialAnswersRecord<string, AnswerValue>-Prefill data (e.g., from address lookup)
marketstring-Market identifier for region-specific questions
onClose() => void-Called when close (X) button is clicked

Callbacks & Events

CallbackTypeWhen it fires
onReady() => voidComponent mounted and ready
onSubmit(answers) => voidUser completed all pages
onPageChange(pageIndex, pageId) => voidUser navigates between pages
onAnswerChange(key, value) => voidAny answer changes
onError(error: Error) => voidValidation or internal error
onClose() => voidClose button clicked

Pages

The component renders 17 pages. Pages with conditional visibility are automatically skipped when their conditions are not met (e.g., HOA sub-pages are skipped when HOA = No).

#PageWhat it collects
1Confirm Home DetailsDwelling type, beds, baths, sqft, stories, basement, year, pool
2OwnershipRelationship to owner (owner, agent, other)
3Sale TimelineWhen the user needs to sell
4-7Room Condition (×4)Kitchen, bathroom, living room, exterior — 5-level image select
8HOAIs the home part of an HOA?
9HOA TypeAge-restricted, gated community (if HOA = Yes)
10HOA GuardGuard at entrance (if gated community)
11HOA FeesMonthly fees (if HOA = Yes, optional)
12Eligibility CriteriaDisqualifying property features (solar, foundation, etc.)
13UpgradesHas the home had upgrades?
14HomebuilderWorking with a homebuilder?
15Homebuilder NameWhich homebuilder (if yes)
16Homebuilder DetailsSales associate email + community name (if yes)
17Contact InfoName, email, phone, SMS consent

Prefilling answers

Pass initialAnswers to pre-populate fields (e.g., from property data):

<DtcOnboardingFlow
address={address}
initialAnswers={{
'home.dwelling_type': 'single_family',
'home.bedrooms': 3,
'home.bathrooms.full': 2,
'home.above_grade_sq_ft': 1800,
'home.year_built': 2010,
}}
onSubmit={handleSubmit}
/>

Answer keys

Answers use dot-notation keys matching the server-side schema:

home.dwelling_type, home.bedrooms, home.bathrooms.full, home.above_grade_sq_ft,
home.kitchen_seller_score, home.hoa, home.hoa_type, home.eligibility_criteria,
seller.relation_to_owner, seller.sale_timeline, seller.full_name, seller.email,
seller.phone_number, seller.working_with_home_builder, ...

When you call client.createOffer() or client.updateOffer(), the server SDK maps these keys to the GraphQL schema automatically.

Styling

The component uses the appearance prop for theming. It defaults to the minimal theme. All standard tokens apply — colors, fonts, spacing, borders, and radii are shared with other SDK components like AddressEntry and QualificationQuestions:

<DtcOnboardingFlow
address={address}
appearance={{
theme: 'minimal',
variables: {
colorPrimary: '#003366',
fontFamily: '"Inter", sans-serif',
colorCardBorderSelected: '#003366',
colorCardBackgroundSelected: '#f0f5ff',
},
}}
onSubmit={handleSubmit}
/>

The card selection tokens (colorCardBackground, colorCardBorder, colorCardBorderSelected, colorCardBackgroundSelected) control the selectable card components used for radio and checkbox inputs.

See the Styling & Themes guide for all available tokens.

Resetting the form

To reset the component (e.g., start over with a different address), change the key prop:

<DtcOnboardingFlow
key={address.street1}
address={address}
onSubmit={handleSubmit}
/>