Skip to content

List entries

Page through one waitlist's entries — for rendering the queue in your own app or syncing it into your own systems. This is the read half of running a waitlist headless: capture with signup, react with webhooks, render with this.

GET /sdk/v1/waitlist/{waitlistId}/entries

  • Auth: Server key with the waitlist:read grant — Authorization: Bearer <key>. Product keys (ck_srv_waitlist_…) have it; scoped keys must select it at creation.
  • Order: oldest signup first, stable across pages.
  • Page size: 1–100 entries per request (default 50).

Query parameters

ParamTypeRequiredDescription
cursorstringNoThe nextCursor from the previous page. Omit for the first page.
limitnumberNoEntries per page, 1–100. Defaults to 50.
statusstringNoOnly entries in this state: waiting, invited, or joined.

The cursor is opaque — store it and pass it back, never parse it. It stays valid while you scan even if the queue renumbers underneath you: pages never skip or repeat an entry, though each entry's position is a snapshot taken when its page was read.

Response

FieldTypeDescription
entriesEntry[]One page of entries.
nextCursorstring | nullPass as ?cursor= for the next page; null on the last page.

Entry object

FieldTypeDescription
idstringThe entry's id.
waitlistIdstringThe waitlist's short id.
identifierKindstringWhich channel identifies this person: email or phone.
emailstringThe signup's email address. Empty when identifierKind is phone — read phone instead.
phonestringThe signup's phone number in E.164, when they have one. Empty otherwise.
metadataobjectThe string→string map submitted at signup — contact fields (name, company, …) and anything else you stored. {} when none.
positionnumberQueue position; meaningful while status is waiting.
referralsnumberSignups this person has referred.
referralCodestringThe short code in their share link (…?ref=<code>).
referredBystringThe referrer's own identifier — their email, or their number if that is what identifies them. Absent for direct signups.
statusstringwaiting, invited, or joined.
sourcestringwidget, landing_page, api, import, or manual.
signedUpAtstringISO 8601 timestamp.
invitedAtstringISO 8601 timestamp; absent until invited.
inviteCodestringThe live invite code (from the invite link / ); present once invited, absent while waiting.

Example

bash
curl "https://api.uselucerna.app/sdk/v1/waitlist/wl_launch/entries?limit=50&status=waiting" \
  -H "Authorization: Bearer $LUCERNA_SERVER_KEY"
ts
const base = "https://api.uselucerna.app/sdk/v1/waitlist/wl_launch/entries";
let cursor: string | null = null;

do {
  const url = new URL(base);
  if (cursor) url.searchParams.set("cursor", cursor);
  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.LUCERNA_SERVER_KEY}` },
  });
  if (!res.ok) {
    const error = await res.json();
    throw new Error(`${error.code}: ${error.message}`);
  }
  const page = await res.json();
  for (const entry of page.entries) {
    console.log(entry.position, entry.email, entry.status);
  }
  cursor = page.nextCursor;
} while (cursor);
json
{
  "entries": [
    {
      "id": "5f0c6a8e-…",
      "waitlistId": "wl_launch",
      "identifierKind": "email",
      "email": "ada@example.com",
      "phone": "",
      "metadata": { "name": "Ada Lovelace", "plan": "pro" },
      "position": 1,
      "referrals": 3,
      "referralCode": "481920",
      "status": "waiting",
      "source": "landing_page",
      "signedUpAt": "2026-07-01T09:30:00.000Z"
    }
  ],
  "nextCursor": "MTc1MTM2MjIwMDAwMC41ZjBjNmE4ZS…"
}

Errors

StatuscodeWhen
400invalid_requestMalformed cursor, limit, or status.
401unauthorizedMissing or invalid server key.
403forbiddenThe key was not granted waitlist:read.
404not_foundNo waitlist matches waitlistId.

See Errors for the response shape and retry guidance.

Lucerna Developer Docs