Send transactional emails from Cloudflare Workers using Lettr’s HTTP API. Workers run on Cloudflare’s global edge network with instant cold starts and zero-millisecond latency — perfect for email APIs that need to be fast anywhere in the world.
Using Cursor? Jump straight in using this prompt
Prerequisites
Before you begin, make sure you have:
You’ll also need:
- Cloudflare account (free tier works)
- Wrangler CLI installed (
npm install -g wrangler)
- Node.js 18.x or 20.x for local development
Quick Setup
Create a new Worker project
npm create cloudflare@latest my-email-worker
cd my-email-worker
When prompted, choose:
- Type: “Hello World” Worker
- TypeScript: Yes (recommended)
- Git: Yes (optional)
- Deploy: No (we’ll deploy later)
Install the Lettr SDK
The SDK works seamlessly with Workers and provides a clean, type-safe interface. Add your API key as a secret
npx wrangler secret put LETTR_API_KEY
When prompted, paste your Lettr API key (starts with lttr_).Secrets are encrypted environment variables that are not visible in your code or Wrangler config. They’re perfect for API keys.
Deploy your Worker
Your Worker will be deployed to Cloudflare’s edge network and available at https://my-email-worker.your-subdomain.workers.dev.
Worker Implementation
Create or update src/index.ts:
import { Lettr } from 'lettr';
export interface Env {
LETTR_API_KEY: string;
FROM_EMAIL?: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Only allow POST requests
if (request.method !== 'POST') {
return new Response('Method not allowed', { status: 405 });
}
// Initialize Lettr client
const lettr = new Lettr(env.LETTR_API_KEY);
try {
const body = await request.json() as {
to: string | string[];
subject: string;
html?: string;
text?: string;
};
const { to, subject, html, text } = body;
// Validate required fields
if (!to || !subject || (!html && !text)) {
return Response.json(
{ error: 'Missing required fields: to, subject, and html or text' },
{ status: 400 }
);
}
// Send email
const result = await lettr.emails.send({
from: env.FROM_EMAIL || 'noreply@yourdomain.com',
to: Array.isArray(to) ? to : [to],
subject,
html,
text,
});
console.log(`Email sent successfully. Request ID: ${result.request_id}`);
return Response.json({
success: true,
requestId: result.request_id,
accepted: result.accepted,
});
} catch (error: any) {
console.error('Failed to send email:', error);
return Response.json(
{ error: error.message || 'Failed to send email' },
{ status: error.status || 500 }
);
}
},
};
Cloudflare Workers use the Env interface to define environment variables and secrets. The Lettr SDK automatically handles retries and provides detailed error messages.
Configuration
Configure your Worker in wrangler.toml:
name = "my-email-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"
# Non-sensitive environment variables
[vars]
FROM_EMAIL = "noreply@yourdomain.com"
# Secrets (set via wrangler secret put)
# LETTR_API_KEY = "set via CLI"
Never commit API keys to wrangler.toml. Always use wrangler secret put for sensitive values.
What’s Next