New from emailrHealthCheck Email iconHealthCheck Email
emailr_

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.

Vercel iconVercelPlatform

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

  1. 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 as EMAILR_API_KEY in your secret manager or environment, never in client-side code.

  2. 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.com keeps transactional reputation separate from your corporate mailbox.

    Emailr generates the DNS records: a DKIM TXT record on the emailr._domainkey selector, an SPF TXT record, and an MX + TXT pair on the send subdomain 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 send subdomain 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's include: into it instead of adding a second record.

  3. 03

    Add the key to your project

    Add EMAILR_API_KEY for Production and Preview with the CLI or the project settings, then pull it locally with vercel env pull. Use a separate key per environment so you can revoke one without affecting the others.

    Terminalbash
    npm install emailr
    vercel env add EMAILR_API_KEY
  4. 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.tsts
    import { 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 })
    }
  5. 05

    Schedule a daily digest with Vercel Cron

    Declare the schedule in vercel.json. Vercel calls the path with a GET request and, when a CRON_SECRET environment 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 verify X-Emailr-Signature.
  • scheduled_at lets 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.

Start sending in minutes

Create a free account, verify your domain and send your first email. No credit card required.