Skip to content

After this module you can turn a two-minute discovery form into a priced, on-brand proposal page the client can accept online, in under a minute.

What it does

The demo business is Brightline Studio (a small web agency). The service catalog (services, tiers, prices, weeks, deliverables) and pricing rules live in Settings.

Entry What happens
Discovery Form (/form/proposal-intake, separate workflow) or POST /webhook/prop/create Validate the intake, pick the best tier of each requested service that fits the budget (bundle discount for 3+ services, tax, deposit, 14-day validity), flag over-budget, no-budget and timeline problems. OpenAI writes summary, understanding, approach and next steps (template if AI fails); guardrails replace any price that isn't in the quote and flag promises like "guaranteed". Builds a hosted proposal page with a private link and emails it with Gmail
GET /webhook/prop/view?id=…&t=… The proposal page (token required). Counts views; shows an expiry or accepted banner
POST /webhook/prop/accept The page's accept form (typed name + checkbox). Records who accepted and emails the owner; 409 if already accepted, 410 if expired
GET /webhook/prop/status?id=… or ?email=… Status, views, flags, quote (no HTML or token)

Create options: dry_run (returns the page HTML, saves nothing), send_email: false, ai: false, sections (supply your own text, still checked), now (inject the clock).

Flow

learner-form.json: Discovery Form → To API Body → Create Proposal (HTTP POST prop/create)

Create API ─┐
View API ───┤
Accept API ─┼→ Settings → Route ─create→ Build Quote → Valid Intake? → Use AI? ─yes→ Write Sections (OpenAI) ─┐
Status API ─┘                  │                                   └no─────────────────────────────────────┴→ Join Branches → Assemble Proposal
                               │      → Dry Run? → Email It? → Email Proposal (Gmail) → Record Sent → respond
                               ├view→ Render Proposal → HTML page
                               ├accept→ Accept Proposal → Accepted? → Notify Owner (Gmail) → thank-you page | error page
                               └status→ Proposal Status → respond

Verification status (n8n 2.43.6)

  • 29 behavior checks (55 assertions) without credentials: tier selection against the budget, bundle discount, over-budget/no-budget/timeline flags, service names from form checkboxes, validation, template fallback when AI fails, price and promise guardrails, HTML escaping, private link and token, view counting (preview excluded), accept validation, double accept (409), expiry banner and 410, send_email: false, Gmail failure reported, and a real n8n Form submission creating a proposal.
  • Not run with OpenAI or Gmail credentials (WITH_CREDS=1 TEST_EMAIL=… ./test/test.sh). AI section quality and real email delivery are unverified.

Files

File Tier Purpose
lesson.md Free Step-by-step build
workflow/starter.json Free Endpoints, Settings, quote builder
workflow/learner.json Learner Finished workflow
workflow/learner-form.json Learner Discovery form workflow
workflow/code/ Learner Readable copies of the Code nodes + AI prompt
exercises.md Learner Practice tasks
solutions.md Learner Exercise solutions
notes.md Private Learning log
sell/ Private Offer, video script, blog post