Spin up your first waitlist.
Two calls: create it, then activate it. Everything else is optional.
1
Create the waitlist
curl https://api.waitlist.productcraft.co/v1/workspaces/<workspace_id>/waitlists \
-H 'authorization: Bearer pcft_live_...' \
-H 'content-type: application/json' \
-H 'Idempotency-Key: launch-2026-01' \
-d '{
"slug": "acme-pro",
"display_name": "Acme Pro early access",
"description": "Sign up to be among the first to try Acme Pro."
}'{
"id": "8fe8b761-5cb1-4506-b7fe-c848aad8c8fa",
"workspace_id": "24fab978-7cd7-48ae-bce1-aba876b11957",
"workspace_slug": "acme",
"slug": "acme-pro",
"display_name": "Acme Pro early access",
"description": "Sign up to be among the first to try Acme Pro.",
"status": "draft",
"settings": {},
"created_by": "5864d0d5-a52d-4102-90ac-7018c47c2a64",
"created_at": "2026-07-28T20:08:53.627Z",
"updated_at": "2026-07-28T20:08:53.627Z"
}Only slug and display_name are required. The waitlist is created in draft — the public endpoints 404 until you activate it (step 2).
slug plus your workspace slug form the public key pair used by the anonymous endpoints: /v1/waitlists/<workspace_slug>/<slug>. Slugs must be unique inside the workspace — a collision returns 409.
Send an Idempotency-Key: creation provisions a sub-tree (default variant, referral settings), so a blind retry without the header creates a second waitlist. 24h TTL.
2
Activate it
curl -X PATCH https://api.waitlist.productcraft.co/v1/workspaces/<workspace_id>/waitlists/<id>/status \
-H 'authorization: Bearer pcft_live_...' \
-H 'content-type: application/json' \
-d '{ "status": "active" }'That is the whole setup. The waitlist now accepts public submissions — see chapter 3 for the form side.
3
The status lifecycle
Allowed transitions (anything else returns 422 Invalid status transition):
draft→active|closedactive→paused|closedpaused→active|closedclosed→ nothing. Terminal. Close only when the launch is genuinely over; you cannot re-open.
While a waitlist is anything other than active, the public info endpoint returns 404 (a draft list is indistinguishable from a missing one to anonymous probes) and submissions return 422 Waitlist is not accepting entries. Existing entries are untouched and stay readable, exportable and approvable through the admin lane.
4
Branding + notification defaults
Branding, the linked Auth app, and notification wiring are configured once per workspace — not per waitlist — at /v1/workspaces/:workspace_id/waitlist/settings (GET to read, PUT to update; every field is optional and only the keys you send change).
curl -X PUT https://api.waitlist.productcraft.co/v1/workspaces/<workspace_id>/waitlist/settings \
-H 'authorization: Bearer pcft_live_...' \
-H 'content-type: application/json' \
-d '{
"brand_name": "Acme",
"brand_logo_url": "https://cdn.acme.com/logo.png",
"primary_color": "#1E40AF",
"default_heimdall_app_slug": "acme"
}'brand_name, brand_logo_url and primary_color are echoed back in the public waitlist payload under brand so your own signup page can render them without a second lookup — Waitlist does not host a page for you.
default_heimdall_app_slug is the Auth consumer app approved entries get invited into. See chapter 4.
5
Notification emails
Waitlist sends no email by default. To turn notifications on, set notifications_via_envoi: true in the same settings call — which requires a verified Mail sender:
default_sender_domain_id— a verified Mail domain UUID.default_sender_address— the From address; it must belong to that domain.welcome_template_name/approved_template_name/rejected_template_name— Mail templates that already exist in the workspace template store, fired onentry.created/entry.approved/entry.rejected.
Leaving notifications off is a legitimate choice: subscribe to the same events over webhooks (chapter 6) and send mail yourself.
6
Delete
curl -X DELETE https://api.waitlist.productcraft.co/v1/workspaces/<workspace_id>/waitlists/<id> \
-H 'authorization: Bearer pcft_live_...'
# 204 No Content — cascades to every entry. Export first.