# Set up email forwarding

Forward an address at a domain (`info@example.com`) to a mailbox the person
already has (`me@gmail.com`). Mail sent to the address arrives in that mailbox.
It is free, up to 20 forwards per domain. Forwarding only receives: replies come
from the destination mailbox's own address.

Over MCP the tools are `list_email_forwards`, `create_email_forward` and
`delete_email_forward`; over the API, the three `/email/...Forward` endpoints
below. The domain must be in the account, active, and opted in to API access.

## 1. See what is there

```bash
curl 'https://api.porkbun.com/api/json/v3/email/getForwards/example.com' \
  -H 'X-API-Key: pk1_...' -H 'X-Secret-API-Key: sk1_...'
# -> { "status":"SUCCESS", "forwards":[{"address":"info@example.com","forwardTo":"me@gmail.com","created":"..."}],
#      "limits":{"used":1,"max":20}, "dnsConfigured":true }
```

One address can forward to several mailboxes, so a forward is the pair of
`address` and `forwardTo`.

## 2. Preview, then add

Forwarding needs Porkbun's mail servers in the domain's MX records
(`fwd1.porkbun.com` priority 10, `fwd2.porkbun.com` priority 20) and
`include:_spf.porkbun.com` in its SPF record, at the apex. Adding a forward sets
those up. Preview first:

```bash
curl -X POST https://api.porkbun.com/api/json/v3/email/addForward/example.com \
  -H 'Content-Type: application/json' \
  -d '{"apikey":"pk1_...","secretapikey":"sk1_...","address":"info","forwardTo":"me@gmail.com","dryRun":true}'
```

`dnsChanges` in the answer says what will happen to the zone:

- `mxRecordsRemoved`: MX records at the apex that are not Porkbun's. **They are
  deleted.** If the domain already receives mail somewhere else (Google
  Workspace, Microsoft 365, Fastmail, a mailbox at another host), that service
  stops receiving mail for the whole domain. MX records on subdomains are left
  alone.
- `spf`: `set` (Porkbun's SPF record is added), `merge` (Porkbun's include is
  added to the existing SPF record; `spfBefore` and `spfAfter` show both),
  `unchanged` (already there), or `unchanged_over_limits` (adding it would push
  the SPF record past 10 lookups or 255 characters, so it is left alone, and
  forwarded mail may fail SPF checks until the person trims it).

`confirmationRequired: true` means the add will stop and ask, because of one of
the first two. Then add it for real:

```bash
curl -X POST https://api.porkbun.com/api/json/v3/email/addForward/example.com \
  -H 'Content-Type: application/json' \
  -d '{"apikey":"pk1_...","secretapikey":"sk1_...","address":"info","forwardTo":"me@gmail.com"}'
```

## 3. When it asks: the person decides

If MX records would be deleted or the SPF record changed, the add returns
`DNS_CHANGE_CONFIRMATION_REQUIRED` with the same `dnsChanges`, and **nothing is
changed**. An agent must not answer this itself:

1. Tell the person what will change, in plain terms. For MX records: "the domain
   currently gets its mail from `aspmx.l.google.com`; setting up forwarding
   replaces that, and mail stops arriving there."
2. If they agree, send the same request with `"confirmDnsChanges": true`.
3. If they don't, stop. Forwarding and their current mail provider cannot share
   the domain apex.

Once Porkbun's records are in place, adding more forwards does not ask again.

## 4. If the domain uses other nameservers

The records above are written to the Porkbun zone. If the domain's nameservers
point elsewhere (check with `/domain/getNs/{domain}`), that zone is not the one
the internet sees, and `dnsConfigured` reflects only the Porkbun zone. The person
(or the agent, with access to that DNS provider) has to add the two MX records
and the SPF include there, or move the domain to Porkbun's nameservers.

## 5. Remove a forward

```bash
curl -X POST https://api.porkbun.com/api/json/v3/email/deleteForward/example.com \
  -H 'Content-Type: application/json' \
  -d '{"apikey":"pk1_...","secretapikey":"sk1_...","address":"info","forwardTo":"me@gmail.com"}'
# -> { "status":"SUCCESS", ..., "dnsRecordsRemoved":false }
```

When the last forward goes and the domain has no Porkbun email hosting mailboxes,
Porkbun's MX and SPF records are removed too (`dnsRecordsRemoved: true`). After
that, mail to the domain is no longer accepted anywhere until other MX records
are set up.

## What cannot be done

| Error | Meaning |
|---|---|
| `WILDCARD_NOT_SUPPORTED` | No catch-all (`*@example.com`). Add each address you want |
| `MAILBOX_EXISTS` | The address is a Porkbun email hosting mailbox; one address cannot be both |
| `FORWARD_LIMIT_REACHED` | The domain is at its limit (`limits`). Delete unused forwards, or ask support for more |
| `DUPLICATE_FORWARD` | That forward already exists; nothing to do |
| `FORWARD_NOT_FOUND` | No forward with that `address` and `forwardTo`. List them first |
| `EMAIL_BLOCKED` | Email services are blocked on this domain; the account holder contacts support |

Mailboxes (Porkbun email hosting) are created on the website; the API only sets
their passwords (`/email/setPassword`).


---

## More

- Guides (how-tos): https://porkbun.com/llms/guides
- Topic index: https://porkbun.com/llms
- Full reference (one file): https://porkbun.com/llms-full.txt
- OpenAPI spec (full schemas): https://porkbun.com/api/json/v3/spec
- Short overview: https://porkbun.com/llms.txt
- Official MCP server: https://porkbun.com/mcp (`npx -y @porkbunllc/mcp-server`)
- Create API keys: https://porkbun.com/account/api
