Getting 401 unauthorized error when sending emails with Mailgun API

I’m having trouble sending emails through Mailgun in my Node.js application. Every time I try to send an email, I get a 401 unauthorized error. I’m using NestJS framework and here’s my email service implementation:

import { Injectable } from '@nestjs/common';
import * as MailgunSDK from 'mailgun-js';
import { IEmailData } from './interfaces/email.interface';
import { ConfigService } from '../config/config.service';

@Injectable()
export class EmailService {
  private mailgunClient: MailgunSDK.Mailgun;

  constructor(private readonly configService: ConfigService) {
    this.mailgunClient = MailgunSDK({
      apiKey: this.configService.get('MAILGUN_KEY'),
      domain: this.configService.get('MAILGUN_DOMAIN'),
    });
  }

  sendEmail(emailData: IEmailData): Promise<MailgunSDK.messages.SendResponse> {
    console.log(emailData);
    console.log(this.mailgunClient);
    return new Promise((resolve, reject) => {
      this.mailgunClient.messages().send(emailData, function (err, response) {
        if (err) {
          console.log(err);
          reject(err);
        }
        resolve(response);
      });
    });
  }
}

The client configuration looks correct when I log it:

Mailgun {
  username: 'api',
  apiKey: 'key-abc123def456ghi789jkl012mnp345-qrs-tuv',
  domain: 'my-website.com',
  auth: 'api:key-abc123def456ghi789jkl012mnp345-qrs-tuv',
  host: 'api.mailgun.net',
  endpoint: '/v3',
  protocol: 'https:',
  port: 443
}

And here’s the email data I’m trying to send:

{
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Account Verification',
  html: '<h3>Hello [email protected]!</h3><p>Please verify your account.</p>'
}

What could be causing this 401 error? I’ve double checked my API key and domain settings but still getting the same forbidden message.

I encountered the same 401 unauthorized error with Mailgun while using NestJS. The initial step is to ensure your API key begins with ‘key-’ and verify that you are utilizing the private key rather than the public one. Additionally, confirm that the domain specified in Mailgun exactly matches the one in your application. If you are including a subdomain in the ‘from’ field, it must be included in your authorized recipients list. Start by testing with just the primary verified domain for better results. Remember, if you’re operating in sandbox mode, you can only send emails to recipients listed in your Mailgun dashboard.

Check your Mailgun region first - if you’re on EU servers, switch the host to ‘api.eu.mailgun.net’ instead of the default. Also verify your domain is actually verified in the Mailgun dashboard. Sometimes it looks fine but verification fails without any error message.

401 errors usually come from environment variable problems that aren’t obvious. Had this exact issue - my env vars weren’t loading in production even though they worked locally. Log your ConfigService values directly, not just the client object, to see what’s actually getting retrieved. Also check for trailing spaces or hidden characters in your env file - they’ll mess things up. Try hardcoding the API key temporarily to figure out if it’s a config issue or actual auth problem. And heads up - some hosting platforms make you restart the app after updating env vars, which got me during deployment.