Bubble.io Email Notifications: SendGrid Integration Complete Guide
Transactional email is infrastructure, not a feature. Invitation emails, billing alerts, trial reminders, and activity digests — built correctly in Bubble with SendGrid, dynamic templates, and per-user preference controls.
Email Is Still Your Highest-ROI Communication Channel
Push notifications get dismissed. Slack messages get lost. Email is where business decisions happen. For SaaS products, transactional email — invitation emails, payment receipts, password resets, activity notifications, trial reminders — is not optional. It is infrastructure. This guide shows you how to build a production-grade email system in Bubble using SendGrid, with dynamic templates, reliable delivery, and per-user preferences.
Connecting SendGrid to Bubble in Four Steps
Auth header: Authorization: Bearer SG.YOUR_API_KEY (Private)
Call name: Send Transactional Email
Method: POST
URL: https://api.sendgrid.com/v3/mail/send
Body (JSON):
{
“personalizations”: [{
“to”: [{“email”: “<to_email>”, “name”: “<to_name>”}],
“dynamic_template_data”: {
“subject”: “<subject>”,
“body_text”: “<body_text>”,
“cta_url”: “<cta_url>”,
“cta_label”: “<cta_label>”
}
}],
“from”: {“email”: “hello@yourapp.com”, “name”: “Your App”},
“template_id”: “<template_id>”
}
In SendGrid, create one master template with your brand design. Use Handlebars variables for all dynamic content: {{subject}}, {{body_text}}, {{cta_url}}. One template serves every email type — the body text changes per use case. This means you can update your email design once and every email type gets the update instantly, with zero Bubble changes.
// Parameters: to_email, to_name, subject, body_text, cta_url, cta_label, template_id
Step 1: Only when: to_email is not empty AND contains “@”
Step 2: SendGrid – Send Transactional Email
[pass all parameters through]
Step 3: Create EmailLog record (for debugging)
recipient, template_id, sent_at, status
// Every other workflow calls THIS workflow instead of SendGrid directly
// One place to update, fix, or swap email providers
User:
notif_activity_emails (yes/no, default yes)
notif_billing_emails (yes/no, default yes)
notif_digest_emails (yes/no, default yes)
// Before sending any optional email
Only when: recipient User’s notif_activity_emails = yes
// Billing emails are never optional — always send those
Every SaaS Email You Need to Build
| Trigger | Required? | Opt-Out? | |
|---|---|---|---|
| Team invitation | Invitation record created | Yes | No |
| Welcome / onboarding | Workspace created | Yes | No |
| Trial ending (3 days) | Scheduled workflow, 3 days before trial_ends_at | Yes | No |
| Payment failed | invoice.payment_failed Stripe webhook | Yes | No |
| Payment receipt | invoice.payment_succeeded Stripe webhook | Yes | No |
| Cancellation confirmed | customer.subscription.deleted webhook | Yes | No |
| Activity digest (weekly) | Scheduled workflow, every Monday 8am | No | Yes |
| Re-engagement (30 days inactive) | Scheduled workflow checks last_active date | No | Yes |
Ready to Build on Bubble?
Architecture, data model design, Stripe billing, and full SaaS builds — done right from day one.
