Back to Blog

How to Send Emails Based on Product Events (API Guide)

10 min read

The most effective SaaS emails are triggered by what users actually do in your product. User signs up but doesn't complete onboarding? Send a help email. User creates their first project? Send tips for getting more value. User hits a usage limit? Send an upgrade prompt.

This is event-based email, and it requires connecting your product's event stream to your email platform. This guide walks through the technical implementation: how to track events, send them to your email system, and build automations that respond to user behavior.

The Event-Based Email Architecture

Before diving into code, understand how the pieces fit together.

Your application generates events when users take actions. These events include information about what happened, who did it, and any relevant metadata. For example: "user_created_project" by user 123, with project name "Q1 Marketing Campaign."

These events need to get to your email platform. You can send them directly via API, or through an event streaming service like Segment. Either way, the email platform receives a stream of events with user identifiers and event properties.

Your email platform uses these events as triggers for automations. You configure rules like "when user_created_project fires for the first time, send the project tips email." The platform matches incoming events to rules and sends the appropriate emails.

The user receives an email that feels timely and relevant because it's responding to something they just did.

Defining Your Events

Start by defining the events you want to track. Don't try to track everything. Focus on events that map to meaningful moments in the user journey.

For most SaaS products, you need events in these categories:

Account events: user_signed_up, user_verified_email, user_completed_onboarding, user_invited_teammate

Feature events: The first time a user uses each major feature. project_created, integration_connected, report_generated, automation_activated

Engagement events: user_logged_in, user_returned_after_inactivity (if a user logs in after 7+ days of inactivity)

Billing events: subscription_started, subscription_upgraded, subscription_cancelled, payment_failed

Each event should include the user identifier (email or user ID) and relevant properties. For project_created, you might include project_name and project_type. For subscription_upgraded, you might include old_plan and new_plan.

Keep event names consistent. Use snake_case or camelCase throughout, not a mix. Use past tense (user_created_project) or present tense (user.created_project) consistently. Your future self will thank you.

Sending Events to Your Email Platform

Most email platforms accept events through a REST API. The typical pattern is a POST request with the event name, user identifier, and properties.

Here's what the API call generally looks like:

// Example: sending an event when a user creates a project
await fetch('https://api.emailplatform.com/v1/events', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    event: 'project_created',
    email: user.email,
    properties: {
      project_id: project.id,
      project_name: project.name,
      is_first_project: isFirstProject
    },
    timestamp: new Date().toISOString()
  })
})

Call this API from your application code whenever the relevant action happens. In this example, you'd call it right after successfully creating a project in your database.

Some platforms also accept events through client-side JavaScript. This is useful for tracking frontend actions like button clicks or page views. But for important events like project creation, server-side tracking is more reliable because it's not affected by ad blockers or browser issues.

If you're using an event streaming service like Segment, you send events to Segment, and Segment forwards them to your email platform (and any other tools you've connected). This decouples your application code from specific tool integrations.

Handling Events Reliably

Event delivery needs to be reliable. If an event doesn't reach your email platform, the user doesn't get the email they should receive.

Make event sending asynchronous. Don't block your main application flow waiting for the email platform to respond. Send the event in a background job or fire-and-forget, so a slow or failed API call doesn't affect user experience.

Implement retry logic. If the email platform's API returns an error or times out, retry the request. Most platforms have rate limits, so implement exponential backoff: wait 1 second before the first retry, then 2 seconds, then 4, etc.

Log events for debugging. When something goes wrong with email delivery, you'll want to check whether the event was actually sent. Log the event name, user, and timestamp whenever you send an event.

Handle edge cases. What happens if the user doesn't have an email address yet (anonymous users)? What happens if the event fires multiple times due to retries? Design your event sending to handle these gracefully.

Building Automations from Events

Once events are flowing to your email platform, build automations that respond to them.

The basic automation structure is: trigger + conditions + action.

The trigger is the event. "When project_created fires." Some platforms let you add conditions to the trigger itself, like "when project_created fires and is_first_project is true."

Conditions filter which users receive the email. You might add conditions like "user is on free plan" or "user signed up less than 30 days ago." Conditions let you target the right users without creating dozens of separate events.

The action is sending the email. You select which email template to send, and the platform sends it to the user who triggered the event.

Here's an example automation:

Trigger: project_created Conditions: is_first_project = true, user.plan = free Action: Send "First Project Tips" email

This sends the first project email only to free users, and only on their first project. Paid users or users creating subsequent projects don't receive it.

Timing and Delays

Not every event-triggered email should send immediately. Sometimes a delay improves the experience.

Consider a "signup without activation" email. You don't want to send this immediately after signup. The user is probably still exploring. Instead, trigger it 24 hours after signup, with a condition that the user hasn't activated yet.

