Mailgun email delivery not working with Node.js

I’m having trouble getting my contact form to send emails using Node.js Express and the mailgun-js library. The API credentials work fine when I test them with the official examples, but my implementation doesn’t seem to work. Can someone help me figure out what’s wrong?

Email service module:

const API_KEY = 'my-secret-key';
const MAIL_DOMAIN = 'my-domain.com';

const MailgunAPI = require('mailgun-js');

exports.deliverEmail = function (formData, done) {
    console.log(formData);
    const mailService = new MailgunAPI({apiKey: API_KEY, domain: MAIL_DOMAIN});
    
    const emailData = {
        from: '[email protected]',
        to: '[email protected]',
        subject: 'New Contact Form',
        text: 'Someone filled out the contact form!'
    };
    
    mailService.messages().send(emailData, function (error, response) {
        if(error) return done(error);
        console.log('email delivered');
        done(null, response);
    });
};

Route handler:

const emailService = require('../services/email');

exports.showContactPage = function (req, res, next) {
    res.render('contact-form');
};

exports.handleFormSubmit = function (req, res, next) {
    emailService.deliverEmail(req.body, function (error, result) {
        if(error) return next(error);
        console.log(result);
        res.json({status: 'Message sent successfully'});
    });
};

Any ideas what might be going wrong here?

hey there! I had a similar problem. maybe your Api key or domain is wrong? double-check those settings. also, try console logging the full response from Mailgun, it might give you clues about what’s going wrong!

Had this exact problem a few months back. You’re probably not using the actual form data in your email - your emailData object just has hardcoded text instead of pulling from the contact form. Mailgun might be silently failing or flagging it as spam since the content’s too generic. Try adding the real form fields to your email body: text: 'Name: ' + formData.name + ', Email: ' + formData.email + ', Message: ' + formData.message. Also check that your domain’s verified in Mailgun’s dashboard - unverified domains fail silently all the time without giving you proper error messages.

Check your environment variables and CORS setup first. I hit this same issue - my API_KEY and MAIL_DOMAIN worked locally but weren’t loading properly in production. Use process.env.MAILGUN_API_KEY instead of hardcoding values. Body-parser is another common problem. If it’s not configured right, req.body comes back empty and Mailgun has nothing to send. Drop some console.log statements in your handleFormSubmit function to make sure the route’s actually getting hit. Sometimes the form posts to the wrong endpoint and you won’t see any errors in the Mailgun callback.