Connect Bubble to SendGrid by adding the API Connector plugin, setting your SendGrid API key as a Private Authorization header (server-side only), and creating a POST call to /v3/mail/send. Use Dynamic Templates to keep HTML off your Bubble JSON body. Verify your sender identity in SendGrid first — the #1 cause of 403 errors — then wire the action to a Backend Workflow triggered by form submissions or user sign-ups.
| Fact | Value |
|---|---|
| Tool | SendGrid |
| Category | Marketing |
| Method | Bubble API Connector |
| Difficulty | Intermediate |
| Time required | 45–60 minutes |
| Last updated | July 2026 |
Why SendGrid is the Right Transactional Email Choice for Bubble Apps
Most Bubble apps eventually need to send emails that aren't Bubble's built-in notification: a beautifully branded welcome email when someone signs up, an order confirmation after a purchase, or a reminder when a workflow hits a deadline. Bubble's native email is limited and unbranded. SendGrid fills that gap with a professional delivery infrastructure and a visual template editor.
The integration is cleaner in Bubble than in many other tools. Platforms like FlutterFlow require routing every API call through a Firebase Cloud Function because keys in client-side Dart code are readable. Bolt.new stores keys in a visible `.env` file inside the WebContainer. Bubble's API Connector solves this at the architecture level: every header marked 'Private' stays on Bubble's servers. There is no extra infrastructure to maintain.
The workflow is straightforward: a user fills out a form (or completes a purchase, or signs up), a Bubble workflow fires, and the API Connector action calls SendGrid's `/v3/mail/send` endpoint with the right recipient and template data. SendGrid handles delivery, bounce tracking, and suppression lists. You can surface suppression data back in Bubble via GET calls — giving non-technical founders a deliverability dashboard without leaving their app.
Integration method
Bubble's API Connector plugin sends all SendGrid calls from Bubble's servers. Your Full-Access API key lives in a header marked 'Private' — it never reaches the browser and no external proxy function is needed.
Prerequisites
- A Bubble account on any plan (API Connector plugin is free; Backend Workflows for server-side triggers require a paid Bubble plan)
- A SendGrid account — free tier allows 100 emails/day
- A SendGrid Full-Access API key with at minimum Mail Send and Suppressions Read/Write scopes (Account → Settings → API Keys → Create API Key)
- A verified sender identity in SendGrid Sender Authentication (Settings → Sender Authentication → verify your 'From' email domain or single sender) — this must be done before any API call will succeed
- At least one Dynamic Template created in the SendGrid Email API → Dynamic Templates section, with a Template ID in the format d-xxxxxxxxxx
Step-by-step guide
Create a Scoped SendGrid API Key and Verify Your Sender
Before touching Bubble, get two things right in your SendGrid account: a properly scoped API key and a verified sender identity. Both must exist before the first API call will work. Log in to SendGrid and go to Settings → API Keys → Create API Key. Give it a name like 'Bubble App'. Under permissions, choose 'Restricted Access'. Enable 'Mail Send' (Full Access) and 'Suppressions' (Full Access). Click Create & View, copy the key (starts with `SG.`), and store it somewhere secure — SendGrid only shows the full key once. Next, verify your sender. Go to Settings → Sender Authentication. The simplest path for a custom domain is 'Authenticate Your Domain' — enter your domain, follow the DNS record instructions your email provider gives you, and click Verify. For faster setup on a non-custom domain, use 'Verify a Single Sender' with an email you own and can click a verification link from. Without verified sender authentication, every API call to /v3/mail/send will return a 403 Forbidden error — and that 403 looks identical to an incorrect API key error, which is why this step confuses beginners.
Pro tip: Domain authentication improves deliverability significantly over single-sender verification. If you have access to your domain's DNS settings, take the extra 10 minutes to do it now.
Expected result: You have an SG. API key with Mail Send + Suppressions scopes, and your From address passes SendGrid Sender Authentication. You're ready to configure Bubble.
Install the API Connector Plugin and Configure SendGrid Authentication
Open your Bubble editor and navigate to the Plugins tab in the left sidebar. Click 'Add plugins' and search for 'API Connector'. Install the API Connector plugin by Bubble — it's free and installs instantly. After installation, click on 'API Connector' in your Plugins list. Click 'Add another API' and name it 'SendGrid'. In the 'Authentication' dropdown, select 'None or self-handled' — you'll set the key manually in a shared header so you have full control over the Private checkbox. Under 'Shared headers for all calls', click the plus to add a header. Name it `Authorization`. In the value field, enter `Bearer SG.yourfullapikey` (replace with your actual key). Now, critically, check the 'Private' checkbox next to this header. The Private checkbox is what keeps your key server-side — without it, the Authorization header is sent from the browser and anyone opening DevTools on your site can read the key and send emails from your domain. Also add a second shared header: `Content-Type` with value `application/json` (no Private checkbox needed — this is not sensitive). Set the API's base URL to `https://api.sendgrid.com`.
1{2 "base_url": "https://api.sendgrid.com",3 "shared_headers": [4 {5 "name": "Authorization",6 "value": "Bearer SG.yourkey",7 "private": true8 },9 {10 "name": "Content-Type",11 "value": "application/json",12 "private": false13 }14 ]15}Pro tip: If you ever rotate your SendGrid API key (which you should do periodically), update only the value in this shared header field. All calls inherit the new key automatically.
Expected result: The API Connector shows 'SendGrid' in your API list with the Authorization header marked Private. The base URL is set. You're ready to add the first call.
Create the Send Email Action Using a Dynamic Template
Click 'Add a new call' under your SendGrid API. Name this call 'Send Transactional Email'. Set the method to POST and the path to `/v3/mail/send`. Change 'Use as' to 'Action' — because this call changes state (sends an email), not data retrieval. Set the Body type to 'JSON body'. In the body editor, enter the request structure. The cleanest pattern uses a Dynamic Template ID rather than embedding HTML directly in the body — this keeps your Bubble JSON body minimal and lets you control email design in SendGrid's visual editor. The request body should look like the code block below. Replace `d-xxxxxxxxxx` with your actual template ID from SendGrid's Email API → Dynamic Templates section. For the Initialize call step: Bubble requires a real, successful API response to auto-detect the response fields. Click 'Initialize call'. Before clicking, replace all the `<dynamic>` placeholders with real test values: use an email address you own as both from and to, and fill in any variables your template expects. Click 'Save & Initialize'. If you get a 202 response, initialization succeeds and Bubble detects the (empty) response body. If you get 400, your body has a JSON syntax error. If you get 403, your sender isn't verified yet. After initialization, the call appears in your SendGrid API with a green checkmark. All `<dynamic>` placeholders become input parameters you can map from Bubble data.
1{2 "personalizations": [3 {4 "to": [5 {6 "email": "<dynamic: recipient_email>"7 }8 ],9 "dynamic_template_data": {10 "first_name": "<dynamic: first_name>",11 "order_id": "<dynamic: order_id>"12 }13 }14 ],15 "from": {16 "email": "<dynamic: from_email>",17 "name": "<dynamic: from_name>"18 },19 "template_id": "d-xxxxxxxxxx"20}Pro tip: You can have multiple Dynamic Templates — one for welcome emails, one for order confirmations, one for password resets. Create a separate API Connector call for each template, hardcoding the template_id so each action is clearly named in Bubble's workflow editor.
Expected result: The 'Send Transactional Email' call is initialized with a 202 response. Dynamic template data fields (first_name, order_id, etc.) appear as input parameters in the call. Bubble shows no errors in the API Connector.
Wire the Send Email Action to a Bubble Workflow
Now connect the API call to an event in your Bubble app. Go to the Workflow tab. You can trigger an email send from almost any event: a button click, a sign-up completion, a data change, or a scheduled Backend Workflow. For a sign-up confirmation email: create a workflow on your sign-up page. The trigger is 'When a User signs up' (or 'When Sign Up button is clicked'). Add a new step and choose 'Plugins → SendGrid → Send Transactional Email'. Bubble will show input fields for each `<dynamic>` parameter you defined in the call body: - `recipient_email` → map to 'Result of step 1's email' or 'Current User's email' - `first_name` → map to 'Current User's first name' - `from_email` → enter your verified sender address as a static value (e.g., hello@yourapp.com) - `from_name` → enter your app or brand name as a static value - `order_id` → map to 'Current Order's ID' (or leave empty if not used) For more complex triggers, use a Backend Workflow (Settings → Backend workflows → New API Workflow) and call the SendGrid action as a step. Backend Workflows can be scheduled, triggered by other workflows, or called via API — perfect for post-purchase emails, reminder emails, or batch sending. Note: Backend Workflows require a paid Bubble plan. RapidDev's team has built hundreds of Bubble apps with transactional email integrations like this — if your email flow is more complex (conditional templates, retry logic, batching), a free scoping call at rapidevelopers.com/contact can help you design it right.
Pro tip: Add an 'Only when' condition to your workflow step if you want to gate the email send — for example, 'Only when Current User's email opt-in is yes'. This prevents sending to users who haven't consented.
Expected result: The workflow fires correctly: trigger the event in your Bubble preview, check SendGrid's Activity Feed (Marketing → Activity) to confirm a '202 Accepted' delivery event appears within seconds.
Add a Suppression Check Call for Deliverability Monitoring
A production-grade integration should also surface email health data in your Bubble admin panel. SendGrid's suppression endpoints let you see bounced or spam-reported addresses without leaving Bubble. Back in the API Connector under your SendGrid API, click 'Add a new call'. Name it 'Get Bounces'. Set method to GET, path to `/v3/suppressions/bounces`. Change 'Use as' to 'Data'. Leave the body empty. Click 'Initialize call'. SendGrid will return a JSON array of suppressed addresses. Bubble auto-detects the fields: `email`, `created` (Unix timestamp), and `reason`. On your admin page in Bubble, add a Repeating Group. Set Type to 'External API response' and Data Source to 'Get data from external API → SendGrid - Get Bounces'. Map each text element to `Current cell's email`, `Current cell's reason`, and a formatted date from `Current cell's created` (multiply the Unix timestamp by 1000 in a Bubble expression, then format as Date). This gives a simple suppression list view your team can monitor without SendGrid account access. A 'Remove from bounces' button can call DELETE `/v3/suppressions/bounces/{email}` — create a separate API Connector action call for this.
1{2 "method": "GET",3 "url": "https://api.sendgrid.com/v3/suppressions/bounces",4 "headers": {5 "Authorization": "Bearer <private>",6 "Content-Type": "application/json"7 },8 "params": {9 "start_time": "<optional: unix timestamp>",10 "end_time": "<optional: unix timestamp>",11 "limit": "100",12 "offset": "0"13 }14}Pro tip: The `created` field from the bounces API is a Unix timestamp in seconds. To display it as a readable date in Bubble, use a formula: `1970-01-01 + Current cell's created * 1000 milliseconds` — or just multiply by 1,000 and use Bubble's 'formatted as date' feature.
Expected result: The admin repeating group populates with any bounced addresses from your SendGrid account. The date column shows human-readable dates. The integration is complete end-to-end.
Common use cases
Welcome Email on User Sign-Up
When a new user registers on your Bubble app, trigger a personalized welcome email using a SendGrid Dynamic Template. Pass the user's first name and app-specific onboarding steps as Handlebars variables. This replaces Bubble's default notification with a branded, deliverable email that arrives in the primary inbox rather than promotions.
Add a workflow on the Sign Up page: when 'Sign up' button is clicked and user is created, call the SendGrid API Connector action 'Send Welcome Email' with to = Current User's email, dynamic_template_data = {"first_name": Current User's first name, "app_name": "YourApp"}.
Copy this prompt to try it in Bubble
Order Confirmation After Purchase
Fire a transactional order confirmation email the moment a payment workflow completes in Bubble. Use a Dynamic Template with order line items passed as a JSON array in the template data object. SendGrid renders the items into an HTML table in the email template — your Bubble JSON body stays clean.
In the post-payment workflow, add an API Connector action step: call 'Send Order Confirmation' with to = Current User's email, template_id = 'd-yourtemplateid', dynamic_template_data = {"order_id": Current Order's ID, "total": Current Order's total, "items": Current Order's line items list formatted as JSON}.
Copy this prompt to try it in Bubble
Deliverability Monitoring Dashboard
Build an admin page in Bubble that calls GET /suppressions/bounces and GET /suppressions/spam_reports to display a list of email addresses that are failing delivery. Non-technical founders can monitor email health and remove problem addresses without logging into SendGrid.
Add a repeating group on the Admin page with Type = External API response. Data Source = Get data from external API → SendGrid 'Get Bounces'. Display Email, Created date (formatted), and Reason for each row. Add a 'Remove' button that calls the DELETE /suppressions/bounces/{email} API action.
Copy this prompt to try it in Bubble
Troubleshooting
403 Forbidden error on every /v3/mail/send call even though the API key looks correct
Cause: The 'From' email address used in the request body has not been verified in SendGrid's Sender Authentication. SendGrid rejects send requests from unverified senders regardless of API key validity.
Solution: Go to your SendGrid dashboard → Settings → Sender Authentication. Either authenticate your sending domain (recommended) or verify the specific sender email address as a Single Sender. After verification is confirmed (can take a few minutes for domain verification), retry the API call in Bubble.
Bubble's 'Initialize call' fails with an error before saving the API call configuration
Cause: The Initialize call requires a real, successful API response from SendGrid. If the body contains placeholder text or an invalid email address, SendGrid returns a 400 error and Bubble cannot detect response fields.
Solution: Before clicking 'Initialize call', replace every <dynamic> placeholder in the body with real test values: a valid recipient email you own, your verified From address, and real template variable values. The initialization call actually sends a test email, so use a test address. After initialization succeeds with a 202 response, restore the dynamic mappings.
API key appears to be leaked — someone is sending emails from my domain without my action
Cause: The 'Private' checkbox on the Authorization header was not checked. Without Private, the Bearer token is visible in browser network requests and can be extracted by anyone with DevTools.
Solution: Immediately rotate the SendGrid API key (Settings → API Keys → delete old key → create new key). In the Bubble API Connector, update the Authorization header value with the new key and check the 'Private' checkbox. Verify the checkbox is ticked — it shows a lock icon next to the header name.
Marketing contacts added via API appear as a job ID with no immediate confirmation
Cause: SendGrid's Add Contacts API for marketing contacts (POST /v3/marketing/contacts) is asynchronous. It returns a `job_id` immediately but contacts are not available for several minutes.
Solution: This is expected behavior for the marketing contacts endpoint. If you need immediate confirmation, poll GET /v3/marketing/contacts/imports/{id} with the returned job_id until the status shows 'completed'. For the transactional /v3/mail/send endpoint, a 202 response means the email is queued — it is not asynchronous in the same way.
Backend Workflow send-email step is not available on my Bubble app
Cause: Backend Workflows (API Workflows) are only available on paid Bubble plans. The free plan does not include server-side workflow scheduling.
Solution: To trigger the email from a client-side workflow on the free plan, use a page-level workflow (Button click, Page is loaded, etc.) instead of a Backend Workflow. Backend Workflows are needed for scheduled sends, API-triggered sends, or sends that run after the user closes the browser. Upgrade to the Starter plan ($32/mo) to enable Backend Workflows.
Best practices
- Always check the 'Private' checkbox on the SendGrid Authorization header in Bubble's API Connector — without it, your SG. key is readable in the browser's network requests.
- Verify your sender identity in SendGrid Sender Authentication before building any Bubble workflow — it's the single most common cause of 403 errors and must be done first.
- Use Dynamic Templates instead of embedding HTML in the Bubble API call body. This keeps your JSON body clean and lets marketing teams edit email design in SendGrid without touching Bubble.
- Create separate API Connector calls for each email type (welcome, order confirmation, password reset) with descriptive names — this makes the workflow editor much easier to navigate as your app grows.
- Set up a suppression check page in your Bubble admin panel using GET /v3/suppressions/bounces to monitor deliverability without logging into SendGrid.
- Add 'Only when' conditions to email workflow steps to gate sends based on user consent fields — e.g., 'Only when Current User's email_opt_in is yes'.
- WU awareness: each API call consumes Workload Units on Bubble's post-2023 pricing. If you have a Backend Workflow sending emails to hundreds of users in a loop, monitor WU usage in the Logs tab and consider batching with scheduled workflows.
- Store the 'from' email and 'from' name as Bubble App Data constants (Settings → Option sets or a single-row config table) so you can change them without editing every workflow.
Alternatives
Mailchimp is campaign-oriented — you build a list, segment it, and schedule batch sends to groups. SendGrid is transactional — one email fires per user action. Choose SendGrid for triggered emails (welcome, order confirmation, password reset); choose Mailchimp if your primary need is newsletter campaigns and audience management.
Intercom handles customer messaging and support conversations, and includes outbound messaging features. SendGrid is purely email delivery infrastructure. If you need a live chat widget, conversation inbox, and automated messaging sequences in addition to email, Intercom covers more ground — but at a much higher price point.
Klaviyo combines transactional email with behavioral segmentation and e-commerce automation flows. It's more expensive than SendGrid but handles both triggered emails and campaign sending in one platform. For Bubble apps with e-commerce and purchase-event driven email flows, Klaviyo may replace both SendGrid and Mailchimp.
Frequently asked questions
Does Bubble expose my SendGrid API key to website visitors?
Not if you check the 'Private' checkbox on the Authorization header in the API Connector. With Private enabled, the header is stripped from any client-side request and only sent from Bubble's servers. Without Private, the key is visible in browser DevTools and should be considered compromised.
Why am I getting a 403 error even though my API key is correct?
A 403 from SendGrid's /v3/mail/send endpoint almost always means the From address in your request body is not verified in SendGrid Sender Authentication. This is separate from API key validity — go to SendGrid Settings → Sender Authentication and verify your sending email or domain before retrying.
Do I need a paid Bubble plan to use SendGrid?
Not for basic usage. The API Connector plugin works on all Bubble plans including Free. You only need a paid Bubble plan if you want to trigger emails from Backend Workflows (server-side, scheduled, or API-triggered). A button click or form submit on a page can fire the SendGrid action on the free plan.
Can I use SendGrid for bulk newsletter sends from Bubble?
Technically yes, but SendGrid is designed for transactional email (one recipient per API call). For batch newsletter sends to thousands of subscribers, Mailchimp or Klaviyo are architecturally better choices — they have list management, unsubscribe handling, and bulk send infrastructure built in. Using SendGrid to loop through 1000 contacts in a Bubble workflow would consume significant WU and could hit rate limits.
My Initialize call sends a real email to the test address — is that expected?
Yes. Bubble's Initialize call actually executes the API request to detect response fields. For a POST /v3/mail/send call, that means a real email is delivered to whatever 'to' address you enter during initialization. Always use a test email address you own for the initialization step, not a customer's address.
How do I add multiple recipients to a single SendGrid call from Bubble?
The personalizations array in the /v3/mail/send body supports multiple 'to' objects. You can make the entire 'to' array dynamic by passing it as a JSON-formatted list from Bubble. However, for personalized emails (different Handlebars variables per recipient), create a separate API call per recipient — either in a loop Backend Workflow or by sending one request with separate personalizations entries.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation