# Mailgun 401 Forbidden: why the API rejects your key

Mailgun answers 401 with a one-word plain-text body, Forbidden. What we saw on both regions with a fake key, why response.json() then fails, and what to check.

Author: Formgong
Published: 2026-10-16
Language: en
Canonical: https://formgong.com/en/blog/mailgun-401-forbidden/

Mailgun returns 401 Forbidden when it does not accept the API key for that request. Check that the user is api, that the key is current, that you use the EU host api.eu.mailgun.net for a domain created in the EU region, and that a domain sending key is used only for that domain. The body is plain text, so do not parse it as JSON.

## What Mailgun answered

*Figure: A contact form shows an error after Send. The server log shows Mailgun returned 401 with a plain text body Forbidden, and the code's response.json() failed with Unexpected token F.*

On 16.10.2026 we posted a message to `/v3/<domain>/messages` with a made-up key on both of Mailgun's API hosts. Each answered HTTP 401, `content-type: text/plain`, and a body of one word: `Forbidden`. A request with no key at all got the same answer.

Three ways it showed up in code:

- `fetch` plus `response.json()` in Node: `SyntaxError: Unexpected token 'F', "Forbidden" is not valid JSON`. The real problem, the key, is hidden behind a parse error. See [why JSON parse errors look like this](/en/blog/unexpected-token-doctype-is-not-valid-json/).

- `mailgun.js` 14.1.0: an error with `message: "Unauthorized"`, `status: 401` and `details: "Forbidden"`. With the key variable unset it threw `Parameter "key" is required` before sending anything.

- SMTP through `smtp.mailgun.org` with a made-up password: `Invalid login: 535 Authentication failed`.

## What to check

A made-up key cannot tell these apart, because Mailgun gives the same one-word answer for all of them. These are the causes Mailgun's docs describe, in the order worth checking:

- **Region.** A domain created in the EU region lives on `api.eu.mailgun.net`. Calling `api.mailgun.net` for it fails. In `mailgun.js`, pass `url: "https://api.eu.mailgun.net"`.

- **User name.** Basic auth uses the user `api` and the key as the password.

- **Key type.** Mailgun's docs say a domain sending key only allows POST to `/messages` and `/messages.mime`, for the domain it was created for. Other endpoints, or another domain, need the account's API key.

- **A replaced key.** After you create a new key and delete the old one, every place that still has the old one gets 401.

## Do not call Mailgun from the page

Unlike SendGrid, Mailgun's API answered the browser preflight with `Access-Control-Allow-Origin: *` and allowed the `Authorization` header. So a call from front-end code works, and that is the danger: the key is then in your page for anyone to copy, and it can send mail as your domain. Keep the call on a server or in a function.

## Do you need a Mailgun key for a contact form?

If the API key is in your project only so a contact form can email you, a form that posts to [Formgong](/en/) at `https://formgong.com/submit` needs no key from a mail provider, and Formgong sends the notification. See the [HTML guide](/en/docs/html/).

## Frequently asked questions

### Why does Mailgun return 401 Forbidden?

It does not accept the key for that request: the key is wrong or deleted, the user is not api, the domain is in the other region, or a domain sending key is used for something else.

### Why do I get Unexpected token F is not valid JSON from Mailgun?

Mailgun's 401 body is the plain text Forbidden. Calling response.json() on it fails. Check response.ok first and read the error body as text.

### Which Mailgun API URL should I use in the EU?

Domains created in the EU region use api.eu.mailgun.net. Others use api.mailgun.net.

## Sources and documentation

- [Mailgun: API overview (US and EU base URLs)](https://documentation.mailgun.com/docs/mailgun/api-reference/api-overview)
- [Mailgun: Authentication (user api, domain sending keys)](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication)
- [mailgun.js on npm](https://www.npmjs.com/package/mailgun.js)
- [HTML contact form](https://formgong.com/en/docs/html/)

[Get a form key](https://formgong.com/en/#top)