Most email platforms support delays in automations. The structure becomes: trigger + delay + condition check + action.

Trigger: user_signed_up Delay: 24 hours Condition: user_completed_onboarding = false Action: Send "Need help getting started?" email

The condition is checked after the delay, not at the time of the trigger. This is important. The user might complete onboarding during the 24-hour delay, in which case they shouldn't receive the email.

For immediate emails (like "thanks for upgrading"), skip the delay. For nudge emails (like "you haven't finished setup"), add appropriate delays.

Handling First-Time vs. Repeat Events

Many automations should only fire the first time an event happens. You don't want to send "congrats on your first project" every time someone creates a project.

There are two approaches to handling this.

The first approach is to include "is_first" information in the event itself. When you send project_created, include is_first_project: true or false based on your database. Your automation conditions check this property.

The second approach is to let the email platform track whether a user has received a specific email. Most platforms have a "send only once" option for automations. The platform remembers that user 123 already received the first project email and won't send it again, even if the event fires multiple times.

The first approach gives you more control and makes debugging easier. The second approach is simpler to implement but can be harder to troubleshoot.

Common Event-Triggered Automations

Here are the automations most SaaS products should have:

Welcome email: Trigger on user_signed_up. Send immediately. No conditions needed; everyone who signs up should receive it.

Activation nudge: Trigger on user_signed_up. Delay 24 hours. Condition: user has not completed activation. Send only once.

First feature milestone: Trigger on each major feature event (first project, first integration, etc.). Send immediately. Condition: is_first_time = true.

Inactivity re-engagement: This is trickier because it's based on the absence of events. Most platforms let you trigger on "user has not done X in Y days." Trigger when user hasn't logged in for 7 days. Send re-engagement email.

Upgrade prompt: Trigger on usage_limit_approached (you'd fire this event when usage hits 80% of limit). Condition: user is on free or starter plan. Send upgrade information.

Trial expiration: Trigger on trial_ending_soon (fire this event 7 days before trial ends). Begin the trial expiration sequence.

Debugging Event-Triggered Emails

When an email doesn't send as expected, debugging can be tricky. Here's how to approach it.

First, verify the event was sent. Check your application logs. Did the API call succeed? Did it include the right user and properties?

Second, verify the event was received. Most email platforms have an event log or debugger. Check if the event appears there with the correct data.

Third, verify the automation matched. Check the automation's activity log. Did the event match the trigger? Did the user meet the conditions? Was there a suppression rule that prevented sending?

Fourth, check delivery. If the automation fired but the user didn't receive the email, check deliverability. Did the email bounce? Is the address valid? Is it in spam?

Build visibility into your event pipeline. The more you can see what's happening at each stage, the faster you can fix issues.

Testing Event-Triggered Emails

Test your automations before going live. Create test user accounts and manually trigger events to verify emails send correctly.

Most email platforms have a test mode that lets you trigger automations without sending real emails. Use this during development.

Test the full flow: trigger the event, verify the automation fires, verify the email renders correctly with real user data, verify personalization works, verify links work.

Test edge cases: What happens if a required property is missing? What happens if the user's email is invalid? What happens if the event fires twice? Make sure your automations handle these gracefully.

Scaling Considerations

As your user base grows, event volume increases. A few things to consider:

Batch events if possible. If your email platform supports it, batch multiple events into a single API call. This reduces network overhead and helps you stay within rate limits.

Use queues for reliability. Instead of sending events directly from your application, push them to a message queue (like Redis, RabbitMQ, or SQS) and process them with a background worker. This decouples event generation from event delivery and makes the system more resilient.

Monitor event lag. If events are queuing up and not being processed quickly, your emails will be delayed. Set up monitoring to alert you if event processing falls behind.

Consider event volume in your email platform pricing. Most platforms charge based on contacts, emails sent, or events processed. High event volume can significantly impact costs. Only send events that you actually use for email triggers or segmentation.

Getting Started

Here's a practical path to implementing event-based emails:

Week 1: Identify the 5 most important events for your product. User signup, activation, and 2-3 feature milestones.

Week 2: Instrument your application to send these events to your email platform. Start with server-side tracking for reliability.

Week 3: Build your first automation. Welcome email triggered by signup is the easiest starting point.

Week 4: Add activation nudge and first feature milestone emails. Test thoroughly.

Week 5: Monitor performance and iterate. Check which emails are being opened and clicked. Refine your triggers and content.

Event-based email is a significant improvement over batch campaigns, but it requires upfront investment in instrumentation. Start simple, get the infrastructure working, then expand to more sophisticated automations. The result is emails that feel timely and relevant because they genuinely are.