A newsletter box for any Atlas site, with proof of consent

Atlas now has a newsletter module: one field for an email or a WhatsApp number, double opt in, a mandatory captcha, and a record of exactly what each person agreed to. It ships switched off, and this is what it does and what it does not do yet.

Every brand site eventually gets the same request: put a subscribe box in the footer. The box is the easy part. The hard part is everything behind it: stopping bots from using your form to mail strangers, knowing who agreed to what, and letting people leave in one click.

Atlas now has a newsletter module for that. It is live in Atlas API 0.1.56 and Atlas admin 0.1.41. It is off for every brand until an admin switches it on, so nothing changes for your site today.

What a visitor sees

One field. They type an email or a mobile number and press the button.

  1. An email address gets a confirmation mail. The person becomes a subscriber only when they click the link in it (double opt in). The link is valid for 72 hours.
  2. A WhatsApp number is stored with its consent and nothing is sent to it yet. Sending to WhatsApp belongs to the omnichannel module, not here.
  3. Every mail carries List-Unsubscribe headers, so mail clients can offer one click unsubscribe. The link opens a page with a single button, and only the button (a POST) changes anything. That way a link scanner cannot unsubscribe someone by accident.

What a bot sees

Subscribing sends a confirmation mail to whatever address was typed. That is exactly what abusers want, so the endpoint is stricter than a normal form:

  1. A signed one time challenge with a time trap and a small proof of work, which Atlas Shield already provides.
  2. A mandatory Cloudflare Turnstile token, or hCaptcha if a brand cannot use Cloudflare. A brand cannot switch the newsletter on until a captcha integration is saved and its key test passes.
  3. A honeypot field, and rate limits.
  4. If the captcha provider cannot be reached, the answer is a 503 and nothing is stored or mailed. It fails closed.

The answer also never reveals whether an address is already known. A new address, a known one and a blocked one all get the same 202.

What you call from your site

Your server posts to Atlas with the brand's read token. It never calls from the browser. First it asks for a challenge, then it subscribes:

{"contact": "0812 3456 7890", "locale": "id", "source": "footer",
 "tags": ["promo"], "consent_version": "footer-2026-11",
 "challenge": "<token>", "solution": 4711, "captcha_token": "<turnstile token>", "website": ""}
StatusMeaning
202Accepted. Email gets next: confirm_email, WhatsApp gets next: none
422A problem with the input, with a code such as contact_invalid or captcha_failed
429Too many attempts, with Retry-After
503The captcha could not be checked, so nothing was stored

Proof of consent

Each brand keeps its consent texts as versions, with a text per language and a policy link. A site sends only the version key it showed. Atlas stores a hash of that exact text next to every consent record, so you can later prove what wording a person saw even if you edit the text afterwards. The admin therefore makes "new version" the default action and warns you when you edit a version that already has consents.

Addresses are stored encrypted. Lookups use a keyed hash. Unsubscribed data is erased after 7 days, unconfirmed sign ups after 14 days and WhatsApp numbers after 30 days. Only the hash stays on a suppression list, so someone who left is not mailed again.

In the admin

There is a Newsletter area with the subscriber list, filters by status, source and channel, and a count per status. Editors see masked addresses. Publishers and admins see full ones, and only admins change settings, block a subscriber or erase one. Before you switch the module on, a checklist shows what is missing: captcha set up (Atlas tests the keys again when you turn it on), a consent text written and, recommended, your own email connection. Without that connection, confirmation mails go out through the Atlas default sender.

What it does not do yet

This is the first phase. Be clear about the limits:

  1. It collects and manages subscribers. It does not send campaigns yet. Composing and sending from Atlas content is the next phase.
  2. WhatsApp numbers are stored with consent, but nothing is sent to them.
  3. No lists or segments beyond tags.
  4. The consent flow follows the principles of Indonesian data protection law (UU PDP): a clear notice, a confirmation click, withdrawal at any time and erasure. We have not had a legal review of the exact wording, so check it with your own counsel before you rely on it.

What we checked, and what we did not

We ran the whole flow on a local Atlas: subscribing by email and by WhatsApp number from a real site footer, confirming, one click unsubscribe, and the captcha failing closed. The API and the admin are deployed to production, the migrations ran and the module is off. We have not run a real subscribe in production, because no brand has switched the module on yet.

Turning it on

  1. Save a Turnstile or hCaptcha integration for the brand.
  2. Add at least one consent text in the brand's newsletter settings.
  3. Switch the module on under Settings, then Modules.

The full API reference is in the newsletter docs.

//Keep reading

More from the blog

All posts →

//Run every brand from one place.

Start with one brand for free. Bring your team when you are ready.

$ npm install @atlas/client @atlas/nuxt

Free for one brandNo credit cardUpgrade anytime