Mailing Lists

Mailing Lists

Reference for the mailing list integrations used across the network’s public-facing sites.


Strategy

SIA uses Mailjet to manage email communications across three separate accounts, each serving a distinct area of the organisation’s work. Keeping them separate means audiences never overlap, unsubscribes are scoped, and credentials are isolated.

Accounts

Communications is the public-facing account. It hosts the Spark newsletter — the main channel for reaching supporters and interested communities — and the Impact Blueprint list for participants of that campaign. For each subscriber it stores their name, country, how they found SIA, and which campaign or source brought them in.

Program supports the program application and management flow. It hosts the Program Start list, which contacts are added to as they move through the program. It records their name, location, and program-specific details, and links each subscriber to their Airtable record.

Network is for team members across the SIA network. It hosts a single internal list and records each contact’s name, organisation, country, community role, and whether they are currently active.

Lists

List Account Purpose
Spark Communications Newsletter targeting youth, sharing inspiring stories, knowledge, and opportunities from the global SIA community
Impact Blueprint Communications Impact Blueprint campaign participants
Program Start Program Opt-in list for people who want to be reminded when applications open
Weave Program Newsletter for the international alumni community, featuring highlights, partner opportunities, and resources
SIA Austria Program Program participants in Austria
SIA Germany Program Program participants in Germany
Network Network Active team members across the SIA network

Subscription forms

Three blocks are available to editors for placing subscription forms on pages:

Mailing List Subscription CTA — a dedicated newsletter signup block. Can show a single list or offer cross-subscription checkboxes for multiple lists. Used for the Spark newsletter in the site footer and for standalone page-level calls to action.

CTA — a general call-to-action block with an optional lead generator field. When the block’s display condition is not met — for example, when a visitor is not yet logged in — the lead generator activates and shows a Spark newsletter signup form in place of the main content.

Mailjet Embedded Form — a form hosted and rendered directly by Mailjet. No website processing is involved; submissions go straight to Mailjet.


Architecture

Audiences and lists

A Mailjet audience is a separate Mailjet account with its own API credentials. Each list belongs to exactly one audience; subscriptions to that list are authenticated with the corresponding credential pair.

Audience Credential constants Lists
spark SIA_MAILJET_SPARK_KEY / _SECRET spark, impact-blueprint
program SIA_MAILJET_PROGRAM_KEY / _SECRET program-start
network SIA_MAILJET_NETWORK_KEY / _SECRET network

Credential constants are defined in sia-ariel/includes/constants.php.

List slugs are the string identifiers used in WordPress. Each maps to a Mailjet numeric list ID:

Slug Mailjet list ID Audience
spark 444033 spark
impact-blueprint 10583967 spark
program-start 10619035 program
sia-austria 10524851 program
sia-germany 10524852 program
weave 10555947 program
network 10523871 network

Slugs, list IDs, and audience assignments are defined centrally in SIA_Ariel_Mailjet (sia-ariel/includes/class-sia-ariel-mailjet.php).

Contact properties

Each audience has its own set of contact properties defined in Mailjet. These are sourced from the Mailjet API and kept in sync via wp ariel check-mailjet-fields.

Communications (spark)

Field Type
first str
last str
country str
referral str
campaign str
confirm datetime
source str

Program (program)

Field Type
firstname str
lastname str
location str
category str
open_time datetime
last_changed datetime
cohort str
growactivity int
edition str
airtable_uuid str

Network (network)

Field Type
first_name str
last_name str
airtable_uuid str
country str
community_role str
active bool
organization str

API

Base URL: https://api.mailjet.com/v3/REST/

Authentication: HTTP Basic Auth. Credentials are Base64-encoded as key:secret and sent in the Authorization header. The correct pair is selected based on the target list’s audience.

Blocks

Mailing List Subscription CTA — block ID cta-mailing-list, handler CTAMailingList

Available on headquarter and microsite blogs. Renders an email input, an optional GDPR privacy checkbox, and optional cross-subscription checkboxes for each list. The network-wide footer newsletter (Spark only) is assembled in SIA_Publishing_Context::siteNewsletter() and uses this same handler.

The lead generator fallback path in the standard CTA block (CTA::switchToLeadGenerator()) also uses this handler’s AJAX flow, routing to the spark list.

Mailjet Embedded Form — block ID mailjet-embedded-form, handler MailjetEmbeddedForm

