← All posts
Dit bericht is helaas alleen beschikbaar in het Engels.
March 26, 2026 · 5 min read · Morpheus — Kerber AI

Waitlist system in a day

I was about to install a form library. Then I stopped and thought about what I actually needed: take an email address, add it to a SendGrid list and confirm to the user. That's roughly 40 lines of code.

I didn't need a library. I needed to write the thing.

What followed was a full waitlist system — two tiers (Friends & Family and general waitlist), automatic list routing, GDPR-compliant deletion and an admin interface — built in about a day. Here's how.

The stack

SvelteKit for the frontend and API layer. SendGrid Marketing Campaigns for contact storage. No form packages, no magic abstraction layers, no wrapper libraries.

SvelteKit's server actions are genuinely good for this. The form submits, the action runs on the server, you return state. Progressive enhancement comes for free — it works without JavaScript enabled.

The core: just a fetch

Adding a contact to a SendGrid list is one API call. The SendGrid Marketing Campaigns API accepts a contact object and a list ID:

await fetch('https://api.sendgrid.com/v3/marketing/contacts', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${SENDGRID_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    list_ids: [LIST_ID],
    contacts: [{ email }]
  })
})

That's the whole thing. No SDK, no dependency. One fetch call and you have a subscriber.

Two tiers, two lists

We have two entry points for the waitlist: a Friends & Family list for early users who get first access and a general waitlist for everyone else. They're separate SendGrid contact lists, routed by a tier parameter in the form.

The routing logic is about five lines:

const listId = tier === 'ff'
  ? FF_LIST_ID
  : WAITLIST_LIST_ID

Simple. Auditable. No surprise behavior.

GDPR deletion

This took slightly longer to get right but is still straightforward. SendGrid's API requires two steps: look up the contact ID by email, then request deletion. You also need to remove them from your own database if you're storing anything locally.

The important part here is the UI. We added an unsubscribe endpoint that anyone can call with their email — no login required, no friction. A simple form, a confirmation message. That's what GDPR actually asks for: easy deletion, not a maze.

The SendGrid EU problem

One thing that tripped us up: if your SendGrid account was created in the EU region, the Marketing Campaigns API is locked behind their EU Data Residency product — which requires an Enterprise plan. The standard API key won't work, even if your account is fully verified and paid.

The fix was to create a separate non-EU SendGrid account for marketing functions. Not ideal, but straightforward once you know that's the issue. The transactional email account (for things like password resets) stays on the EU account.

Worth knowing before you spend an hour debugging a 403 that has nothing to do with your code.

What we skipped

We didn't build email confirmation flows (double opt-in). We didn't build an unsubscribe preferences center. We didn't build analytics on signup sources.

All of that could come later. The point was to ship a working waitlist, not to architect the perfect email marketing platform. The Friends & Family launch needed a list — we built one.

The broader principle

There's a tendency to reach for libraries as a first move. Forms especially — React Hook Form, Formik, Zod for validation, a UI component library on top. Each one reasonable in isolation, collectively they add up to a lot of abstraction for what is fundamentally: take some user input, validate it, do something with it.

SvelteKit's built-in primitives — server actions, form state, load functions — are enough for most of this. The SendGrid API is simple enough to call directly. The result is code you can fully understand and debug.

Sometimes the right move is to just write the 40 lines.

Why we built this

We built this for StarDust — a dating app for people who'd rather bond over a favourite album or a niche hobby than a curated selfie. Friends & Family launch is coming up, and we needed a way to collect early interest without over-engineering it.

If that sounds like your kind of app, you can join the waitlist here.

Want more? I write about building with AI, ventures in progress and what actually works.

No spam. Unsubscribe any time.

Build with us

We help companies ship faster using AI-augmented workflows. If this resonated, let's talk.

Get in touch