Mailgun
Mailgun is an email delivery and marketing platform. Datafly Signal delivers your first-party events to Mailgun server-side, upserting members of a Mailgun mailing list so your audience stays in sync with the contacts your site identifies — no browser pixel or client-side SDK required.
Signal targets Mailgun’s mailing-list member API. Each identifying event creates the member if it does not exist and updates it in place if it does (an upsert), refreshing the contact’s name, subscription status, and custom variables.
Prerequisites
- A Mailgun account with a verified sending domain.
- A Private API key (Mailgun dashboard, Settings > API Keys).
- An existing mailing list to sync into (e.g.
newsletter@mg.example.com). Create it under Sending > Mailing lists before configuring Signal — this integration manages members, not lists. - Your account region: US accounts use
https://api.mailgun.net, EU accounts usehttps://api.eu.mailgun.net. The API key only works against the region it was created in.
Configuration
Signal authenticates to Mailgun with HTTP Basic auth, using the username api and your Private API key as the password.
| Field | Required | Description |
|---|---|---|
| Private API Key | Yes | Your Mailgun Private API key. Sent as the Basic-auth password. |
| API Base URL | Yes | https://api.mailgun.net (US) or https://api.eu.mailgun.net (EU). Must match your key’s region. |
| Mailing List Address | Yes | The address of an existing Mailgun mailing list to sync contacts into. |
Configure in Signal
- In the Signal management UI, open Integrations and add Mailgun.
- Paste your Private API key, set the API Base URL for your region, and enter the Mailing List Address.
- Attach the integration to a pipeline and select the Default preset.
- Save and enable the integration.
API Endpoint
Signal sends an HTTP POST to the member endpoint for your list:
POST {base_url}/v3/lists/{list_address}/members
Authorization: Basic base64("api:<your-api-key>")
Content-Type: application/x-www-form-urlencodedFor a US account with list newsletter@mg.example.com:
POST https://api.mailgun.net/v3/lists/newsletter@mg.example.com/membersSignal always sends upsert=true, so repeat events update an existing member rather than returning a duplicate error.
Identity Signals
Mailgun matches members on the plaintext email address — it does not accept hashed emails. Signal maps the visitor’s email ($traits.email, lowercased and trimmed) to the required address field. The contact’s name maps to name, and Signal’s anonymous_id is stored under the member’s custom variables (vars) so you can reconcile members against your first-party stream.
Events with no email cannot be delivered (the member API requires address); anonymous pageviews are dropped.
Event Mapping
The Mailgun member API is a contact-upsert surface — it has no event-name concept. Every identifying event refreshes the same member record. The Default preset maps:
| Signal event | Effect on the Mailgun member |
|---|---|
page | Updates vars.last_page_url (only when an email is present) |
Signed Up | Sets vars.signup_method |
Identified | Updates vars.company, vars.plan, name, and subscription status |
Order Completed | Updates vars.last_order_id, vars.last_order_revenue, vars.last_order_currency |
Marketing consent (context.consent.canonical.marketing) maps to the member’s subscribed flag.
Example
A Datafly.js call that identifies a user:
datafly.identify("user-123", {
email: "Jane@Example.com",
name: "Jane Doe",
first_name: "Jane",
last_name: "Doe",
plan: "pro",
company: "Acme Ltd"
});produces this request to Mailgun (form-encoded; shown decoded for readability):
POST https://api.mailgun.net/v3/lists/newsletter@mg.example.com/members
address=jane@example.com
name=Jane Doe
subscribed=true
upsert=true
vars={"first_name":"Jane","last_name":"Doe","plan":"pro","company":"Acme Ltd","anonymous_id":"a1b2c3"}Testing
- Send a test
Identifiedevent from a page running Datafly.js (or via the Signal Event Debugger). - In the Mailgun dashboard, open Sending > Mailing lists, select your list, and confirm the member appears with the expected name and custom variables.
- Send a second event with a changed trait (e.g. a new
plan) and confirm the member is updated in place rather than duplicated.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
401 Unauthorized | Wrong key, wrong username, or wrong region | Confirm the key is the Private key, the Base URL matches the key’s region (US vs EU). |
404 Not Found | List does not exist, or wrong Base URL | Create the mailing list in Mailgun first; verify the Mailing List Address and region host. |
400 Bad Request | Missing or malformed email | Ensure events carry $traits.email; anonymous events have no address to upsert. |
| Member never updates | Email differs by case/whitespace | Signal lowercases and trims the address; confirm the source email is consistent. |
| Events not delivered | Anonymous traffic | Only identified events (with an email) reach Mailgun; pageviews without an email are dropped. |