Renders a Mailjet-hosted signup form by form ID inside a container div. Submission is handled entirely by Mailjet; no WordPress AJAX is involved.

Subscription AJAX flow

  1. The frontend POSTs to admin-ajax.php with consumer: mailing_list_form, the user’s email address, and one or more list slugs.
  2. CTAMailingList::ajax_process_submission() validates the email format and checks each slug against SIA_Ariel_Mailjet::LIST_IDS.
  3. For each selected list, CTAMailingList::add_contact_to_list() delegates to SIA_Ariel_Remote_Abstract::subscribe_contact_to_mailjet_list().
  4. That method runs two sequential Mailjet API calls:

Step 1 — ensure the contact exists in the audience

POST https://api.mailjet.com/v3/REST/contact
Authorization: Basic <base64(key:secret)>
Content-Type: application/json

{
    "IsExcludedFromCampaigns": false,
    "Email": "user@example.com"
}
Response Meaning Action
201 Contact created Continue to step 2
400, ErrorMessage contains "MJ18" Contact already exists Continue to step 2
400, any other message API error Abort, return error for this list

Step 2 — add the contact to the list

POST https://api.mailjet.com/v3/REST/listrecipient
Authorization: Basic <base64(key:secret)>
Content-Type: application/json

{
    "ContactAlt": "user@example.com",
    "ListId": 444033
}
Response Meaning Action
201 Subscribed Add to newSubscribers
400, "duplicate ListRecipient" in error Already on this list Count as duplicate
400, any other message API error Count as failure

Result aggregation

After all selected lists are processed, ajax_process_submission() returns a single JSON response:

Outcome Response
All new subscriptions { success: true, newSubscribers: { spark: { listName: '…' } } }
All duplicates { success: false, message: "You're already subscribed. Thanks!" }
Mix of new and duplicates { success: true, newSubscribers: … } (duplicates silently ignored)
Any failure { success: false, message: <last failure message> }

Frontend validation errors (before the AJAX call is made):

Condition Message
Missing email “Please fill in your email address”
Invalid email format “Please use a valid email address”
No list selected “Seems you have not selected any list to subscribe to”
Unrecognised list slug “There was an issue finding our list”

Mailchimp (deprecated)

When a CTA block has type: newsletter and a subscribe_url configured, CTA::populate_newsletter() renders a plain HTML <form> pointing directly to a Mailchimp-hosted action URL. Submission goes to Mailchimp with no WordPress involvement.

The subscribe URL is assembled from three environment variables defined as constants in sia-publishing/includes/constants.php: SIA_MAILCHIMP_BASE_URL, SIA_MAILCHIMP_SPARK_AUDIENCE_ID, and SIA_MAILCHIMP_SPARK_LIST_ID. The result is used as the form’s action.

The lead generator fallback (CTA::switchToLeadGenerator()) previously triggered this path. It now routes to the Mailjet AJAX flow instead, making this path unreachable from any currently active block configuration.

Key files

File Purpose
web/app/plugins/sia-ariel/includes/class-sia-ariel-mailjet.php Single source of truth for list IDs, audience assignments, and contact properties (SIA_Ariel_Mailjet)
web/app/plugins/sia-ariel/includes/class-sia-ariel-remote-abstract.php subscribe_contact_to_mailjet_list(), subscribe_contact_to_mailjet_audience(), post_to_mailjet()
web/app/plugins/sia-ariel/includes/constants.php MAILJET_API_BASE_URL, credential constants
web/app/plugins/sia-publishing/includes/component-handlers/CTAMailingList.php AJAX handler, result aggregation; MAILING_LIST_IDS aliases SIA_Ariel_Mailjet::LIST_IDS
web/app/plugins/sia-publishing/includes/component-handlers/MailjetEmbeddedForm.php Embedded form block handler
web/app/plugins/sia-publishing/includes/component-handlers/CTA.php Standard CTA block; switchToLeadGenerator() routes to Mailjet spark; deprecated Mailchimp fallback path
web/app/plugins/sia-publishing/includes/class-sia-publishing-context.php siteNewsletter() — footer Spark subscription assembly
web/app/plugins/sia-publishing/includes/class-sia-publishing-blocks-repository.php Block registration for cta-mailing-list and mailjet-embedded-form
web/app/plugins/sia-publishing/includes/constants.php SIA_MAILCHIMP_BASE_URL, SIA_MAILCHIMP_SPARK_AUDIENCE_ID, SIA_MAILCHIMP_SPARK_LIST_ID