> ## 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 in the EU, or send-us.ahasend.com as a US connection point forwarding to the EU. 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.

<Info>
  **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.
</Info>

## Prerequisites

Before sending, [verify your domain](/docs/domains) and [create an SMTP credential](/docs/smtp/credentials). Use a [sandbox credential](/docs/send-api/sandbox) 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:

<AccordionGroup>
  <Accordion title="System Requirements" icon="server">
    * **Node.js installed** on your system ([Download Node.js](https://nodejs.org/))
    * **npm** or **yarn** package manager
    * Basic knowledge of JavaScript and Node.js
  </Accordion>
</AccordionGroup>

## Installation

Install Nodemailer in your Node.js project:

<CodeGroup>
  ```bash npm theme={null}
  npm install nodemailer
  ```

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

  ```bash pnpm theme={null}
  pnpm add nodemailer
  ```
</CodeGroup>

For TypeScript projects, also install type definitions:

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

## Connection Settings

| Setting | Value |
| - | - |
| EU host | `send.ahasend.com` |
| US connection point | `send-us.ahasend.com`; accepts SMTP and forwards it to the EU |
| Ports | 25, 587 and 2525 |
| Encryption | STARTTLS required on every supported port |
| Authentication | AUTH PLAIN only after STARTTLS |
| Username and password | Your SMTP credential, not an API key |
| Port 465 | Implicit TLS is not supported |

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

## Basic Email Examples

<CodeGroup>
  ```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);
  });
  ```
</CodeGroup>

<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.
</Tip>

## Testing with Sandbox Mode

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

<CodeGroup>
  ```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();
  ```
</CodeGroup>

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

## Environment Variables & Best Practices

### Using Environment Variables

<CodeGroup>
  ```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
  ```
</CodeGroup>

## Resources

<CardGroup cols={2}>
  <Card title="Nodemailer Documentation" icon="book" href="https://nodemailer.com/">
    Official Nodemailer documentation and examples
  </Card>

  <Card title="AhaSend Support" icon="life-ring" href="mailto:support@ahasend.com">
    Get help from our engineering team
  </Card>
</CardGroup>

## Related Guides

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


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