Loops

Loops is a marketing-automation and transactional-email platform for SaaS and e-commerce teams. Datafly Signal delivers your first-party events to the Loops Send Event API server-to-server, so a single behavioural event can identify a contact, update their properties, and trigger a Loops workflow — without loading Loops’ client-side code in the browser.

Prerequisites

  • A Loops account with at least one event-triggered workflow or loop (or you can let Loops auto-create the event on first use).
  • A Loops API key. Generate one in the Loops dashboard under Settings → API. Use a dedicated key for Signal so you can revoke it independently.
  • Contacts are matched by email (or user ID), so your Signal events must carry an identified email or user ID. Anonymous-only events cannot be delivered to Loops.

Configuration

FieldRequiredDescription
API KeyYesYour Loops team API key from Settings → API. Sent as an Authorization: Bearer header. Never expose this key client-side.

Configure in Signal

  1. In the Signal management UI, open Integrations → Add integration and choose Loops.
  2. Paste your API Key.
  3. Select the Default preset. It maps the standard funnel — page views, sign-ups, logins, and the e-commerce conversion events — to Loops events, and routes contact fields and marketing consent to the contact record.
  4. Review the event mappings. Loops event names are free text and are created automatically on first use, so make sure the eventName values in your blueprint match the trigger names configured in your Loops loops/workflows.
  5. Save and enable the pipeline.

API Endpoint

POST https://app.loops.so/api/v1/events/send
Authorization: Bearer <API_KEY>
Content-Type: application/json

A successful request returns HTTP 200 with { "success": true }. Validation failures return 400 with { "success": false, "message": "..." }. The API is rate-limited to 10 requests per second per team; Signal automatically throttles delivery and retries 429 responses with exponential backoff.

Identity Signals

Loops resolves each event to a contact using plaintext identifiers — there is no hashed-identity surface:

Signal fieldLoops fieldNotes
email (trait)emailPrimary contact identifier. Required unless userId is present.
user_iduserIdAlternative identifier. Either email or userId must be present.

The contact is created automatically if it does not already exist. Standard contact properties — firstName, lastName, and userGroup — are updated from the same event when present.

Marketing consent maps to the Loops subscribed contact flag. When context.consent.canonical.marketing is true, Signal sets contactProperties.subscribed = true. When consent is absent or denied, Signal omits the field so an existing contact is never silently unsubscribed by a missing signal — manage suppression in Loops itself.

Event Mapping

Signal sends GA4-style snake_case event names. Event-specific data is nested under eventProperties (used for email personalisation), and contact fields are nested under contactProperties (saved onto the contact).

Signal eventLoops eventName
pagepage_view
Signed Upsigned_up
Logged Inlogged_in
Product Viewedproduct_viewed
Product Addedproduct_added_to_cart
Checkout Startedcheckout_started
Order Completedorder_completed

Example

A Datafly.js call:

datafly.track("Order Completed", {
  order_id: "ORD-1042",
  revenue: 89.97,
  currency: "GBP",
  tax: 14.99,
  shipping: 4.99,
  coupon: "WELCOME10",
});
 
datafly.identify("user_8821", {
  email: "sam@example.com",
  first_name: "Sam",
});

produces this request to Loops:

{
  "email": "sam@example.com",
  "userId": "user_8821",
  "eventName": "order_completed",
  "contactProperties": {
    "firstName": "Sam"
  },
  "eventProperties": {
    "order_id": "ORD-1042",
    "revenue": 89.97,
    "currency": "GBP",
    "tax": 14.99,
    "shipping": 4.99,
    "coupon": "WELCOME10"
  }
}

The order_completed event triggers any Loops workflow listening for it, and eventProperties such as revenue and order_id are available as merge fields in the workflow’s emails.

Testing

  1. Trigger an identified event (for example, complete a test purchase) on your site.
  2. In Signal, open the Event Debugger and confirm the event delivered to Loops with HTTP 200 and { "success": true }.
  3. In the Loops dashboard, open the contact (by email) and confirm the event appears in their activity timeline and that any mapped contact properties were updated.
  4. If you wired the event to a workflow, confirm the workflow entered and the email rendered the expected eventProperties merge fields.

Troubleshooting

SymptomLikely causeFix
400 { "success": false }Missing email and userId, or missing eventName.Ensure the event carries an identified email or user ID and that the blueprint sets eventName.
401 / 403Invalid or revoked API key.Regenerate the key in Settings → API and update the integration.
409 ConflictAn idempotency key was reused within 24 hours.Expected for genuine duplicates; Signal treats it as a permanent (non-retried) outcome.
429 Too Many RequestsExceeded 10 requests/second per team.Signal retries automatically with backoff; if sustained, reduce event volume or contact Loops about your limit.
Workflow doesn’t triggereventName doesn’t match the trigger configured in Loops.Align the blueprint’s eventName with the exact name used in your Loops workflow.
Properties missing in emailData sent as a contact property instead of an event property (or vice versa).Event-template merge fields read from eventProperties; contact fields read from contactProperties. Check the mapping target prefix.