# Your first form — catch an email and answer it (Kit 9)

Kit 8 put your page online. It has a headline, a few cards, and one loud button. Somebody lands on it, reads it, likes it, and then leaves, and you never find out they were there.

That's every personal site on the internet. A front door with nobody writing down who knocked.

So this is the kit where your page stops being a brochure and starts being a business. One form. A box on your page where a person can raise their hand, and a small piece of code on your server that catches it, saves it, and writes back to them within seconds. That's the entire thing, and it is the difference between a website and an audience.

Almost everyone builds this wrong, and they build it wrong in the same way: they make the box, the box works, and nothing else exists. The address gets saved and the person who typed it hears nothing back. That is not a broken form, which is the problem. It looks like a working one.

So we build all four parts, and the last step of this kit is walking the whole thing as a stranger.

## What a list actually is (read this once)

A list is not a mailing tool. It's the only audience you own.

Everything else you have is rented. Your followers belong to a platform that can change what it shows them tomorrow, and has, repeatedly. Your search traffic belongs to an algorithm. Your ad reach belongs to whoever you last paid. An email address is the one connection where nothing sits between you and the person except a mail server, and yours is the mail server.

That's why this comes before anything clever. A hundred people who chose to hear from you is worth more than ten thousand followers you can't reach on purpose.

And a real list is four things, not one:

1. **A form** the person fills in.
2. **A place the address lands** that you control.
3. **A reply that goes out immediately**, while they still remember signing up.
4. **A way out**, in every message, that works.

Skip number three and they forget you within a day. Skip number four and you are, legally and practically, a spammer. Most people build number one and think they're finished.

**One honest note before we start**, the same one I made about storage back in Kit 4. There are excellent email platforms out there. Kit, Beehiiv, MailerLite and the rest are genuinely good at this, and if you end up on one, that's a fine outcome and I'm not here to talk you out of it. Their whole business is deliverability, and they're better at it than you or I will be.

This kit isn't about avoiding them. It's about not needing one on day one, when you have four subscribers and no reason to pay a monthly bill or hand your list to somebody else to hold. You already own a domain, a server, and a mail key. Those four pieces are already enough. Start here, learn what the moving parts actually are, and move to a platform later from a position of understanding instead of guessing. Exporting a list is a file. It's not a migration.

## The four forms (pick one before you start)

They're sitting at **connectwithcliff.com/forms**, free to copy, no attribution needed. They aren't four colors of the same box. A consultant and a coffee shop don't sell the same way, so each one is built around how that kind of business actually makes money:

1. **The Booked Calendar** — if you sell your time. Consultants, coaches, attorneys, accountants, agencies. You're not collecting emails here, you're filtering for people worth talking to, so the copy disqualifies on purpose and the form asks for a first name. Someone who won't type their name won't show up to a call either.
2. **The Blueprint** — if you sell what you know. Courses, templates, guides, memberships. The headline shape is boring and specific on purpose: free, a number, the thing, and exactly who it's for. "A guide" is worth nothing. "42 pages" is a thing. No field on load, just a button, so the first commitment is one click.
3. **The First Order** — if you ship something in a box. A discount is the only lead magnet that has ever really worked in retail, so lead with the number and put the product in frame. The second line does the real work: the code gets you the email, restocks are why they stay after they've spent it.
4. **The Walk-In** — if people come to you. Cafes, salons, studios, gyms, restaurants. Your visitor is on a phone deciding whether you're worth the trip, so the offer is given away first with no email required and the ask comes after. Address and hours sit inside the form, not the footer, because that's the question they came to answer.

**How to choose if two of them fit you:** go by how well the person already knows you, not by which one looks nicest. Someone who has never heard of you should not be shown a field at all, just a button, because clicking is a smaller thing to agree to than typing. Someone who has been on your site before can take one image, one promise, one button. Someone who has been burned by people in your industry needs the thing handed over before the ask. And someone who came looking for you on purpose will read long copy all the way down to a field at the bottom.

Same email address, four different conversations. Most sites pick one shape and use it on everybody.

Pick one. You can add others later; the endpoint you're about to build handles all of them.

## Prerequisite
- **Kit 3** — your Cloudflare account, where the DNS record at the end of this goes.
- **Kit 5** — your domain.
- **Kit 6** — your Mailgun sending key, on that domain. This is the kit where it finally does something for a stranger instead of for you.
- **Kit 7** — your server. The form needs somewhere to post to.
- **Kit 8** — your page. That's where the form goes.
- Kit 1's terminal and Claude Code, so Claude can build and deploy it.

If Kit 6 is the one you skipped, do it first. Everything here depends on being able to send mail from your own domain.

## How to use it (any OS)
- **Quick:** hit Copy, open Claude Code, paste this in, and say the line below.
- **Most reliable:** hit Download, then tell Claude:
  *"read ~/Downloads/signup-form-setup.md and build it with me."*

Either way, say:

