Wraps Logo
Bolt.new + Email Guide

How to Send Email from Your Bolt.new App

You built it in Bolt. Now users need a welcome email, a receipt, a password reset. Here's how to wire it up in 10 minutes — without writing a single line of email logic in your app.

10 min readWraps Team
10 min
Setup time
$0.10
Per 1K emails
0 lines
Of email logic in your app
What you're building
Your Bolt.new server emits a behavioral event when something happens. A Wraps workflow catches it and sends the email. Your app has no email logic — it just says "this happened."

One-time setup

Run these in your local terminal — not inside Bolt.new.

Set up AWS

You need an AWS account with the CLI configured. Free tier is enough for most apps. AWS setup guide

Deploy email infrastructure

Sets up SES in your account and verifies your sending domain. Domain verification guide

Terminal
npx @wraps.dev/cli email init

Connect to the Wraps Platform

Terminal
npx @wraps.dev/cli platform connect

Creates a cross-account IAM role so the Wraps Platform can send email through your SES when a workflow fires. Run this once — re-run wraps platform update-role if you add new features later.

Get a Wraps API key

In the Wraps dashboard, go to Settings → API Keys and create a new key named bolt-app.

Copy the key now — shown once.
Once you close the dialog the full key is gone. If you lose it, delete it from the dashboard and create a new one.

Add the key to Bolt.new (.env)

Add it to your server-side .env file — no VITE_ prefix.

Never use VITE_WRAPS_API_KEY
Bolt.new uses Vite — VITE_ variables get bundled into browser JS and are readable in DevTools. Server-side .env variables are only accessible in your Node.js routes.
.env (server-side only)
WRAPS_API_KEY=wraps_a1b2c3d4....<hmac>

Emit events from your server

Install the SDK

Terminal
npm install @wraps.dev/client

Initialize once, use anywhere

server/lib/wraps.ts
import { createPlatformClient } from "@wraps.dev/client";

export const wraps = createPlatformClient({
  apiKey: process.env.WRAPS_API_KEY!,
});

Emit events from your routes

server/routes/auth.ts (or wherever events happen)
import { wraps } from "../lib/wraps";

// When a user signs up
app.post("/api/signup", async (req, res) => {
  const { email, name } = req.body;
  // ... create user ...

  await wraps.track("user.signed_up", {
    contactEmail: email,
    contactName: name,
    createIfMissing: true,
    properties: { plan: "free", source: "bolt" },
  });

  res.json({ success: true });
});

// When an order is placed
app.post("/api/orders", async (req, res) => {
  // ... process order ...

  await wraps.track("order.placed", {
    contactEmail: req.user.email,
    properties: { orderId: order.id, amount: order.total },
  });

  res.json({ order });
});

Set up a workflow in Wraps

Email logic lives in the Wraps dashboard, not your code.

  1. 1Dashboard → Workflows → New workflow
  2. 2Trigger: Event received → event name: user.signed_up
  3. 3Step: Send email → choose your template

See the custom events guide for full workflow reference.

Common events to track

EventTriggers
user.signed_upWelcome email
order.placedOrder confirmation
password.reset_requestedPassword reset
subscription.cancelledWin-back sequence
trial.endingUpgrade nudge

FAQ

Run npx @wraps.dev/cli email init to set up SES, then wraps platform connect to give Wraps permission to send through your SES in workflows. After that, your app calls api.wraps.dev via the SDK — no Lambda deploy needed.

Ready to Connect Your Bolt.new App?

Emit an event from your server. Wraps sends the email. No email logic in your code.

Related Articles