Skip to main content

Add a waitlist from Python

Collect signups before launch and turn them into users afterwards. Each signup gets a referral code, invites go out in first-come order, and the whole list exports as CSV.

Keys

Browser calls use a publishable key (nv_pub_live_…), which is safe to ship. Reading and admin calls use a secret key (nv_live_…) on your server only. Create both under Dashboard → API keys.

Publishable key pasted into the page that embeds the form
NORDVA_SECRET_KEY=nv_live_…

01Server: Python

waitlist-signup.py

import os
import httpx

res = httpx.post(
    "https://api.nordva.dev/v1/waitlist/signups",
    headers={"Authorization": f"Bearer {os.environ['NORDVA_SECRET_KEY']}"},
    json={"email": email, "referrer_code": referrer_code},
)
if res.status_code >= 400:
    err = res.json()["error"]
    raise RuntimeError(f"{err['code']}: {err['message']}")
data = res.json()["data"]
print(data["position"], data["referral_link"])

Server-side signup uses the secret key. Pass the visitor's referral code through if your form URL carries ?ref=.

02Server: read stats, Python

waitlist-stats.py

import os
import httpx

res = httpx.get(
    "https://api.nordva.dev/v1/waitlist/stats",
    headers={"Authorization": f"Bearer {os.environ['NORDVA_SECRET_KEY']}"},
)
if res.status_code >= 400:
    err = res.json()["error"]
    raise RuntimeError(f"{err['code']}: {err['message']}")
data = res.json()["data"]
print(data["total_signups"], data["confirmed_count"], data["top_referrers"][:3])

03Zero-code alternative: hosted widget

any HTML page

<script src="https://cdn.nordva.dev/v1/waitlist.js"
  data-key="nv_pub_live_…"
  data-placeholder="[email protected]"
  data-button="Join waitlist"
  data-success="You're on the list"
  data-theme="auto"></script>
<nordva-waitlist></nordva-waitlist>

04Verify from a terminal

curl -s https://api.nordva.dev/v1/waitlist/stats \
  -H "Authorization: Bearer nv_live_…" | jq .data

Behaviour worth knowing

  • Every response is { data, error, meta }. On failure error.code is a stable string such as VALIDATION_ERROR, PLAN_LIMIT_REACHED or RATE_LIMITED, with a remediation message.
  • POST and PATCH requests accept an Idempotency-Key header; the same key with the same body returns the original response for 24 hours.
  • Rate limits per key: 30 requests a minute on Free, 120 on Indie, 500 on Builder. A 429 carries Retry-After.
  • Browser calls with a publishable key must come from an origin registered on the project, otherwise the API answers ORIGIN_NOT_ALLOWED.