Skip to content

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

  1. Load prefillsgetHomeDetail() calls the GraphQL sellerInputPrefills query to get property data Opendoor already knows (bedrooms, year built, etc. from MLS)
  2. Map keysmapPrefillsToAnswers() converts the API’s dot-notation keys to the camelCase keys the questionnaire uses (which match GraphQL OfferInput field names)
  3. Render formQuestionnaireProvider manages answers in local state, QuestionnaireLayout renders pages with a sidebar review card
  4. Submit — answers are sent directly to updateOffer() since the keys already match OfferInput

Prebuilt pages

PageFields
homeConfirmationPageBedrooms, bathrooms, sq ft, dwelling type, year built, HOA, eligibility criteria
homeFeaturesPageBasement, pool, parking, kitchen features, room features, exterior features
homeConditionPageInterior conditions, exterior conditions, system conditions, seller scores

Lifecycle callbacks

CallbackTypeWhen it fires
onReady() => voidProvider mounted
onSubmit(answers) => voidLast page completed
onPageChange(index, page) => voidUser navigates between pages
onAnswerChange(key, value) => voidAny answer changes
onError(error: Error) => voidAny 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.