Forms
Collect newsletter and waitlist signups with a hosted page, an iframe or your own HTML form, with double opt-in, a honeypot and Cloudflare Turnstile.
A signup form adds the people who submit it as contacts and subscribes them to lists. Stamp0 hosts the form page; you can link to it, embed it in an iframe, or post to it from your own HTML or JavaScript.
Create a form
curl https://api.stamp0.com/forms \
-H "Authorization: Bearer $STAMP0_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Newsletter",
"fields": [
{ "name": "email", "label": "Email", "type": "email", "required": true },
{ "name": "first_name", "label": "First name", "type": "text" },
{ "name": "role", "label": "Role", "type": "text" }
],
"list_ids": ["lst_…"],
"double_opt_in": true,
"success_message": "Check your inbox to confirm."
}'fields(up to 30) must include a requiredemailfield. A field'snameisemail,first_name,last_nameor a property key; itstypeisemail,text,number,checkboxordate.double_opt_inis on by default: new signups staypendingon the form's lists until they click the confirmation email. It needs at least one list and adefault_fromin the marketing settings.- After a signup the page shows
success_message, or redirects toredirect_url(https). PATCH /forms/:idwithstatus: "disabled"stops accepting signups.
The response carries hosted_url (the page), action_url (where submissions go) and embed snippets. Both URLs are https://api.stamp0.com/f/frm_….
Put it on your site
| Option | How |
|---|---|
| Link | Link to hosted_url |
| Iframe | Paste embed.iframe; it loads hosted_url?embed=1 |
| Your own HTML | Paste embed.html, a plain <form> that posts to action_url, and style it yourself |
| JavaScript | POST JSON to action_url from the browser (CORS is open); the response is { status, redirect_url, message } |
What a signup does
A submission creates the contact (source form) or finds the existing one, and subscribes it to list_ids: subscribed at once, or pending with a confirmation email when double opt-in is on. Confirming also clears an earlier global unsubscribe, because it is fresh consent.
Only the fields the form declares are read, coerced to the property's type. A form only fills values a contact does not have yet: it never overwrites stored names or properties, because anyone can submit anyone's address. New contacts count toward the plan's contact limit.
Spam protection
spam_protection has three settings:
honeypot(on by default): a hidden field bots fill in; such submissions are dropped silently. Keep it in your own HTML (embed.htmlincludes it).turnstile(off by default): requires a Cloudflare Turnstile check. It works on the hosted page and the iframe, which render the widget for you.max_per_ip_per_hour(default 20): signups from one IP address per hour.
The double opt-in email goes out through your SES like any other email and shows in your email log. It has no unsubscribe link: it is the request to subscribe.
Reference: Forms.
Events
Send custom contact events such as trial.started from your app to trigger sequences, resume waiting steps and filter segments, with idempotency keys.
Unsubscribe and compliance
RFC 8058 one-click List-Unsubscribe, a visible unsubscribe link, a preference center and your postal address in every marketing email, with opt-outs honored at once.