Loops
Loops is an email platform for SaaS and ecommerce. Datafly Signal sends your events to the Loops Send event API (POST /api/v1/events/send) to trigger Loops workflows, and keeps the contact’s name and subscription current.
Why route Loops through Datafly Signal
- Events come from your server, not the browser. They reach Loops even when a tracker blocker or a failed page unload would have dropped a client-side call.
- Delivery is queued and retried. Signal buffers to Kafka and retries on 429 or a transient failure rather than dropping the event; a permanent rejection goes to the dead-letter queue with the vendor’s reason.
- One consent decision governs every destination. Loops is gated by the same consent state as the rest of your stack, so a withdrawal applies everywhere at once.
Get your Loops credentials
Create an API key
In Loops go to Settings > API and generate a key.
Create the events and their properties
Signal’s event names (under Presets) create events in Loops on first use. Add the event properties in Loops (Events page, or the workflow’s Event received node) so they are available in emails.
Configuration
| Field | Required | Description |
|---|---|---|
api_key | Yes | Your Loops team API key. Generate it in the Loops dashboard under Settings -> API. Never expose this key client-side. Sent as an Authorization: Bearer header. |
Management UI setup
- Go to Integrations in the sidebar and open the Integration Library tab.
- Find Loops under Marketing Automation and click Install.
- Choose a preset, enter the fields above and click Install Integration.
Management API setup
curl -X POST http://localhost:8084/v1/admin/integration-catalog/loops/install \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Loops",
"variant": "default",
"config": {
"api_key": "your_api_key"
},
"delivery_mode": "server_side"
}'What Signal sends
An example request, rendered from the default preset for purchase:
POST https://app.loops.so/api/v1/events/send
Idempotency-Key: 3f1c2a90-7d4e-4b8a-9c61-2f0e5d7a1b22
{
"email": "neill@example.com",
"eventName": "order_completed",
"eventProperties": {
"coupon": "AUTUMN10",
"currency": "GBP",
"item_count": 2,
"order_id": "ORD-1001",
"price": 129.99,
"product_id": "SKU-1",
"product_name": "Parka Jacket",
"revenue": 279.98,
"shipping": 4.99,
"tax": 46.66
},
"firstName": "Neill",
"lastName": "Mcfixture",
"userId": "crm-user-7"
}| Field | Source |
|---|---|
email, userId | The email from identify() traits (trimmed, lower-cased) and the signed-in user ID. Loops finds the contact by either and creates it if new. |
eventName | The event name shown under Presets. |
firstName, lastName, userGroup | Contact properties from traits, sent at the top level as Loops expects. |
subscribed | true on newsletter_subscribed, false on newsletter_unsubscribed; never set from cookie consent. |
eventProperties | The event’s properties as scalars: currency upper-cased, the first item and item_count on product and order events. |
Idempotency-Key header | The Signal event ID, so a retry never triggers a workflow twice (Loops answers 409 for a reused key). |
Loops delivers email to the address and accepts no hashed identifier, so it is sent in plain text. An event with neither an email nor a user ID is dropped.
Presets
| Preset | Signal event → vendor event |
|---|---|
| Default | sign_up → signed_up, login → logged_in, purchase → order_completed, generate_lead → lead_submitted, newsletter_subscribed, newsletter_unsubscribed |
| B2B / SaaS | sign_up → signed_up, login → logged_in, onboarding_completed, trial_started, trial_converted, trial_expired, subscription_started, subscription_cancelled, invitation_accepted |
| Retail | sign_up → signed_up, view_item → product_viewed, add_to_cart → product_added_to_cart, begin_checkout → checkout_started, purchase → order_completed, refund → order_refunded, newsletter_subscribed, newsletter_unsubscribed |
Events not listed are not sent. Each preset is a starting point: add, rename or remove mappings on the installed integration.
Notes and limits
- Page views are not sent: each event can trigger a workflow.
Consent
Marketing-automation integrations have no consent category by default. Assign the marketing category when you install Loops, so an event is delivered only when the visitor has granted it. Cookie-banner consent is not email or SMS opt-in: keep messaging opt-in in Loops.
Verify it’s working
- Open the integration in the Signal Management UI and watch Live Events while you trigger a mapped event.
- Confirm a 2xx response from Loops.
- Find the contact in Loops and check the event or record arrived.
Troubleshooting
| Symptom | Resolution |
|---|---|
400 | A property has a type Loops cannot convert. |
401 | The API key is wrong. |
409 | The same event was already delivered (idempotency key reused within 24 hours). |