Product Block 02 · Sellable today

Smart Intake + Triage Form

A public form that thinks. Routes the right work to the right human in 30 seconds.

Deploy: 2 days $2,000 setup $300/mo
Live demo Try the demo → https://intake.cafecito-ai.com/

Best fit: Law firms, property management cos, MCA brokers, contractors with multi-trade work, wholesale food distributors. Anywhere a generic "Contact Us" form is silently losing $50k+/yr in misrouted leads.

⚡ Self-bootstrap · paste into Claude Code or Codex

Smart Intake + Triage Form — build it without writing code

Drop the prompt below into Claude Code (`/plan` mode) or Codex. The agent will research the prospect, scaffold the worker by cloning Lavin Eviction, generate the form + extraction prompt + dashboard, deploy it, and hand you a Loom + cold pitch draft.

You provide

You provide: (1) a prospect slug from /new-hire/prospects (or any law firm / PM co / MCA broker URL), (2) the prospect contact email.

You get back

You get: a hosted intake form on a sub-route of cafecito-ai.com, a password-gated dashboard URL, a 60-second Loom of submit→route→confirm, and a draft cold-pitch email + WhatsApp.

Runtime & cost

Roughly 75 minutes wall-clock with you watching at the gates. ~$1-2 in Claude tokens during testing.

📋 Copy the entire block below into Claude Code (`/plan`) or Codex
You are building a Smart Intake + Triage Form (Block 02 in the Cafecito AI new-hire playbook). Full reference at https://cafecito-ai.com/new-hire/blocks/02-smart-intake-triage. Read it first. Use plan mode. Stop at every [GATE].

INPUTS YOU NEED FROM THE HUMAN (ask before doing anything else):
1. Prospect slug from /new-hire/prospects (or a URL if not in the list)
2. Prospect decision-maker email (managing partner / owner / ops lead)

