Send email from Vercel Functions with emailr_
Send transactional email from Vercel Functions with emailr_, manage keys with Vercel environment variables and schedule digest emails with Vercel Cron.
Whether your Vercel project is Next.js, SvelteKit, Astro or plain functions in /api, sending email works the same way: keep the key in an environment variable and call the emailr SDK from server code.
This guide also shows a scheduled digest with Vercel Cron, a common pattern for activity summaries and reminders.
Set up emailr_ with Vercel
- 01
Create an API key
Create a key under API keys in the dashboard. Keys start with
et_live_and are scoped to one domain workspace. Store it asEMAILR_API_KEYin your secret manager or environment, never in client-side code. - 02
Add and verify your sending domain
In the dashboard, open Domains and add the domain you send from. A subdomain such as
mail.yourcompany.comkeeps transactional reputation separate from your corporate mailbox.Emailr generates the DNS records: a DKIM TXT record on the
emailr._domainkeyselector, an SPF TXT record, and an MX + TXT pair on thesendsubdomain used as the MAIL FROM / Return-Path. A DMARC record is optional but recommended.If Vercel manages your domain's DNS, add the records from the Domains page of your Vercel dashboard.
Emailr's DKIM selector and
sendsubdomain don't collide with other providers' records, so you can add them before cutting over and send from both providers during the migration. A domain can only have one SPF record: if one already exists, merge Emailr'sinclude:into it instead of adding a second record. - 03
Add the key to your project
Add
EMAILR_API_KEYfor Production and Preview with the CLI or the project settings, then pull it locally withvercel env pull. Use a separate key per environment so you can revoke one without affecting the others.Terminalbashnpm install emailr vercel env add EMAILR_API_KEY - 04
Send from a function
Vercel Functions accept Web-standard handlers. The SDK client is safe to create at module scope, so warm invocations reuse it.
api/welcome.tstsimport { Emailr } from 'emailr' const emailr = new Emailr({ apiKey: process.env.EMAILR_API_KEY! }) export async function POST(request: Request) { const { email } = await request.json() const result = await emailr.emails.send({ from: 'Acme <[email protected]>', to: email, subject: 'Welcome to Acme', html: '<p>Thanks for signing up.</p>', }) return Response.json({ id: result.message_id }) } - 05
Schedule a daily digest with Vercel Cron
Declare the schedule in
vercel.json. Vercel calls the path with a GET request and, when aCRON_SECRETenvironment variable is set, includes it as a bearer token so you can reject other callers.vercel.json + api/digest.tsts// vercel.json // { "crons": [{ "path": "/api/digest", "schedule": "0 8 * * *" }] } import { Emailr } from 'emailr' const emailr = new Emailr({ apiKey: process.env.EMAILR_API_KEY! }) export async function GET(request: Request) { if (request.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) { return new Response('Unauthorized', { status: 401 }) } const recipients = await getUsersWithActivity() // your query for (const user of recipients) { await emailr.emails.send({ from: 'Acme <[email protected]>', to: user.email, subject: 'Your daily summary', template_id: process.env.DIGEST_TEMPLATE_ID!, template_data: { name: user.name, count: user.count }, }) } return Response.json({ sent: recipients.length }) }
Tips
- For large audiences, a cron job that loops over
emails.send()can hit function time limits. Create a Broadcast to a segment instead. - Webhook handlers on Vercel follow the same pattern as the Next.js guide: read the raw body with
request.text()and verifyX-Emailr-Signature. scheduled_atlets you queue a single email for later without a cron job.
Frequently asked questions
Does emailr_ work with Vercel Edge Functions?
Sending does: the SDK uses fetch. For webhook verification on the edge, use Web Crypto instead of node:crypto.
How do I keep my API key secure on Vercel?
Store it as an environment variable, never prefix it with NEXT_PUBLIC_ or similar, and use separate keys for Production and Preview.
Can I schedule emails on Vercel?
Yes. Use Vercel Cron for recurring jobs, or pass scheduled_at on a single send to have emailr_ deliver it later.
Do I need a separate integration from the Vercel marketplace?
No. An API key in your environment variables is all the setup required.
Keep going
Related guides
- Send email from Next.jsSend transactional email from Next.js App Router route handlers and server actions with the emailr_ SDK, and verify delivery webhooks safely.
- Send email from SupabaseSend transactional and auth email from Supabase Edge Functions with emailr_, including a Send Email auth hook for branded signup and magic-link emails.
- Send email from Cloudflare WorkersSend transactional email from Cloudflare Workers with the fetch-based emailr_ SDK, store keys as Worker secrets and verify webhooks with Web Crypto.
Start sending in minutes
Create a free account, verify your domain and send your first email. No credit card required.