Skip to Content
TutorialsSend a Transactional Email

Send a Transactional Email

This tutorial walks through the full lifecycle of a transactional email: declaring the event type, creating the template, binding them together, and testing delivery.

Step 1: Declare the Event Type

First, declare the event that will trigger the email. This registers the schema and enables template binding.

Tool: events.declare

{ "tool": "events.declare", "input": { "name": "lead.captured.v1", "brand_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "payload_schema": { "email": { "type": "string", "format": "email" }, "source": { "type": "string", "enum": ["vsl_form", "quiz_completion", "inbound_lead", "other"] }, "attribution": { "type": "object" }, "personId": { "type": ["string", "null"], "format": "uuid" } }, "description": "Fired when a new lead is captured from any source" } }

Response:

{ "name": "lead.captured.v1", "status": "active", "createdAt": "2026-05-19T14:00:00Z" }

Step 2: Create the Email Template

Create the email template that will be sent when the event fires. Use Handlebars syntax for dynamic fields.

Tool: templates.create

{ "tool": "templates.create", "input": { "name": "Lead Welcome Email", "channel": "email", "brand_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "subject": "Welcome to Loop Health!", "body": "<h1>Welcome!</h1><p>Thanks for signing up{{#if attribution.utm_campaign}} through our {{attribution.utm_campaign}} campaign{{/if}}.</p><p>We'll be in touch with your personalized health optimization plan.</p>" } }

Response:

{ "templateId": "tpl_welcome01", "name": "Lead Welcome Email", "channel": "email", "status": "draft", "createdAt": "2026-05-19T14:05:00Z" }

Step 3: Bind the Template to the Event

Connect the template to the event type. When lead.captured.v1 fires, the platform will render and send this template.

Tool: events.bind_template

{ "tool": "events.bind_template", "input": { "event_name": "lead.captured.v1", "brand_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "template_id": "tpl_welcome01", "channel": "email" } }

Response:

{ "binding_id": "bind_abc123", "event_name": "lead.captured.v1", "template_id": "tpl_welcome01", "channel": "email", "status": "active" }

Step 4: Test the Pipeline

Fire a test event to verify everything works end-to-end. Test events are tagged and routed to the sandbox — no real messages are sent to actual users.

Tool: events.fire_test

{ "tool": "events.fire_test", "input": { "event_name": "lead.captured.v1", "brand_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "payload": { "email": "test@loop.health", "source": "vsl_form", "attribution": { "utm_source": "google", "utm_campaign": "bpc157-launch" } }, "recipient": "qa@loop.health" } }

Response:

{ "ok": true, "data": { "event_name": "lead.captured.v1", "status": "delivered", "channel": "email", "recipient": "qa@loop.health" } }

What Happens Next

Once you’re satisfied with the test:

  1. The event declaration is already active — any lead.captured.v1 event will trigger the welcome email
  2. Fire events from your application using the REST API or @loop/contracts (see Web App Integration)
  3. Monitor delivery via analytics.ask or the platform dashboard