# Simple Signups > Simple Signups is a hosted signup backend for any website. You POST emails, > waitlist signups, and form submissions to one endpoint; we store them, block > abuse, and let you export the data. It is NOT a form builder — you bring your > own HTML or UI. This is a SaaS, not a library to install. **What it is / is not** - IS: a lightweight signup/form backend. One endpoint. Destination is a `campaignId` (starts with `pub_`). No customer-side backend or database. - IS FOR: newsletters, waitlists, early access, beta lists, contact and lead capture on static/JAMstack and AI-generated sites. - IS NOT: a form builder, CRM, or email marketing suite. We do not design forms or send marketing email (only the optional double opt-in confirmation). **Quickstart** 1. Create a campaign in the dashboard and copy its public id (`pub_...`). 2. Add each website domain you will embed on to the campaign allow-list. 3. Point an HTML form (or a `fetch` call) at the subscribe endpoint below. **Endpoint** - `POST https://simple-signups.com/api/subscribe` - Alias: `POST https://simple-signups.com/c/:publicCampaignId` (id from the path; body then only needs `email`). - Accepts `application/json` or `application/x-www-form-urlencoded`. **Fields** Do not invent fields. Only these are accepted: - `campaignId` (required) — your public campaign id, starts with `pub_`. - `email` (required) — the subscriber email address. - `firstName` (optional) — given name. - `lastName` (optional) — family name. - `tags` (optional) — array of short category slugs, or a comma/semicolon/pipe string (max 20). Re-subscribe merges (unions) tags. - `metadata` (optional) — object of string/number/boolean values (size-capped). - `redirect` (optional) — no-JS success URL; must be an allowed domain. - `hp` (optional) — honeypot; leave empty, filled requests are dropped. - `turnstileToken` (optional) — Cloudflare Turnstile token when bot checks are on. **Examples** HTML (no JavaScript): ```html
``` JavaScript (fetch): ```js await fetch('https://simple-signups.com/api/subscribe', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ campaignId: 'pub_your_campaign_id', email }), }); ``` curl: ```sh curl -X POST https://simple-signups.com/api/subscribe \ -H 'content-type: application/json' \ -d '{"campaignId":"pub_your_campaign_id","email":"jane@example.com"}' ``` **Error codes (stable enums)** - `VALIDATION_ERROR` (400) — missing/invalid fields or malformed body. - `EMAIL_UNDELIVERABLE` (400) — email domain has no usable MX records. - `DOMAIN_NOT_ALLOWED` (403) — origin/redirect not in the allow-list. - `BOT_CHECK_FAILED` (403) — Turnstile verification failed. - `CAMPAIGN_NOT_FOUND` (404) — unknown campaignId. - `PAYLOAD_TOO_LARGE` (413) — body exceeds the 4 KiB cap. - `RATE_LIMITED` (429) — per-IP or per-campaign limit; back off using `Retry-After`. - `TOKEN_INVALID` (410) — confirmation token expired or already used. - `INTERNAL` (500) — unexpected server error. **Anti-abuse (on by default)** - Domain allow-list checked via Origin/Referer. - Honeypot `hp` field; per-IP and per-campaign rate limits. - Optional Cloudflare Turnstile. - Email deliverability (MX) checks. - Optional double opt-in: subscribers stay `pending` until they confirm. ## Docs - [Quickstart & guides](https://simple-signups.com/docs/): Create a campaign, allow-list domains, and embed a form. - [API reference](https://simple-signups.com/docs/api/): Canonical request fields and stable error codes. - [OpenAPI spec](https://simple-signups.com/api/openapi.json): Machine-readable schema for tools and agents. ## Optional - [Privacy policy](https://simple-signups.com/privacy/): How subscriber data is handled. - [Terms of service](https://simple-signups.com/terms/): Terms for using the service.