A waitlist is the smallest possible product: a box for an email and a place to keep the emails. Here's how to ship one without a backend.
Collect the email
Use a publishable key (ck_pub_…, domain-locked, create-only) and POST
from the page:
await fetch('https://contactapi.dev/v1/contacts', {
method: 'POST',
headers: {
'Authorization': 'Bearer ck_pub_your_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, source: 'waitlist', ref: 'launch-tweet' }),
})
Attach whatever you want to segment on later, such as source, a
referral, or plan interest. It's all saved as-is.
Handle duplicates for free
Create upserts by email, so someone signing up twice updates their record rather than creating a second one. No dedupe logic on your side.
Work the list
When you're ready to invite people, page through with your secret key:
GET /v1/contacts?page=1&page_size=100
Export, invite, or pull the emails into your sender. That's a launch-ready waitlist.
Where ContactAPI fits
ContactAPI is an open-source REST API for saving and managing contacts. You POST an email plus any JSON fields, get simple CRUD back, and can reach the same data from an AI client over its MCP server. No CRM, no pipeline stages, no lock-in.