A branded, mobile-friendly form at /client/[id]/info. Which sections render is controlled per tenant by the intake_form_sections map on invoice_settings. Answers are stored as form_data on both the estimate link and the contract row, so the contract can always be re-rendered from exactly what the customer stated.
Also called: intake form · customer info form · project info questionnaire · customer details before contract · customer information form · collect legal info · onboarding form
- 1Customer approves the estimate and lands on the form (no login, no password — the link id is the auth).
- 2Fields pre-fill from what's already known, with a deliberate exception: a partial name like 'keith' with no last name is left blank so the customer types their FULL legal name.
- 3Submit posts to /api/client-portal/submit-form, which renders and freezes the contract and stamps customer_form_completed_at.
- 4The customer is routed straight to /client/[id]/contract.
The library header lays out the pipeline it serves: estimate signed → configurable form → contract row created with the body frozen → customer signs → admin counter-signs. The name pre-fill guard is a real defect fix: 'A partial GHL first name like "keith" would otherwise sit pre-filled and get submitted as the legal name — leave it blank so the customer enters their FULL legal name.' A contract signed under a nickname is a contract with a defect in it.
- Legal name, mailing address and site address collected by phone and mistyped into a contract
- Contracts signed under an informal first name
- Ownership, permit and financing questions surfacing after the job is sold
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →