> ## Documentation Index
> Fetch the complete documentation index at: https://ahasend.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> AhaSend stores all message data in the EU. See /facts.
> The API base URL is https://api.ahasend.com. Send the API key in the Authorization: Bearer header. See /api-reference/authentication.
> Use send.ahasend.com for SMTP. Ports 25, 587 and 2525 use STARTTLS. Port 465 is not supported. See /smtp.
> For send-only integrations, create an API Key v2 under Credentials → Add and scope it to messages:send:{your-domain}. See /send-api/credentials and /api-reference/scopes.

# Send Email in Node.js via SMTP (Nodemailer)

> Send email from Node.js with Nodemailer and the AhaSend SMTP relay: STARTTLS on port 587, HTML, attachments, env vars and sandbox testing.

Send emails through AhaSend's SMTP servers using Node.js with Nodemailer, the most popular and feature-rich email library for Node.js. This guide covers everything from basic setup to advanced features like attachments and custom headers.

> [!NOTE]
>
> **Why Nodemailer?** Node.js doesn't have built-in SMTP support, but Nodemailer provides a powerful, well-maintained solution with extensive features including HTML emails, attachments, embedded images, and robust error handling.

## Prerequisites

Before sending, [verify your domain](https://ahasend.com/docs/domains.md) and [create an SMTP credential](https://ahasend.com/docs/smtp/credentials.md). Use a [sandbox credential](https://ahasend.com/docs/send-api/sandbox.md) for these examples so no email is delivered. Keep the username and password in your server's secret store.

Before you begin, ensure you have:

> [accordion] System Requirements
>
> * **Node.js installed** on your system ([Download Node.js](https://nodejs.org/))
> * **npm** or **yarn** package manager
> * Basic knowledge of JavaScript and Node.js

## Installation

Install Nodemailer in your Node.js project:

```bash npm theme={null}
npm install nodemailer
```

```bash yarn theme={null}
yarn add nodemailer
```

```bash pnpm theme={null}
pnpm add nodemailer
```

For TypeScript projects, also install type definitions:

```bash TypeScript Support theme={null}
npm install --save-dev @types/nodemailer
```

## Connection Settings

| Setting | Value |
| - | - |
| Host | `send.ahasend.com` |
| Ports with STARTTLS | 25, 587 and 2525 |
| Port with implicit TLS | 465 (TLS from the first byte, also called SSL/TLS or SMTPS) |
| Encryption | Required on every port: STARTTLS on 25, 587 and 2525, implicit TLS on 465 |
| Authentication | AUTH PLAIN after STARTTLS on 25, 587 and 2525; AUTH PLAIN or AUTH LOGIN on 465 |
| Username and password | Your SMTP credential, not an API key |

All message data is stored in the EU. See [SMTP limits](https://ahasend.com/docs/smtp.md#what-are-the-smtp-limits).

## Basic Email Examples

```javascript Plain Text Email theme={null}
const nodemailer = require('nodemailer');

// Create transporter
const transporter = nodemailer.createTransport({
    host: 'send.ahasend.com',
    port: 587,
    requireTLS: true, // Force TLS
    auth: {
        user: 'YOUR_SMTP_USERNAME',
        pass: 'YOUR_SMTP_PASSWORD'
    }
});

// Email options
const mailOptions = {
    from: '"Your Company" <hello@yourdomain.com>',
    to: 'user@example.com',
    subject: 'Welcome to our platform!',
    text: 'Thanks for signing up. We\'re excited to have you!'
};

// Send email
transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log('Error:', error);
    }
    console.log('Email sent successfully!');
    console.log('Message ID:', info.messageId);
});
```

```javascript HTML Email theme={null}
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
    host: 'send.ahasend.com',
    port: 587,
    requireTLS: true,
    auth: {
        user: 'YOUR_SMTP_USERNAME',
        pass: 'YOUR_SMTP_PASSWORD'
    }
});

const mailOptions = {
    from: '"Your Company" <hello@yourdomain.com>',
    to: 'user@example.com',
    subject: 'Welcome to our platform!',
    html: `
        <html>
        <body>
            <h1>Welcome!</h1>
            <p>Thanks for signing up. We're <strong>excited</strong> to have you!</p>
            <p><a href="https://yourdomain.com/get-started">Get Started</a></p>
        </body>
        </html>
    `,
    text: 'Welcome! Thanks for signing up. Visit https://yourdomain.com/get-started to get started.' // Fallback
};

transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log('Error:', error);
    }
    console.log('HTML email sent successfully!');
    console.log('Message ID:', info.messageId);
});
```

```javascript With Attachments theme={null}
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
    host: 'send.ahasend.com',
    port: 587,
    requireTLS: true,
    auth: {
        user: 'YOUR_SMTP_USERNAME',
        pass: 'YOUR_SMTP_PASSWORD'
    }
});

const mailOptions = {
    from: '"Your Company" <hello@yourdomain.com>',
    to: 'user@example.com',
    subject: 'Your Invoice is Ready',
    html: `
        <html>
        <body>
            <h1>Invoice Attached</h1>
            <p>Please find your invoice attached to this email.</p>
        </body>
        </html>
    `,
    attachments: [
        {
            filename: 'invoice.pdf',
            path: '/path/to/invoice.pdf'
        },
        {
            filename: 'terms.pdf',
            path: '/path/to/terms.pdf'
        }
    ]
};

transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log('Error:', error);
    }
    console.log('Email with attachments sent successfully!');
    console.log('Message ID:', info.messageId);
});
```

> [!TIP]
>
> **Pro Tip:** Use [connection pooling](https://nodemailer.com/smtp/pooled/) for bulk emails, always provide both HTML and text versions, and implement proper error handling with retry logic. Start with sandbox mode during development and use environment variables for credentials.

## Testing with Sandbox Mode

Use sandbox mode to safely test your Node.js email integration:

```javascript Sandbox Test theme={null}
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
    host: 'send.ahasend.com',
    port: 587,
    requireTLS: true,
    auth: {
        user: 'YOUR_SMTP_USERNAME',
        pass: 'YOUR_SMTP_PASSWORD'
    }
});

const mailOptions = {
    from: '"Test Sender" <test@yourdomain.com>',
    to: 'test@example.com',
    subject: 'Sandbox Test Email',
    headers: {
        'AhaSend-Sandbox': 'true',
        'AhaSend-Sandbox-Result': 'deliver'
    },
    text: 'This email is sent in sandbox mode for testing.'
};

transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log('Error:', error);
    }
    console.log('Sandbox email sent successfully!');
    console.log('Message ID:', info.messageId);
});
```

```javascript Sandbox Bounce Test theme={null}
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
    host: 'send.ahasend.com',
    port: 587,
    requireTLS: true,
    auth: {
        user: 'YOUR_SMTP_USERNAME',
        pass: 'YOUR_SMTP_PASSWORD'
    }
});

const mailOptions = {
    from: '"Test Sender" <test@yourdomain.com>',
    to: 'test@example.com',
    subject: 'Sandbox Bounce Test',
    headers: {
        'AhaSend-Sandbox': 'true',
        'AhaSend-Sandbox-Result': 'bounce'
    },
    html: `
        <html>
        <body>
            <h1>Bounce Test</h1>
            <p>This email simulates a bounce for webhook testing.</p>
        </body>
        </html>
    `
};

transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log('Error:', error);
    }
    console.log('Sandbox bounce test sent - check webhooks!');
    console.log('Message ID:', info.messageId);
});
```

```javascript Async/Await Pattern theme={null}
const nodemailer = require('nodemailer');

async function sendSandboxEmail() {
    const transporter = nodemailer.createTransport({
        host: 'send.ahasend.com',
        port: 587,
        requireTLS: true,
        auth: {
            user: 'YOUR_SMTP_USERNAME',
            pass: 'YOUR_SMTP_PASSWORD'
        }
    });

    const mailOptions = {
        from: '"Test Sender" <test@yourdomain.com>',
        to: 'test@example.com',
        subject: 'Async Sandbox Test',
        headers: {
            'AhaSend-Sandbox': 'true',
            'AhaSend-Sandbox-Result': 'deliver'
        },
        text: 'Testing with async/await pattern.'
    };

    try {
        const info = await transporter.sendMail(mailOptions);
        console.log('Async sandbox email sent successfully!');
        console.log('Message ID:', info.messageId);
        return info;
    } catch (error) {
        console.error('Failed to send sandbox email:', error);
        throw error;
    }
}

sendSandboxEmail();
```

> [!NOTE]
>
> **Sandbox Benefits:** Emails sent in sandbox mode are free, trigger webhooks normally, and never actually deliver to recipients - perfect for development and testing.

## Environment Variables & Best Practices

### Using Environment Variables

```javascript Nodemailer with environment variables theme={null}
const nodemailer = require('nodemailer');
require('dotenv').config(); // npm install dotenv

for (const name of ['SMTP_USERNAME', 'SMTP_PASSWORD', 'FROM_EMAIL']) {
    if (!process.env[name]) throw new Error(`${name} is required`);
}

const transporter = nodemailer.createTransport({
    host: process.env.SMTP_HOST || 'send.ahasend.com',
    port: parseInt(process.env.SMTP_PORT) || 587,
    requireTLS: true,
    auth: {
        user: process.env.SMTP_USERNAME,
        pass: process.env.SMTP_PASSWORD
    }
});

const mailOptions = {
    from: { name: process.env.FROM_NAME || "Your Company", address: process.env.FROM_EMAIL },
    to: 'user@example.com',
    subject: 'Environment Test',
    text: 'This email uses environment variables for configuration.'
};

transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log('Error:', error);
    }
    console.log('Email sent using environment variables!');
});
```

```ini .env configuration theme={null}
# SMTP Configuration
SMTP_HOST=send.ahasend.com
SMTP_PORT=587
SMTP_USERNAME=your_smtp_username
SMTP_PASSWORD=your_smtp_password

# Email Configuration
FROM_NAME=Your Company
FROM_EMAIL=hello@yourdomain.com
```

## Resources

> [card] [Nodemailer Documentation](https://nodemailer.com/)
>
> Official Nodemailer documentation and examples

> [card] [AhaSend Support](mailto:support@ahasend.com)
>
> Get help from our engineering team

## Related Guides

* Before sending: [verify your domain](https://ahasend.com/docs/domains.md) and [create an SMTP credential](https://ahasend.com/docs/smtp/credentials.md).
* Connection and message rules: [SMTP hosts, ports and limits](https://ahasend.com/docs/smtp.md), [special headers](https://ahasend.com/docs/smtp/special-headers.md), [sandbox mode](https://ahasend.com/docs/send-api/sandbox.md), [retention](https://ahasend.com/docs/retention.md) and [plan features](https://ahasend.com/docs/facts.md#plans-and-features).
* Other ways to send: [REST API](https://ahasend.com/docs/send-api/send-email.md), [AhaSend CLI](https://ahasend.com/docs/cli/quickstart.md), [Node.js SDK](https://ahasend.com/docs/guides/nodejs-sdk.md) and [Go SDK](https://ahasend.com/docs/guides/go-sdk.md).
* Delivery events: [webhook setup](https://ahasend.com/docs/integrations/webhooks.md) and [local webhook testing](https://ahasend.com/docs/cli/webhook-testing.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.