> "Help me put a working email signup form on my personal page and wire it up end to end on my own server. Interview me first, one question at a time, don't dump a form on me: (1) which of the four forms I want from connectwithcliff.com/forms (The Booked Calendar if I sell my time, The Blueprint if I sell what I know, The First Order if I ship something in a box, The Walk-In if people come to me) and any color changes I want, (2) what someone actually gets by signing up, in concrete terms, because I need three real lines and not 'join my newsletter', (3) whether I'm giving away a specific free thing or just a regular email, (4) what my welcome email should say in my own voice, (5) my from-name and reply-to address on my Kit 6 domain, and (6) the one thing I want someone to do straight after they sign up, because that is what goes on the thank-you page. Then write the copy WITH me before you build anything, and hold me to this: the form promises what shows up in their inbox and how often, in plain words a stranger would believe. No 'exclusive insights', no 'join the community', no fake scarcity. If my three lines are vague, push back and make me be specific. Then build it: (a) put the form on my Kit 8 page, styled to match it; (b) build a small endpoint on my Kit 7 server that accepts the signup, validates the email format, rejects disposable-address domains, and rate-limits by IP so a bot can't hammer it. Tell me plainly what you are installing before you install it: my server currently just hands out static files, so this needs a runtime (Node is fine), a process manager so it survives a reboot, and an nginx rule that passes /api through to it. Copy my working nginx config to a backup file BEFORE you touch it, and if the new config fails its test, put the old one straight back so my site never goes down. Never expose the app's own port to the internet; everything reaches it through nginx; (c) store subscribers in a single SQLite file on my server with these exact columns: email, subscribed_at, consent_ip, consent_text, source (which page and form), status, and unsubscribe_token. My site sits behind Cloudflare and nginx, so make sure you record the visitor's real IP and not the proxy's, and rate-limit on that same real IP, otherwise every visitor looks like one person. For consent_text, store the exact sentence printed under the button on my form, word for word, and make sure that sentence actually says what they will get and how often. Normalise the address before saving it, lowercased and trimmed. Set up a nightly copy of that SQLite file to my Kit 4 storage, because a list living in exactly one place is a list I will eventually lose; (d) send the welcome email immediately through my Kit 6 Mailgun, from my own domain, with a working unsubscribe link and both the List-Unsubscribe and List-Unsubscribe-Post headers so Gmail and Outlook show their own unsubscribe button. Check with me first whether my Mailgun account is US or EU, because they are different API addresses and the wrong one fails quietly. Single opt-in is what I want, so the welcome goes out on submit; tell me if anything about my audience or where they live means I should be doing confirmed opt-in instead; (e) at the same time send a copy of every signup to my own inbox so I always have a second copy of my list outside the server; (f) build a real thank-you page at its own address, not just a message that swaps in where the form was, and send people to it after they sign up. It has to tell them to look in spam and drag the email into their inbox, because that one instruction is what makes the rest of my emails arrive at all, and it has to point at the one next thing I told you about. Keep the inline message as the fallback if the redirect ever fails; (g) build the unsubscribe route so the link in the email actually works, flips their status, and shows a real page; (h) make it idempotent: if the same address signs up twice it must not send a second welcome, and treat addresses as the same when they differ only by capitalisation or surrounding spaces. If someone who previously unsubscribed signs up again, put them back to active, issue them a fresh unsubscribe token, retire the old one, and do send the welcome that time; (i) add a DMARC record to my Kit 3 Cloudflare alongside the SPF and DKIM from Kit 6, and start it on the monitoring setting rather than the strict one, so I find out about problems instead of bouncing my own mail on day one. Explain what it is doing and when I should tighten it. Important: put the save, the welcome, the consent record and the notification in ONE shared function that every form on my site calls, so I can never add a second form later that saves the address but forgets the welcome. Then test it in front of me as if you were a stranger: ask me for an address at a different provider from my own domain and have me keep that inbox open, submit the form from the live page, show me the row in the database, have me confirm the welcome actually arrived and tell you whether it landed in inbox or spam, then click the unsubscribe link and show me the status change. Do not tell me it works until you've watched all four happen. Finally, show me the one command I can run to see my subscribers, and the one command to export them to CSV so I'm never locked in."

## What it sets up

**1. The form on your page.** The one you picked, in your color, matching the page from Kit 8. Plain HTML and a few lines of CSS living in the same file as everything else. No embed script, no third-party widget loading on your site, nothing phoning home to a company you've never met.

**2. A real endpoint.** This is your first piece of code that does something when a stranger touches it. It's small, maybe sixty lines, and once you've built one you understand what every API you've ever used is doing underneath. It validates, it rate-limits, it saves, it replies.

**3. One file that holds your list.** A single SQLite file on your server. It's a real database, but it's one file you can copy, back up, or email to yourself. No database server to run, no hosting bill, no dashboard. Claude can read it conversationally: ask "how many people signed up this week" and it just answers.

**4. The welcome email, immediately.** The whole point. They hit the button and within seconds something from your domain, in your voice, lands in their inbox. This one email does more for whether they remember you than the next ten you send.

