DEV Community

Cover image for ZeptoMail: How to Send Transactional Emails in Your Application
Stephen Gbolagade
Stephen Gbolagade

Posted on

ZeptoMail: How to Send Transactional Emails in Your Application

If you’re building a SaaS or any type of application and you need an affordable, reliable way to send transactional emails, ZeptoMail by Zoho is a top-tier choice, and I'm sure you have made that decision already, or are about to.

Before diving in, it is worth noting that at the time of writing this article, Zeptomail is strictly for transactional emails. If you’re looking for a way to blast an email campaign to your users, you can try Zoho Campaign (if you really like Zoho’s ecosystem) or any other marketing software out there.

Note the differences again between transactional and marketing emails:

  • Transactional: Triggered by user actions (password resets, order receipts). System-to-user.

  • Marketing: Sent manually for promotion (newsletters, sales). One-to-many.

Note (again): ZeptoMail is strictly for transactional mail. For newsletters, stick to Mailchimp or Zoho Campaigns.

How to Get Started with Zeptomail by Zoho

Getting started is pretty straightforward:

  • Sign up at https://www.zoho.com/zeptomail/
  • Complete your profile
  • Add a custom domain, and contact support via live chat to approve your domain
  • Verify your domain: configure your DNS (very important)
  • Start integrating

Zeptomail DNS Configuration

To verify your domain name, Zoho will provide you with the CNAME and TXT records you need to add to your DNS. Update your DNS with those details, and you’ll be verified automatically.

Zeptomail Txt and CNAME DNS verification

The DNS setup is not just for Zeptomail’s verification, but it’s a must if you want your email messages to be delivered to the recipients.

Note that before you can be granted access to start using the email service, you need to provide a way to verify what you need the service for. I recommend having a clear landing page for your website and showing it to them to activate your account.

If you’re already on production, you can buy CREDIT so you never run out of it unexpectedly; otherwise, the free credit is enough for testing.

Zeptomail credit costs N1,200 for 1 CREDIT. And 1 Credit is 10,000 email messages, which lasts up to 6 months… This is literally less than $1 for me (I live in Nigeria, the price might be adjusted a bit in your country).

The next thing is integration.

How to Integrate Zeptomail in a Custom Application

There are two best ways to integrate Zeptomail by Zoho in your application, the first one is using the SMTP approach with a transporter, and the second method is using the RESTful API provided by ZOHO.

NOTE: I use Nodejs/Nextjs as an example, but you can pick the idea and use it for Python, C#, PHP, and Java.

1. The SMTP Approach (Nodemailer)

Best for traditional servers or migrating from existing providers like Gmail or SendGrid. It treats ZeptoMail as a high-volume relay.

Zeptomail SMTP Approach

Installation:
npm install nodemailer

Implementation:

const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
    host: 'smtp.zeptomail.com',
    port: 587,
    secure: false, // Use STARTTLS
    auth: {
        user: 'email@yourdomain.com', 
        pass: 'YOUR_ZEPTOMAIL_API_KEY' 
    }
});

async function sendMail() {
    const info = await transporter.sendMail({
        from: '"App Name" <noreply@yourdomain.com>',
        to: 'customer@example.com',
        subject: 'Reset Your Password',
        html: '<b>Click the link below...</b>',
    });
    console.log('Sent:', info.messageId);
}
Enter fullscreen mode Exit fullscreen mode

The major setup here is the transporter, which is straightforward. For the sendMail() function, you can extend it as much as you like, you can make it reusable, and handle multiple recipients.

PS: the from email must end with the verified custom domain, else it will be false.

2. The RESTful API Approach

Best for Serverless (Lambda/Vercel) or microservices. It skips the SMTP handshake overhead, making it faster and more lightweight.

Zeptomail's API Approach

For more than 18 months, I have been using the SMTP approach for both development and production, but recently it has started misbehaving in development. So I have to switch to using the API directly, and it’s been so sweet.

I will use Node/NextJS for this API approach example, too.

Reusable Utility (TypeScript + React Email for React-based app):
This snippet handles both HTML strings and React Email components.

export async function sendEmail({ to, subject, react, emailHtml, attachments }: SendEmailOptions) {
  const apiKey = process.env.ZEPTOMAIL_API_KEY; 
  const senderEmail = "noreply@yourdomain.app";

  const recipients = Array.isArray(to) ? to : [to];

  try {
    const response = await fetch("https://api.zeptomail.com/v1.1/email", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Zoho-enczapikey ${apiKey}`,
      },
      body: JSON.stringify({
        from: { address: senderEmail, name: "YourBrand" },
        to: recipients.map((addr) => ({ email_address: { address: addr } })),
        subject,
        htmlbody: emailHtml,
        // Optional: Map attachments to Base64
        ...(attachments?.length && {
          attachments: attachments.map((att) => ({
            name: att.filename,
            content: typeof att.content === "string" ? att.content : att.content.toString("base64"),
            mime_type: att.contentType || "application/octet-stream",
          })),
        }),
      }),
    });

    const data = await response.json();
    return response.ok ? { success: true, id: data.request_id } : { success: false, error: data };
  } catch (error) {
    return { success: false, error };
  }
}
Enter fullscreen mode Exit fullscreen mode

And that’s it.

You can copy this example and change the parameters to use if your app is a NodeJS-based app. But note the AUTHORIZATION field, Zoho-enczapikey before your API key, is important just like you do Bearer … Otherwise, your email service request will fail.

If you're on a modern stack like Next.js or Supabase Edge Functions, simply go with the REST API. It’s simple, faster, has no connection overhead, and gives you better access to ZeptoMail's advanced reporting features.

If you are having issues working with Zeptomail integration, you can ask, and the community, including myself, will try to put you through, or simply contact Zeptomail’s support.


Cover image and Screenshots: Zeptomail

Top comments (0)