Getting 401 unauthorized error when sending emails with Mailgun API

I keep receiving a 401 unauthorized error while attempting to send emails using Mailgun API in my NestJS app. I’ve verified my API keys and domain configurations, yet the issue continues. Below is my email service code implementation:

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

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

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

  sendEmail(emailData: IEmailData): Promise<MailgunJS.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 configuration for my client shows:

Mailgun {
  username: 'api',
  apiKey: '3a5f7829db970c6e92f8bc63e27xxx-xxx-xxx',
  domain: 'my-domain.com',
  auth: 'api:3a5f7829db970c6e92f8bc63e27xxx-xxx-xxx',
  host: 'api.mailgun.net',
  endpoint: '/v3',
  protocol: 'https:',
  port: 443
}

Here is the email data that I am attempting 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 the cause of this authorization error?

Had this same issue last month with my NestJS project. You’re probably using the wrong API key - I was using the private key instead of the domain-specific sending key. Go to Settings > API Keys in your Mailgun dashboard and grab the one that starts with ‘key-’, not ‘pubkey-’. Also check that your domain authentication is actually finished - your from address needs to match exactly with whatever domain you verified in Mailgun. If you’re still testing, just use their sandbox domain first to figure out if it’s an auth problem.

check if ur using the right mailgun region - eu users need api.eu.mailgun.net instead of api.mailgun.net. also make sure the domain is actually verified in ur mailgun dashboard, sometimes it takes a while to propagate

Double check your environment variables are loading properly. I hit this same issue and wasted hours debugging the API key when my ConfigService was just returning undefined values. Add some logging to see what your config.get() methods actually return - you might be surprised. If you’re using containers, make sure your env vars are getting passed through. That 401 error is misleading since Mailgun throws it for any auth failure, even when the API key is empty or malformed.