**5. The consent record.** Five extra columns written at signup: when they signed up, from what IP, what the checkbox or button literally said, where they came from, and their unsubscribe token. Nobody adds these before they need them, which is exactly why you should. The day a platform, a partner, or a regulator asks how you got an address, you either have the answer or you don't.

**6. A second copy in your inbox.** Every signup also emails you. It sounds redundant. It's the cheapest backup you will ever build: if the server dies tonight, your entire list is still sitting in your own email, searchable.

**7. The page they land on.** A real thank-you page at its own address, not a line of text swapping in where the form was. It does three jobs a message cannot: it tells them to check spam and drag the email into their inbox, which is the single cheapest thing you can do to make your future emails arrive; it points them at one next step while you have their full attention; and because it is a page with its own URL, you can measure it, and one day put an ad pixel on it.

**8. A working way out.** One-click unsubscribe in every message, the proper `List-Unsubscribe` header so Gmail and Outlook show their own unsubscribe button, and a real page when they click. Building this on day one costs an hour. Retrofitting it after you have a list costs a weekend and some goodwill.

**9. One shared function.** Every form on your site runs through the same code path. This is the one people skip, and it is the one that bites. If adding a second form means copying the logic, then one day you copy nine tenths of it and ship the version that saves the address and never writes back. Build it once, call it from everywhere, and that failure becomes impossible instead of unlikely.

## Where your emails go, and what to do with them

This is the question I get asked most, and it's the one nobody answers, so here's how I'd actually run it if I were starting tonight.

**Answer the first fifty by hand.** Not as a growth tactic. As research. When someone signs up, reply personally and ask what they're working on. You will learn more about who your audience actually is from ten real replies than from any amount of analytics, and you'll find out fast if the people signing up are the ones you thought. Automate the conversation only after you know what the conversation is.

**Let them land in your normal inbox, with a label.** Don't build a support desk for four people. The notification from step 6 arrives in the inbox you already read, and a single filter tags it. When a real thread starts you just reply like a human, because you are one.

**Keep the list and the inbox separate in your head.** The SQLite file is who's on your list. Your inbox is your conversations. Don't try to make one do the other's job. That confusion is what makes people buy a CRM in month one and never open it again.

**Back it up on a schedule you don't think about.** One line in your server's crontab copying that file to your Kit 4 storage nightly. Ask Claude for it while you're in there. A list that exists in exactly one place is a list you're going to lose.

**Don't mail people until you have something to say.** The most common failure isn't sending too little, it's the opposite: someone gets a list, panics about consistency, and starts sending filler weekly. Send when you've built something, learned something, or have something to give. The welcome email already did the hard part.

**Know when to graduate.** Past a few hundred people, or the moment deliverability starts mattering more to you than control, move to a real platform. Mailgun's free tier covers 100 emails a day, which is a while at first and not forever. That's a good problem, and by then you'll know exactly what you're buying and why.

## Deliverability — the part not to skip

Your mail is now coming from your own domain, which means your domain's reputation is yours to build or wreck.

- **Add the third record.** Kit 6 set SPF and DKIM. This kit adds DMARC, which tells the big providers what to do with mail that fails the other two. All three, or your welcome lands in spam and you'll never know.
- **Never import a list you didn't collect.** Not a conference list, not scraped addresses, not a purchased one. A single spam-complaint spike on a young domain can follow you for months, and there's no undo button.
- **Warm up gently.** A brand-new domain sending to five people is invisible and fine. A brand-new domain sending to five hundred at once looks exactly like what a spammer does. Grow into it.
- **Watch the bounces.** If an address bounces hard, stop sending to it. Repeatedly mailing dead addresses is one of the loudest bad-sender signals there is.
- **Honor unsubscribes instantly.** Not "within ten days." Instantly. It's one database write and it's the whole basis of the deal.

None of this is optional paperwork. It's the reason your email arrives at all.

## Cost, straight
Zero new dollars, same as Kit 8. Your domain, your Cloudflare, and your server are already paid for. Mailgun's free tier covers your first hundred emails a day and you're nowhere near that. SQLite is a file. The forms are free to use.

The only thing this costs is an evening, and you'll spend most of it deciding what your three lines actually say.

## Make it stick

The number I care about here isn't subscribers, it's whether the loop closes. Sit down at your phone, go to your live page like you've never seen it before, put in a real address you can check, and watch what happens. Did the welcome arrive? Does it sound like you? Does the unsubscribe link work when you click it?

Test the stranger's path, not yours. The one you built is the one you already know works.

You're done when: the form is live on your page, a real signup from your phone produced a row in your database, landed you on the thank-you page, and put a welcome email in your inbox, a copy of that signup landed in your own mail, the unsubscribe link flipped the status and showed you a page, and signing up twice with the same address didn't send two welcomes.

That's Kit 9. Your front door now has someone standing behind it. Everything after this, anything you ever give away, sell, launch or announce, goes to a list you own on a machine you control.

Next: something worth giving away, so the form has a reason to exist.

-- Cliff (connectwithcliff.com)
