Skip to content

Newsletter signup

Capture email subscribers from your storefront. Signup is double opt-in: your storefront submits the email, the platform emails a confirmation link, and the subscriber becomes confirmed only after they click it. Examples reuse the api() helper.

Subscribe (public)

POST /api/v1/public/newsletter/subscribe — tenant header, no auth (it's a public capture, rate-limited per tenant).

await api("/public/newsletter/subscribe", {
  method: "POST",
  body: JSON.stringify({
    email: "dana@example.com",   // required, valid email — normalized to lowercase
    source: "footer",            // optional free-form capture-origin tag
  }),
});
// → { ok: true }

The response is always { ok: true } — it deliberately doesn't reveal whether that email was new, already pending, or already confirmed (so the endpoint can't be used to probe who's subscribed). A new email creates a pending subscriber and triggers the confirmation email; submitting an already-known email is an idempotent no-op (no duplicate, no second email mid-flight).

The double opt-in flow

  1. POST …/subscribe → subscriber stored pending, confirmation email sent.
  2. The email contains a confirm linkGET …/public/newsletter/confirm?token=…. The subscriber clicks it and becomes confirmed.
  3. Every email also carries a one-click unsubscribe linkGET …/public/newsletter/unsubscribe?token=….

The confirm and unsubscribe links are tokenized targets the platform emails — they're not endpoints your storefront builds or calls. Your integration is just the subscribe POST; the platform owns the confirmation + unsubscribe lifecycle (which is why those two routes aren't in the API reference).

Only confirmed subscribers are mailable, so a captured-but-unconfirmed email won't receive campaigns until the link is clicked.

Action destinations

The emailed confirm and unsubscribe links always validate the opaque token on litecommerce's server before changing subscriber state. Preview emails use the stable API preview domain, not a raw Vercel deployment URL.

After a valid action, litecommerce redirects only to a trusted destination:

ActionDestination order
ConfirmedpostActionRedirectUrl → storefront origin → neutral page
UnsubscribednewsletterUnsubscribeRedirectUrlpostActionRedirectUrl → storefront origin → neutral page
Link no longer activenewsletterInactiveRedirectUrl → neutral page

Configured destinations must be absolute http(s) URLs whose origin is the tenant's verified storefront domain, that tenant's hosted litecheckout origin, or an operator-approved host. Blank settings are normal: they fall through to the next documented destination. Invalid or untrusted settings are ignored rather than emitted as a browser redirect.