Managing Signups
List, export, delete, and manage the people on your waitlist.
List Signups
View all signups for a waitlist with full data including phone numbers, UTM parameters, custom question answers, and referral information.
From the dashboard: Click View Details on any waitlist card to open the detail page with a searchable, sortable, filterable signups table.
API: GET /waitlists/{waitlist_id}/signups
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 50 | Results per page (1-100) |
last_key |
string | — | Pagination cursor from previous response |
Response:
{
"signups": [
{
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"phone": "+1234567890",
"position": 1,
"referral_token": "a3b2c1d4e5f67890a1b2c3d4e5f67890",
"referral_count": 5,
"referred_by": "b4c5d6e7f8a90123b4c5d6e7f8a90123",
"utm": {
"utm_source": "twitter",
"utm_medium": "social",
"utm_campaign": "launch",
"utm_term": "waitlist",
"utm_content": "cta-button"
},
"custom_answers": {
"q1": "Startup founder",
"q2": "Product Hunt"
},
"email_verified": true,
"email_opt_out": false,
"email_opt_out_at": null,
"device_type": "desktop",
"timezone": "America/New_York",
"created_at": "2025-03-15T10:30:00.000Z"
}
],
"count": 1,
"last_key": "eyJwYXJ0aXRpb..."
}
Response fields:
| Field | Type | Description |
|---|---|---|
email |
string | The signup’s email address |
first_name |
string | First name |
last_name |
string | Last name |
phone |
string | Phone number (only present if provided) |
position |
integer | Position in the waitlist |
referral_token |
string | Unique token for this signup’s referral link |
referred_by |
string | Referral token of the person who referred this signup |
referral_count |
integer | Number of people referred by this signup |
created_at |
string | ISO 8601 timestamp of when the signup was created |
utm |
object | UTM tracking parameters (only present if any were captured) |
utm.utm_source |
string | UTM source value |
utm.utm_medium |
string | UTM medium value |
utm.utm_campaign |
string | UTM campaign value |
utm.utm_term |
string | UTM term value |
utm.utm_content |
string | UTM content value |
custom_answers |
object | Answers to custom questions (only present if the waitlist has custom questions) |
email_verified |
boolean | Whether the signup has verified their email address |
email_opt_out |
boolean | Whether the signup has opted out of marketing emails |
email_opt_out_at |
string | ISO 8601 timestamp of when the signup opted out |
device_type |
string | Device type detected at signup (e.g., desktop, mobile, tablet) |
timezone |
string | IANA timezone of the signup (e.g., America/New_York) |
To paginate, pass the last_key value from the response as a query parameter in your next request.
Import from CSV
Import existing signups into your waitlist — useful for migrating from another tool or adding a pre-existing email list.
From the dashboard: Click the three-dot menu on any waitlist card and select Import CSV. Choose a .csv file, preview the import count, and confirm.
API: POST /waitlists/{waitlist_id}/import
Request Body:
{
"signups": [
{
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"phone": "+1234567890"
},
{
"email": "bob@example.com",
"first_name": "Bob"
}
]
}
| Field | Type | Required | Description |
|---|---|---|---|
email |
string | Yes | Email address — must be a valid format |
first_name |
string | No | First name |
last_name |
string | No | Last name |
phone |
string | No | Phone number |
Response (200):
{
"imported": 47,
"skipped": 3,
"errors": [
{ "row": 12, "email": "not-an-email", "error": "Invalid email" },
{ "row": 45, "email": "", "error": "Invalid email" }
]
}
The response includes three fields:
| Field | Type | Description |
|---|---|---|
imported |
integer | Number of signups successfully created |
skipped |
integer | Number of duplicate emails that were skipped |
errors |
array | Up to 50 error detail objects, each with row, email, and error |
Import behavior:
- Deduplication against existing signups: Each email is checked against the waitlist’s existing signups. Emails that already exist are skipped.
- Deduplication within the batch: If the same email appears multiple times in the import, only the first occurrence is imported. Subsequent duplicates are skipped.
- Batch processing: Valid signups are written to the database in batches of 25 for efficiency.
- Imported signups are assigned sequential positions starting from the current count.
- The signup counter is updated atomically after the import completes.
- Maximum 10,000 signups per import.
- The
errorsarray is capped at 50 entries.
CSV File Format
The CSV file should have column headers in the first row. The importer recognizes these columns (case-insensitive):
| Column | Required | Description |
|---|---|---|
email |
Yes | Email address — must be a valid format |
first_name or first name |
No | First name |
last_name or last name |
No | Last name |
phone |
No | Phone number |
notes |
No | Freeform notes about the signup |
Extra columns are ignored. The dashboard parses the CSV client-side and sends the data as JSON.
Email Opt-Outs
Signups can unsubscribe from marketing emails by clicking the unsubscribe link in any blast, referral notification, or milestone email. When a signup opts out:
- The
email_opt_outfield is set totrueandemail_opt_out_atrecords the timestamp - They are skipped in future email blasts, referral notifications, and milestone emails
- Their waitlist position and all other data are preserved — they’re only opting out of emails
- Opted-out signups appear in the signup list with an “Opted out” indicator
- The opt-out status is included in CSV exports
After unsubscribing, users also have the option to delete their data entirely via the unsubscribe page. This permanently removes their signup record and decrements the waitlist’s signup count.
Export to CSV
Download all signups as a CSV file. The export includes every field: email, name, phone, position, referral data, UTM parameters, custom question answers, email opt-out status (email_opt_out, email_opt_out_at), consent records (consent_given_at, consent_text_version, privacy_policy_version), email verification status, and creation date.
From the dashboard: Click Export CSV on any waitlist card, or use the Export CSV button on the waitlist detail page. A new browser tab opens with the download.
API: GET /waitlists/{waitlist_id}/export
The API supports authentication via query parameter (?token=YOUR_JWT) for browser download links. The response is a CSV file with Content-Type: text/csv and Content-Disposition: attachment headers.
Waitlist Statistics
Get aggregate stats for a waitlist, including referral signup counts for calculating viral rate.
API: GET /waitlists/{waitlist_id}/stats
{
"waitlist_id": "a1b2c3d4",
"total_signups": 1247,
"referral_signups": 312,
"created_at": "2025-03-01T00:00:00.000Z"
}
| Field | Description |
|---|---|
total_signups |
Total number of signups on the waitlist |
referral_signups |
Number of signups that came through a referral link |
Viral Rate can be calculated as: (referral_signups / total_signups) * 100
Delete a Signup
Remove a specific person from the waitlist by email.
API: DELETE /waitlists/{waitlist_id}/signups/{email}
Returns 204 No Content on success. Returns 404 Not Found if the signup does not exist.
Deleting a signup does not decrement the total signup count. This is intentional — position numbers for all remaining signups stay stable, so no one’s position shifts when someone is removed. The signup record is permanently deleted from the database.
Offboarding Emails (Pro)
When a signup is deleted and the waitlist owner has an offboarding email template configured, the system automatically sends the offboarding email to the deleted signup’s email address. This happens as a fire-and-forget operation — the delete returns 204 immediately and the email is sent in the background. This lets you notify people when they’re accepted off the waitlist or removed for any reason.
To use offboarding emails:
- Create an offboarding email template on the Email Templates page (Pro plan required).
- When you delete a signup, the system checks if the owner has an offboarding template and sends it automatically.
The template variables {{email}}, {{first_name}}, {{last_name}}, and {{waitlist_name}} are filled in automatically.
Move Signup Position (Advanced+)
Manually change a signup’s position in the waitlist. Use this to prioritize VIPs, influencers, or manually reward users.
API: PATCH /waitlists/{waitlist_id}/signups/{email}/position
The email is specified in the URL path (URL-encoded if necessary). The request body contains the new position:
{
"position": 1
}
| Field | Type | Required | Description |
|---|---|---|---|
position |
integer | Yes | The new position for this signup. Must be a positive integer. |
The signup’s position is updated directly to the specified value. Note that this does not automatically shift other signups — if two signups end up with the same position number, they will both appear at that position. To swap two signups, you would need to move each one individually.
Response:
{
"email": "jane@example.com",
"position": 1
}
Bulk Delete
Remove multiple signups at once — useful for cleaning up test data, removing spam, or processing batch deletion requests.
API: POST /waitlists/{waitlist_id}/signups/bulk-delete
{
"emails": [
"test1@example.com",
"test2@example.com",
"spam@bot.net"
]
}
| Field | Type | Required | Description |
|---|---|---|---|
emails |
array of strings | Yes | Email addresses to delete (maximum 100 per request) |
Response (200):
{
"deleted": 3
}
The deleted count reflects how many signup records were actually removed. Emails that don’t exist on the waitlist are silently skipped.
Bulk Move (Advanced+)
Reorder multiple signups at once — useful for manually prioritizing VIPs or reorganizing positions after an import.
API: POST /waitlists/{waitlist_id}/signups/bulk-move
{
"updates": [
{ "email": "vip@example.com", "position": 1 },
{ "email": "friend@example.com", "position": 2 }
]
}
| Field | Type | Required | Description |
|---|---|---|---|
updates |
array | Yes | Array of { email, position } objects (maximum 100 per request) |
updates[].email |
string | Yes | Email address of the signup to move |
updates[].position |
integer | Yes | New position (must be >= 1) |
Response (200):
{
"moved": 2
}
The moved count reflects how many signups were actually repositioned. Invalid entries (missing email, position < 1, or non-existent signups) are silently skipped.
Team Member Access
If you’re on the Pro plan with Team Management enabled, your team members can access your waitlists too. The system checks whether the authenticated user is:
- The direct owner of the waitlist, OR
- A team member of the owner
This applies to all admin operations: listing signups, exporting, deleting, and viewing stats.
Related
- Creating Waitlists — configure waitlist settings, fields, and custom questions
- Email Blasts — send bulk emails to everyone on your waitlist (Pro)
- Data Export — download all signups as a CSV file