ENVIRONMENT (verify, don't change):
- Working dir: /home/eratner/cafecito-ai
- Cloudflare account: f7a9b24f679e1d3952921ee5e72e677e
- Wrangler authenticated via OAuth (`npx wrangler whoami`)
- Reference scaffold: /home/eratner/lavin-eviction/

SECRETS TO CONFIRM (don't create — ask if missing):
- ANTHROPIC_API_KEY (Claude Sonnet for tool-use extraction)
- RESEND_API_KEY (transactional email)
- TWILIO_SID, TWILIO_TOKEN (for SMS confirmations)

THE PLAN — execute step by step, asking for approval at each [GATE]:

STEP 1 — RESEARCH THE PROSPECT (10 min)
- Fetch prospect site. Submit their existing "Contact Us" form with a fake but realistic case. Time the response. Save the screenshot of their reply (or the absence of one).
- Call their front desk if listed. Ask how they triage matters: "if I have a slip-and-fall vs a contract dispute, who handles each?" Capture the routing tree.
- Identify their typical matter types (3-5).
[GATE 1 — show baseline response time + routing tree, ask "proceed?"]

STEP 2 — DESIGN THE EXTRACTION SCHEMA (10 min)
- Use Prompt #1 from the block page ("Extraction-schema generator") with the routing tree from Step 1.
- Output: Claude tool-use JSON schema (5-7 fields), the extraction prompt, the routing function pseudocode.
[GATE 2 — show schema + routing function, ask "this matches your understanding of their workflow?"]

STEP 3 — SCAFFOLD THE WORKER (10 min)
- Create directory /home/eratner/cafecito-ai/intake-<prospect-slug>/.
- Clone the Lavin Eviction worker (from /home/eratner/lavin-eviction/). Rename worker, D1 database, KV namespace.
- Use Prompt #2 from the block page ("CF Worker scaffold from Lavin pattern") to generate worker.js + wrangler.jsonc + D1 migration with the schema from Step 2.
[GATE 3 — show worker.js + wrangler.jsonc, ask "deploy this scaffold?"]

STEP 4 — BUILD THE PUBLIC FORM (10 min)
- Use Prompt #3 from the block page ("Public form HTML generator") with prospect's name + brand color (pull from their site CSS).
- Wire as a route: GET /intake → returns form HTML. POST /api/intake → handler.
[GATE 4 — show the rendered form on localhost via wrangler dev, ask "looks like their brand?"]

STEP 5 — DEPLOY (5 min)
- Set secrets: `wrangler secret put ANTHROPIC_API_KEY`, RESEND_KEY, TWILIO_SID, TWILIO_TOKEN, INTAKE_PASSWORD, FROM_EMAIL, FROM_PHONE.
- Apply D1 migration: `wrangler d1 migrations apply intake-<slug>-db --remote`.
- Deploy: `unset CLOUDFLARE_API_TOKEN && NODE_OPTIONS="--dns-result-order=ipv4first" NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt CLOUDFLARE_ACCOUNT_ID=f7a9b24f679e1d3952921ee5e72e677e npx wrangler deploy`.
- Print the live URL (e.g. https://intake-<slug>.evan-ratner.workers.dev/intake).
[GATE 5 — print the URL, ask "submit your first test case now"]

STEP 6 — FIVE-CASE TEST PASS (15 min)
- Wait for human to submit 5 cases: emergency-in-Spanish, routine-English, misrouted matter, attachment-heavy, angry/hostile.
- Tail `wrangler tail intake-<slug>` and the D1 intake_records table during testing.
- Ask the human "what failed?" After each fault, edit the prompt or worker, redeploy in 60 sec, ask them to re-test.
- Loop until 5/5 pass.
[GATE 6 — confirm 5/5 passed, ask "ready to record demo?"]

STEP 7 — RECORD THE DEMO (5 min, human action)
- Tell human: "Open Loom or QuickTime. Record one 60-second Loom showing: (a) submit a Spanish case with attachment, (b) the routing email landing in your inbox, (c) the SMS confirmation arriving on your phone, (d) the dashboard view of the new intake. Save the URL."
- Wait for the URL.

STEP 8 — DRAFT THE COLD PITCH (5 min)
- Use Prompt #4 ("Cold pitch with the receipts") with: baseline-response-time from Step 1, demo Loom from Step 7, intake URL from Step 5, prospect contact email from initial inputs.
- Output: subject + email body + WhatsApp message. Don't send.
[GATE 7 — show the draft, ask the human to approve / edit / send manually]

STEP 9 — SHIP THE SUMMARY (2 min)
- Single-line summary for Slack: "[FIRM NAME] intake form live at [URL] · demo: [LOOM] · pitch sent to [EMAIL]."
- Append to /home/eratner/cafecito-ai/intake-shipped.md.

DONE. End the plan.

GUARDRAILS: never deploy without all secrets set. Never bypass [GATE]s. If a step takes 2x its estimate, escalate. Cost ceiling for testing: $3 in Claude tokens.

META: this is the same operating loop as Block 01. Once you've watched it run a few times, the next plan in the series is the BUILDER agent that runs THIS plan unattended for any (prospect, block) pair.
01Stack
  • CF Worker + Hono
  • D1 (intake records)
  • Claude tool-use (extraction + routing)
  • Resend (email)
  • Twilio (SMS)
  • R2 (uploaded files)
02Live references

Working production examples. Read the code. Steal the pattern.

  • Lavin Eviction Live property-manager intake → routes to Danny Lavin or Category Five PMs by case type · D1 lavin-eviction-db
  • Cafecito intake worker D1 cafecito-db, public form behind cafecito-admin.pages.dev
  • BoostAI scan intake Form → audit → 14-day email sequence — same pattern
03Day-1 plan

A real prospect. A real demo. A real outbound message — all before 5pm.

  1. 09:00–09:30 Pick a prospect with a broken intake.

    Open the prospect site. Submit their existing "Contact Us" form with a fake-but-realistic case. Set a timer for the response. Now you have the baseline you'll beat.

  2. 09:30–10:30 Audit their actual routing logic.

    Call the front desk and ask: "If I have a slip-and-fall vs a contract dispute, who handles each?" Write down the routing tree they describe. That tree IS your Claude system prompt.

  3. 10:30–11:00 Clone the Lavin Eviction worker.

    In /home/eratner/lavin-eviction/, copy the intake handler, the D1 schema, and the Claude extraction prompt. Rename worker to <prospect-slug>-intake. Don't edit logic yet — just rename.

  4. 11:00–12:00 Define the extraction schema.

    Five form fields max (mobile completion drops 40% past 5). Claude tool-use extracts the structured fields: case_type, urgency, dollar_value, language, contact_method. Use enums, not free text.

  5. 12:00–13:00 Wire the routing rules.

    A simple match table in the worker: case_type=eviction → danny@. case_type=contract → partner_a@. dollar_value>50k → escalate. Test the table against 5 hand-crafted cases before going further.

  6. 13:00–14:00 Build the bilingual confirmation.

    Resend email + Twilio SMS in the language Claude detected from the submission text. Include tracking ID, expected response window, and an "if urgent call X" fallback. The confirmation is half the value to the prospect.

  7. 14:00–15:00 Five-case test pass.

    Submit: an emergency in Spanish, a routine matter in English, a misrouted case (e.g. divorce sent to a corporate firm), an attachment-heavy submission, an angry/hostile submission. Note every fault — fix or note for v0.2.

  8. 15:00–16:00 Build the dashboard.

    One screen showing today's intakes, where they routed, whether the human responded. The dashboard is what makes them keep paying $300/mo. Use cafecito-admin.pages.dev as the pattern.

  9. 16:00–17:00 Send the cold pitch with the receipt.

    Email + WhatsApp the managing partner / owner. Attach a Loom: "I submitted your form at 9:04. Got an automated reply at 16:30. Here's what mine does in 30 seconds." Price plainly. Reply target: tomorrow.

04Best practices & gotchas
  • Five fields max on the form. Anything more bleeds completions.

    Why: Mobile completion drops 40% past 5 fields. Every extra field is a closed tab. Use Claude tool-use to extract from a single "describe your situation" textarea instead of asking 12 structured questions upfront.

  • Use Claude tool-use for extraction. Never regex, never keyword matching.

    Why: Real submissions are messy: "my tenant won't pay and the AC broke and they have a dog and..." Tool-use handles ambiguity, multi-issue cases, and language drift. Regex breaks the moment a customer surprises you.

  • Confirm in the customer's language, not the firm's.

    Why: A Spanish-speaking client who gets an English autoreply assumes nobody read their case. Detect language from the submission text (not browser locale). The internal routing email can be in English; the customer-facing confirmation must match the customer.

  • Idempotency key on submit (form session ID + timestamp window).

    Why: Mobile users double-tap. Tab-restore re-fires. Without idempotency you create three D1 rows for one customer and email three lawyers about the same case. Hash the session ID, reject duplicates within 60 seconds.

  • Never store unencrypted PII (SSN, DOB, account numbers).

    Why: Law firms and PM cos handle this constantly. Plaintext in D1 is their next compliance incident. Encrypt at field level, store the key in Workers Secrets, decrypt only at routing time.

  • Dashboard auth from day 1, not "we'll add it later."

    Why: A public intake page with an open dashboard URL is a discoverable database of every one of their clients' problems. Workers Basic auth or signed cookie takes 20 minutes; "we'll add it later" never happens, and the breach absolutely will.

  • Decide hosted page vs iframe embed before you scope.

    Why: Hosted (intake.<theirfirm>.com) = SEO benefit + branding + a redirect they'll forget about. Iframe embed = ugly border + analytics blackhole + their devs hate you. For non-technical clients, hosted always.

05Prompts (copy-paste)

Drop these into Claude Code. Replace the [BRACKETED] fields with the prospect's details.

Prompt 1 Extraction-schema generator

Designs the Claude tool-use schema that extracts structured fields from the prospect's typical free-text submissions.

I'm building a smart intake form for [BUSINESS NAME], a [law firm / PM company / MCA broker / etc.] in Miami. Their typical inbound matter looks like this:

[paste 3-5 anonymized real submissions, call notes, or email threads from the prospect]

Their actual routing logic (from talking to their front desk):
- [matter type A] → [person/team]
- [matter type B] → [person/team]
- [escalation criteria, e.g. dollar value > X, urgency = same-day]

Design me:
1. A Claude tool-use JSON schema with the 5–7 fields needed to route correctly. Use enums where possible.
2. The extraction prompt that takes a free-text submission + the schema and outputs the structured fields. Handle multi-issue submissions gracefully.
3. The routing function (pseudocode) that takes the extracted fields and returns the recipient email + Twilio number.

Output schema, prompt, and routing function as three labeled blocks ready to drop into a Cloudflare Worker.
Prompt 2 CF Worker scaffold from Lavin pattern

One-shot scaffolds the entire intake worker — form endpoint, D1 schema, Claude extraction, routing, confirmations, dashboard.

Build me a Cloudflare Worker that handles a smart intake form for [BUSINESS NAME].

Reference: /home/eratner/lavin-eviction/. Clone its handler shape, D1 schema, and dashboard auth.

Endpoints:
- POST /api/intake → accepts form payload, idempotency-keys on session, calls Claude tool-use for extraction, writes to D1 intake_records, fires Resend + Twilio confirmations in detected language, fires Resend routing email to assigned human.
- GET /dashboard → password-gated (Workers Secret INTAKE_PASSWORD), shows today's intakes, who routed where, response status, search.
- POST /api/intake/:id/respond → marks responded, logs human responder, used by dashboard quick-action.

D1 schema:
- intake_records (id, ts, raw_text, extracted_json, language, urgency, case_type, dollar_value, assigned_to, responded_at, response_by)

Bindings:
- D1: INTAKE_DB
- KV: INTAKE_DEDUP (60s TTL on session hash)
- Secrets: ANTHROPIC_API_KEY, RESEND_KEY, TWILIO_SID, TWILIO_TOKEN, INTAKE_PASSWORD, FROM_EMAIL, FROM_PHONE

Output complete worker.js (Hono), wrangler.jsonc additions, D1 migration, public form HTML (5 fields, mobile-first, inline CSS), dashboard HTML. Make it ship-ready — no placeholders.
Prompt 3 Public form HTML generator

Generates the customer-facing intake form HTML — mobile-first, 5 fields, no framework, inline styles, bilingual toggle.

Generate a single-file HTML intake form for [BUSINESS NAME].

Constraints:
- Mobile-first (works at 375px width without horizontal scroll)
- Five fields max: name, contact, language preference, "describe your situation" textarea (500 char), one optional file upload
- No frameworks. Inline CSS only. No external fonts (system stack).
- Editorial palette: cream #FDF9F2, ink #1A1814, accent #B8472A. Match cafecito-ai.com.
- Submit posts as multipart/form-data to /api/intake with a hidden session_id (uuid generated client-side).
- Confirmation state in-place after submit: "Got it. We'll respond by [time]. Reference: [tracking_id]."
- Spanish + English toggle in top right (default English, persists in localStorage).
- One-paragraph trust line under the form ("Submitted in confidence. Response within [X] hours.").

Output: complete index.html, ready to paste into the worker as a string template literal.
Prompt 4 Cold pitch with the receipts

The outreach email + Loom pairing — the demo IS the pitch. Submit their broken form, then send yours.

Write me a 4-sentence cold email + 2-sentence WhatsApp follow-up to [DECISION MAKER] at [BUSINESS NAME] in Miami.

Setup: I submitted their existing "Contact Us" form at 9:04am with a realistic case. Got back [auto-reply | hours-later real reply | nothing] at [TIME]. I built them a smart intake form that handles the same submission in 30 seconds with the right person looped in.

The Loom (90 sec) shows: their form submission timestamp → their delayed/absent reply → my form submission → instant routing email landing in the right inbox → bilingual SMS confirmation to the customer.

Email should:
- Open with the specific timestamp gap (actual numbers)
- Link the Loom prominently
- Name the price ($2k setup, $300/mo)
- Ask one yes/no question that makes "yes" easy

WhatsApp should:
- One line acknowledging the email + the Loom URL
- Offer to white-label under their domain by tomorrow

No emojis. No "circle back." No "hope this finds you well."
06Selling script

Discovery question (ask this first)

"When a new client fills out your contact form on a Saturday, what happens? Walk me through it minute by minute."

The frame

Every form submission that gets misrouted, delayed past 24 hours, or lost in voicemail is a client who hires the firm down the street. A bilingual triage form that routes correctly in 30 seconds pays for itself the first time it captures a single $5k matter you would have lost.

The demo play

Submit their existing form during the discovery call. Then submit yours from the same phone. The 30-second roundtrip is the entire pitch — they hear the SMS land before you finish the next sentence.

Objections

  • "My customers don't fill out forms — they call."

    "Half do. The half that calls already gets through. The half that gives up after voicemail — that's your revenue leak. The form catches the half you're losing without anyone noticing."

  • "What about privacy / HIPAA / attorney-client privilege?"

    "Field-level encryption, decryption only at routing, no plaintext PII at rest. I'll send the architecture doc and walk through it with your IT person before we ship a line of code."

  • "My staff handles intake fine."

    "Your staff handles intake during business hours. The form handles it the other 128 hours a week. It doesn't replace your staff — it stops your weekends from leaking $50k a quarter to the firm that does answer."

  • "$300/mo seems steep for a form."

    "It's a form, a routing brain, a bilingual customer-confirm system, and a dashboard. The closest your IT vendor would quote is $15k of build-time and $1.5k/mo. This is the same thing without the project."

The close

"$2k now puts it live this week on your subdomain. $300/mo from the day it takes its first submission. If it doesn't catch one matter you would have lost in 30 days, kill it — no contract."

07Pricing notes

Anchor on the lost-matter math. A single mid-size matter (legal: $5k, PM: $3k repair, MCA: $2k commission) more than covers the first year. Per-message Twilio cost ~$0.008. Setup includes: form, Claude extraction, D1 schema, dashboard, bilingual confirms, routing logic, 1hr training. Does NOT include: CRM integration ($1k), white-label dashboard branding ($500), custom encryption ($1k). Upsell: bundle Block 01 → "24/7 Front Desk" at $700/mo.