Email Steps & SMTP
Pulsabase Edge Functions include a native Email step for sending transactional emails without an external library. You can use Pulsabase’s built-in SMTP or bring your own provider.
SMTP Configuration
Section titled “SMTP Configuration”Configure your SMTP settings in Dashboard → Settings → Email.
Option A — Pulsabase SMTP (Managed)
Section titled “Option A — Pulsabase SMTP (Managed)”Pulsabase provides a shared SMTP service for development and low-volume production use. No configuration required — it’s enabled by default.
| Setting | Value |
|---|---|
| Provider | Pulsabase Managed SMTP |
| From address | noreply@mail.pulsabase.io |
| Rate limit | 200 emails/day (free tier) |
Option B — Bring Your Own SMTP (Recommended for Production)
Section titled “Option B — Bring Your Own SMTP (Recommended for Production)”Connect any SMTP-compatible provider (SendGrid, Resend, Postmark, AWS SES, IONOS, etc.):
| Field | Example |
|---|---|
| SMTP Host | smtp.sendgrid.net |
| SMTP Port | 587 (TLS) or 465 (SSL) |
| Username | apikey |
| Password | SG.xxxxx (your API key) |
| From Name | Acme Inc. |
| From Email | hello@acme.com |
Email Templates
Section titled “Email Templates”Email templates are managed in Dashboard → Settings → Email Templates. Each template has:
- Slug — unique identifier for use in edge steps (e.g.,
welcome,password-reset) - Subject — static or dynamic (supports
{{variables}}) - Body — HTML or plain text (supports
{{variables}})
Template Variables
Section titled “Template Variables”Templates support the same {{}} interpolation as edge steps:
<!-- Template: welcome --><h1>Welcome, {{name}}!</h1><p>Your account at <strong>{{project_name}}</strong> is ready.</p><p><a href="{{app_url}}">Get started →</a></p>Variables are filled at send-time from the email step’s variables object.
Adding an Email Step
Section titled “Adding an Email Step”In any edge function, add a step of type Email:
Step Configuration
Section titled “Step Configuration”| Field | Description |
|---|---|
to | Recipient email address (string or {{variable}}) |
template | Template slug (e.g., welcome) |
variables | Key-value pairs injected into the template |
reply_to | Optional: reply-to address |
cc | Optional: CC list |
bcc | Optional: BCC list |
Example: Welcome Email Flow
Section titled “Example: Welcome Email Flow”Function: send-welcome-emailTrigger: after INSERT on users (via after hook)
Step 1: fetch_user → [Database] SELECT name, email FROM users WHERE id = {{input.id}}
Step 2: send_welcome → [Email] to: {{steps.fetch_user.body.email}} template: welcome variables: { name: {{steps.fetch_user.body.name}}, project_name: "Acme", app_url: "https://app.acme.com" }Example: Password Reset Email
Section titled “Example: Password Reset Email”Function: password-reset
Step 1: generate_token → [Database] INSERT INTO reset_tokens (user_id, token, expires_at) VALUES ({{input.user_id}}, gen_random_uuid(), NOW() + INTERVAL '1 hour') RETURNING token
Step 2: send_reset → [Email] to: {{input.email}} template: password-reset variables: { reset_url: "https://app.acme.com/reset?token={{steps.generate_token.body.token}}" }Dry Run with Email
Section titled “Dry Run with Email”When testing functions in Dry Run mode, email steps are simulated — no email is actually sent. The __logs output shows exactly what would have been sent:
{ "__logs": [ { "step": "send_welcome", "type": "email", "dry_run": true, "simulated_payload": { "to": "user@example.com", "subject": "Welcome to Acme!", "template": "welcome", "variables": { "name": "Jane", "project_name": "Acme" } } } ]}Best Practices
Section titled “Best Practices”- Use after hooks for transactional emails (welcome, notifications) — they run async and don’t slow down the API response
- Test with dry run before enabling a function on a hook
- Configure reply-to if you want users to be able to reply to transactional emails
- Monitor deliverability — check your SMTP provider’s bounce/complaint rates in their dashboard, not in Pulsabase