Questionnaire
The questionnaire collects home details, eligibility criteria, and condition information needed to generate an offer. It uses the same OpendoorProvider context as AddressEntry.
Basic usage
import { QuestionnaireProvider, QuestionnaireLayout, homeConfirmationPage, homeFeaturesPage, homeConditionPage, mapPrefillsToAnswers,} from '@opendoor/partner-sdk-client-react';import { useOpendoorClient } from '@opendoor/partner-sdk-client-react';
const pages = [homeConfirmationPage, homeFeaturesPage, homeConditionPage];
function Questionnaire({ opendoorOfferRequestId }) { const client = useOpendoorClient(); const [initialAnswers, setInitialAnswers] = useState({}); const [isLoading, setIsLoading] = useState(true);
// Load prefilled answers from Opendoor (MLS data, property records) useEffect(() => { client .getHomeDetail({ opendoorOfferRequestId }) .then((result) => { setInitialAnswers(mapPrefillsToAnswers(result.answerPrefills)); }) .catch(() => {}) // Not fatal — form starts empty .finally(() => setIsLoading(false)); }, [opendoorOfferRequestId]);
const handleSubmit = async (answers) => { await client.updateOffer(opendoorOfferRequestId, answers); };
if (isLoading) return <p>Loading...</p>;
return ( <QuestionnaireProvider pages={pages} initialAnswers={initialAnswers} onSubmit={handleSubmit} > <QuestionnaireLayout /> </QuestionnaireProvider> );}How it works
- Load prefills —
getHomeDetail()calls the GraphQLsellerInputPrefillsquery to get property data Opendoor already knows (bedrooms, year built, etc. from MLS) - Map keys —
mapPrefillsToAnswers()converts the API’s dot-notation keys to the camelCase keys the questionnaire uses (which match GraphQLOfferInputfield names) - Render form —
QuestionnaireProvidermanages answers in local state,QuestionnaireLayoutrenders pages with a sidebar review card - Submit — answers are sent directly to
updateOffer()since the keys already matchOfferInput
Prebuilt pages
| Page | Fields |
|---|---|
homeConfirmationPage | Bedrooms, bathrooms, sq ft, dwelling type, year built, HOA, eligibility criteria |
homeFeaturesPage | Basement, pool, parking, kitchen features, room features, exterior features |
homeConditionPage | Interior conditions, exterior conditions, system conditions, seller scores |
Lifecycle callbacks
| Callback | Type | When it fires |
|---|---|---|
onReady | () => void | Provider mounted |
onSubmit | (answers) => void | Last page completed |
onPageChange | (index, page) => void | User navigates between pages |
onAnswerChange | (key, value) => void | Any answer changes |
onError | (error: Error) => void | Any error occurs |
Answer keys match GraphQL
The questionnaire uses GraphQL OfferInput camelCase field names as answer keys:
homeBedrooms, homeBathroomsFull, homeBathroomsPartial,homeAboveGradeSqFt, homeDwellingType, homeYearBuilt,homeKitchenCondition, homeBathroomCondition, ...When you call client.updateOffer(id, answers), the keys go directly to GraphQL with no transformation needed.
Questionnaire-internal keys (feature toggles, condition checkboxes) use dot-notation and don’t get sent to GraphQL — they feed derived fields like seller scores.