Capture signups
Add one or more signups to a waitlist. Use this from your backend to funnel signups from your own landing page, product, or import job into Lucerna.
POST /sdk/v1/waitlist/signup
- Auth: Server key —
Authorization: Bearer <key> - Batch size: 1–100 entries per request
- Duplicates: emails already on the waitlist are skipped, never duplicated
Request body
| Field | Type | Required | Description |
|---|---|---|---|
waitlistId | string | Yes | The waitlist's short id (1–64 chars), e.g. wl_launch. |
entries | Entry[] | Yes | 1–100 signups to create. |
Entry object
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The signup's email address. |
metadata | object | No | Free-form string→string map stored on the entry for later segmentation. Values are trimmed. Defaults to {}. |
source | string | No | Where the signup came from. Recognized values: widget, landing_page, api, import, manual. Any other value is stored under metadata.source and the entry is recorded as api. Defaults to api. |
referredBy | string | No | The referrer's email or referral identifier (≤320 chars), for referral attribution. |
Response
Returns the counts of what happened. created + skipped always equals the number of entries you submitted.
| Field | Type | Description |
|---|---|---|
success | true | Always true on a 2xx. |
created | number | Entries newly added to the waitlist. |
skipped | number | Entries whose email was already present. |
201 Created— at least one entry was created.200 OK— every submitted email was already on the waitlist.
json
{ "success": true, "created": 2, "skipped": 1 }Example
bash
curl -X POST https://api.uselucerna.app/sdk/v1/waitlist/signup \
-H "Authorization: Bearer $LUCERNA_SERVER_KEY" \
-H "Content-Type: application/json" \
-d '{
"waitlistId": "wl_launch",
"entries": [
{
"email": "ada@example.com",
"metadata": { "plan": "pro", "utm_source": "producthunt" },
"referredBy": "grace@example.com"
}
]
}'ts
const res = await fetch("https://api.uselucerna.app/sdk/v1/waitlist/signup", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LUCERNA_SERVER_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
waitlistId: "wl_launch",
entries: [
{
email: "ada@example.com",
metadata: { plan: "pro", utm_source: "producthunt" },
referredBy: "grace@example.com",
},
],
}),
});
if (!res.ok) {
const error = await res.json();
throw new Error(`${error.code}: ${error.message}`);
}
const { created, skipped } = await res.json();Errors
| Status | code | When |
|---|---|---|
400 | invalid_request | Missing/invalid field, empty entries, or more than 100 entries. |
401 | unauthorized | Missing or invalid server key. |
403 | forbidden | The waitlist is closed or rejects an email by policy. |
404 | not_found | No waitlist matches waitlistId. |
See Errors for the response shape and retry guidance.