Developers
API reference
Integrate GetWaitly signups into your own forms. Works with any stack — no SDK required.
Management API (API keys)
Read your waitlists and subscribers, and add signups, with a personal API key. Create one in Account settings → API keys and send it as a bearer token on every request:
Authorization: Bearer gw_live_…Base URL: https://getwaitly.com/api/v1.
| Method | Path | Description |
|---|---|---|
| GET | /account | Your account and plan. |
| GET | /waitlists | List your waitlists. |
| GET | /waitlists/{key} | One waitlist and its counts. |
| GET | /waitlists/{key}/subscribers | List subscribers (limit, offset, status). |
| POST | /waitlists/{key}/subscribers | Add a subscriber (email required). |
| GET | /hooks | List your REST Hook subscriptions. |
| POST | /hooks | Subscribe a URL to an event (waitlist, event, url). |
| DELETE | /hooks?id= | Unsubscribe a hook. |
| GET | /hooks/sample?event= | A sample payload for field mapping. |
REST Hook subscriptions (/hooks) require the Pro plan. The rest of the management API is available on every plan, including Free.
Keys are shown once at creation, stored hashed, and can be revoked anytime. Requests only ever return your own data.
Endpoint
POST https://getwaitly.com/api/joinPOST https://getwaitly.com/api/join/{slug}The first accepts a JSON body. The second is a form actionendpoint: point a native HTML form at it and the browser redirects to the waitlist's thank-you page — no JavaScript required. It also accepts JSON when you send Accept: application/json.
Request body
Send a JSON body with Content-Type: application/json.
| Field | Type | Required |
|---|---|---|
| string | required | |
| slug | string | required |
| name | string | optional |
| phone | string | optional |
| customFields | Record<string, string> | optional |
| ref | string | optional |
| source | string | optional |
| fingerprint | string | optional |
| utmSource | string | optional |
| utmMedium | string | optional |
| utmCampaign | string | optional |
| utmContent | string | optional |
| utmTerm | string | optional |
| referrer | string | optional |
Form action (no JavaScript)
Point your own form at POST /api/join/{slug} with the browser's default application/x-www-form-urlencoded encoding. Field names are email (required), name (or firstName/lastName), phone, ref, and any custom question answers as cf_0, cf_1, … in the same order as your Widget Builder.
- Success— the visitor is redirected (303) to the waitlist's thank-you page, or the confirmation notice when double opt-in is on.
- Error — the visitor is redirected (303) back to the page the form was on, with
?gw_error=…appended. - Allowed origins — if your waitlist has a domain allowlist, add the site hosting the form.
- CAPTCHA— Cloudflare Turnstile requires JavaScript, so a captcha-enabled waitlist can't use a native form action. Disable captcha or use the widget script instead.
Responses
All responses return HTTP 200. Use the success and type fields to determine the outcome.
Confirmed
Signup succeeded. Use the returned position and referral link on your thank-you page.
{
"success": true,
"type": "confirmed",
"position": 42,
"referralCode": "abc123defg",
"referralLink": "https://getwaitly.com/ref/abc123defg",
"unsubscribeToken": "550e8400-..."
}Pending confirmation
Email verification required. The visitor must click the link we email them before they count as confirmed.
{
"success": true,
"type": "pending_confirmation",
"email": "visitor@example.com"
}Blocked
The signup was accepted but fraud rules flagged it. Prevented from counting toward referrals or the public waitlist total.
{
"success": true,
"type": "confirmed",
"position": 1,
"referralCode": "",
"referralLink": null,
"unsubscribeToken": ""
}Error
The signup was rejected. Check the error message for the reason.
{
"success": false,
"error": "You're already on this waitlist."
}Common error messages
Invalid email address.Waitlist not found.This waitlist is paused.You're already on this waitlist.This waitlist is currently full.Too many signups from this location. Please try again later.Please use a valid email address.(disposable email)
Listing subscribers
GET /waitlists/{key}/subscribers returns a page of subscribers (limit, offset, status). Each subscriber includes an answers object — the responses to your custom questions, keyed by the question label.
Subscribers
answers is keyed by question label; it only contains the questions the visitor answered.
{
"subscribers": [
{
"id": "a1b2c3d4-...",
"email": "visitor@example.com",
"name": "Ada Lovelace",
"points": 0,
"referrals": 0,
"source": "landing-page",
"status": "confirmed",
"confirmedAt": "2026-10-01T12:00:00.000Z",
"createdAt": "2026-10-01T12:00:00.000Z",
"answers": {
"What's your role?": "Founder",
"How did you hear about us?": "Reddit"
}
}
],
"pagination": { "limit": 50, "offset": 0, "total": 128 }
}Examples
curl -X POST https://getwaitly.com/api/join \
-H "Content-Type: application/json" \
-d '{
"email": "visitor@example.com",
"slug": "my-product",
"name": "Alex",
"source": "landing-page"
}'const res = await fetch("https://getwaitly.com/api/join", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: "visitor@example.com",
slug: "my-product",
name: "Alex",
source: "landing-page",
ref: referralCode,
referrer: document.referrer,
utmSource: params.get("utm_source"),
utmMedium: params.get("utm_medium"),
}),
});
const data = await res.json();
if (data.success) {
window.location.href = `/thank-you?token=${data.unsubscribeToken}`;
}<!-- Point your own form at the waitlist's form action URL.
No JavaScript needed — the browser redirects to your thank-you page. -->
<form action="https://getwaitly.com/api/join/my-product" method="post">
<input type="email" name="email" required placeholder="Your email" />
<input type="text" name="name" placeholder="Full name (optional)" />
<input type="text" name="phone" placeholder="Phone (optional)" />
<button type="submit">Join the waitlist</button>
</form>Rate limits
3 signups per IP address per waitlist per 24 hours. Beyond that, signups return the error Too many signups from this location. The IP is determined from the CF-Connecting-IP header (Cloudflare).
The management API is limited to 100 requests per minute per API key. Responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset; over-limit requests return 429 with a Retry-After header.
Referral tracking
Pass a refparameter with a subscriber's 10-character referral code. The new signup is attributed to that subscriber and they earn 10 points. Referral attribution is only enabled on paid plans (Starter and above).
You can get a subscriber's referral code from the thank-you page response (referralCode field) or from the status page. The referral link format is https://getwaitly.com/ref/{code} — visitors who click it get a cookie that carries the ref value automatically.