← Back to docs

Signup Forms & Double Opt-In

Create embeddable signup forms, turn on double opt-in for a list, and customise the embed.

Overview

A signup form is the public, embeddable front door to a contact list. Drop it on any website and visitors can subscribe. EuroMail sends the confirmation email, adds unsubscribe links and checks the suppression list for you. Every form belongs to exactly one list, and each list can have one form.

For the full endpoint reference, see the Signup Forms API reference.

Turn on double opt-in on the list

Double opt-in is a setting of the contact list, not of the form. Set double_opt_in when you create or update the list:

curl -X POST https://api.euromail.dev/v1/contact-lists \
  -H "Authorization: Bearer em_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Blog Newsletter",
    "double_opt_in": true
  }'

With it on, a new subscriber has to click a confirmation link before they become an active contact. Keep it on for marketing mail.

Create a form

Create the form with the list's id. The API key needs the contacts:manage scope:

curl -X POST https://api.euromail.dev/v1/signup-forms \
  -H "Authorization: Bearer em_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "list_id": "LIST_ID",
    "title": "Get the blog in your inbox",
    "description": "One email a month. Unsubscribe any time.",
    "redirect_url": "https://yoursite.com/thanks",
    "from_address": "[email protected]"
  }'
  • title (required) and description are shown on the form.
  • success_message is shown after a submission. redirect_url sends the visitor to your own page instead.
  • from_address sends the confirmation email. It must be on a verified domain. If you leave it out, EuroMail uses noreply@ on your first verified domain.
  • custom_fields, theme and messages add extra fields, set colours and replace the default wording (for example, to translate the form).

The response (201) is wrapped in data and includes the form's id, slug, the hosted form_url and a ready-made iframe embed_code. A second form for the same list returns 409.

Manage forms with GET /v1/signup-forms (list), GET, PUT and DELETE on /v1/signup-forms/{id}. PUT takes the same fields as create, except list_id.

Embedding the form

The hosted form lives at https://api.euromail.dev/subscribe/your-form-slug. Link to it, put the embed_code iframe on your page, or use the script embed, which renders the form straight into your page so your own CSS applies:

<div id="euromail-form"></div>
<script src="https://api.euromail.dev/subscribe/your-form-slug/embed.js" defer></script>

The script fills the #euromail-form element. Without one, it renders into the element that contains the script tag.

Styling the embed

Every element in the script embed has an em- class, so you can target it from your stylesheet: .em-form, .em-form__title, .em-form__description, .em-form__field, .em-form__label, .em-form__input, .em-form__button, .em-form__message and .em-form__powered.

#euromail-form .em-form__input { /* your styles */ }
#euromail-form .em-form__button { /* your styles */ }

The double opt-in flow

When the list has double_opt_in on, a subscription goes like this:

  1. Submit. The visitor enters their email in the form.
  2. Pending. EuroMail saves the contact with status pending and sends a confirmation email with a link (/confirm/{token}). The link expires after 24 hours.
  3. Confirm. The visitor clicks the link. The contact becomes active, and the time of the click is saved as the token's confirmed_at.
  4. Welcome. If the list has a welcome email configured, it goes out now.

The confirmed_at time shows when the address confirmed the subscription. That is all EuroMail stores about the consent: it does not keep the form wording, the visitor's IP address or a copy of what they agreed to. If you need a fuller consent record, keep it on your side as well. See GDPR Tooling.

If the sending domain has a verified tracking domain, the confirmation link uses it (e.g. https://news.yoursite.com/confirm/...), so the flow stays on your brand.

Unsubscribe handling

Every email sent to a list includes a one-click unsubscribe link (/unsubscribe/{token}) and the List-Unsubscribe headers mailbox providers expect. An unsubscribe updates the contact and adds the address to the suppression list, so it is left out of future sends.

Turning a form off and on

Disable a form without deleting it, for example to pause signups during a migration:

curl -X POST https://api.euromail.dev/v1/signup-forms/{form_id}/toggle \
  -H "Authorization: Bearer em_live_your_key_here"

Each call flips the form between active and inactive, and the response shows the new is_active value. While it is inactive, the hosted page and the embed stop working and new submissions are refused. Call it again to turn the form back on.

Checklist for a compliant signup

  • Turn on double_opt_in on any marketing list.
  • Link your privacy policy near the form.
  • Use a verified sending domain for the confirmation email so it lands in the inbox.
  • Let EuroMail handle unsubscribes. Never re-add someone who opted out.

Send your first email in about 90 seconds

The free tier includes 3,000 emails a month. Email storage and AI processing in Finland, with a DPA on every plan.

Create free account See live delivery data