# Keep your Gmail

> Keep your Gmail or Google Workspace inbox and forward mail to an agent’s Pidgeon address: Gmail forwarding and filters, Workspace routing, confirming the forward from the agent, and how replies work.

Your mail can stay in Gmail or Google Workspace while an agent reads it. Gmail
forwards a copy to the agent's Pidgeon address, and the agent reads and answers
it there. Nothing moves: your MX records, your Gmail and its history stay where
they are.

It works because Pidgeon routes on the envelope recipient, not the `To:`
header. A forwarded message still says `To: you@gmail.com`, but it is
delivered to the agent's address under its original sender.

## Before you start

You need an address for the agent ([Addresses](https://pidgeon.ai/docs/addresses.md)). If that
address accepts only its allow list, add `forwarding-noreply@google.com` to
the list first, or the confirmation below is refused. The details are under
[Allow lists](#allow-lists).

## From Gmail

Automatic forwarding is set up in Gmail on a computer. The Gmail app has no
setting for it.

1. **Settings → See all settings → Forwarding and POP/IMAP → Add a forwarding
   address.** Enter the agent's address, then **Next → Proceed → OK**.
2. Gmail sends a confirmation to the agent's address. Confirm it
   ([Confirm the forward](#confirm-the-forward)).
3. Back in Gmail, refresh the page and open **Forwarding and POP/IMAP** again.
   Choose **Forward a copy of incoming mail to**, pick the agent's address,
   choose what happens to Gmail's copy (**Keep Gmail's copy in the Inbox**
   keeps your inbox as it was), and **Save Changes**.

Gmail forwards new mail only, and never what it has filed as spam. An account
has one automatic forwarding address.

### Only some of your mail

A filter forwards the messages that match it and nothing else. Set up the
forwarding address with steps 1 and 2 first, leave automatic forwarding off,
then:

1. In the search box, open **Show search options** and enter what to match:
   a sender, a domain, words in the subject.
2. **Create filter → Forward it**, choose the agent's address, and **Create
   filter**.

A filter forwards mail that arrives after you create it, not the mail already
in your inbox. One filter forwards to one address.

## From Google Workspace

People in a Workspace organisation set it up from Gmail, as above, unless an
administrator has turned it off. The setting is under **Admin console → Apps →
Google Workspace → Gmail → End User Access → Automatic forwarding**, and it can
also be limited to addresses inside the organisation.

An administrator can send a copy without anybody confirming anything:

- **Default routing** (**Apps → Google Workspace → Gmail → Default routing**):
  match the recipients, then under **Modify message** choose **Add more
  recipients** and add the agent's address. The original still reaches the
  Gmail inbox.
- **A recipient address map** (**Gmail → Routing**) maps one address to
  another. Tick **Also route to original destination**, or Gmail stops
  delivering to the original.

Google says routing changes take up to 24 hours.

## Confirm the forward

Gmail's confirmation arrives at the agent's address from
`forwarding-noreply@google.com`, with a subject that reads
`Gmail Forwarding Confirmation - Receive Mail from you@gmail.com`. It holds two
links and no code: one confirms the forward, the other cancels it.

The agent can wait for it and read the confirming link out of `extracted`:

```bash
curl -G https://pidgeon.ai/api/v1/messages/await \
-H "Authorization: Bearer $PIDGEON_API_KEY" \
-d identity_id=$IDENTITY_ID \
-d from=forwarding-noreply@google.com \
-d has_code=true \
-d timeout=120
```

```ts
const { data } = await messagesAwait({
query: {
  identity_id: identityId,
  from: 'forwarding-noreply@google.com',
  has_code: 'true',
  timeout: 120,
},
throwOnError: true,
});

const confirm = data.data.message?.extracted.links.find((link) => link.kind === 'verification');
```

```python
answer = httpx.get(
  "https://pidgeon.ai/api/v1/messages/await",
  params={
      "identity_id": identity_id,
      "from": "forwarding-noreply@google.com",
      "has_code": "true",
      "timeout": 120,
  },
  headers={"Authorization": f"Bearer {api_key}"},
  timeout=130,
).json()["data"]

confirm = next(
  link for link in answer["message"]["extracted"]["links"] if link["kind"] == "verification"
)
```

`has_code` counts a verification link as well as a code, so it waits past
anything else that arrives first. The confirming link is the only one marked
`verification`; the cancelling link comes back as `other`. Open the confirming
link in a browser and confirm. An agent with a browser tool can do it itself;
otherwise send the link to the person who owns the Gmail account.

Over MCP it is `await_message` with the same `from` and `has_code`.

Google signs the confirmation, so it passes DMARC and the `from` filter
matches it ([Verification codes](https://pidgeon.ai/docs/verification-codes.md) says why a `from`
match needs DMARC).

## What the agent sees

A forwarded message reads like any other, except that the `To:` is your Gmail:

```json
{
"from": { "email": "maria@northwind.example", "name": "Maria Lopez" },
"to": [{ "email": "you@gmail.com" }],
"delivered_to": "agent@yourdomain.com",
"subject": "Contract renewal for 2027",
"authentication": { "spf": "pass", "dkim": "pass", "dmarc": "pass" },
"origin": "smtp"
}
```

`from` is the person who wrote, not you, so the agent answers them and sender
rules match them. Message IDs survive the forward, so a forwarded reply joins
the thread it answers.

### Authentication on a forward

SPF is checked against whoever handed the message to Pidgeon, which on a
forward is Google rather than the original sender. Gmail rewrites the envelope
to your Gmail address, so SPF passes for `gmail.com`, not for the sender's
domain. DKIM is the original sender's signature, and a forward that does not
change the message keeps it intact. So DMARC passes when the sender signed
with its own domain, which most large senders do, and fails when it signed
nothing.

Pidgeon does not read ARC, the headers Google adds to vouch for what it
checked before forwarding. A message that fails DMARC here is not rescued by
Google having seen it pass.

What a failed DMARC changes:

- **`await_message` with `from`** holds the message back in
  `held_back.unauthenticated` unless you pass `include_unauthenticated: true`.
- **Spam:** a failed check counts against a message. A sender rule that says
  **Never mark it as spam** overrules that only when DMARC passed.
- **Allow lists:** below.

In the dashboard, a message whose SPF, DKIM or DMARC failed is also listed
under **Unauthenticated**. A Workspace copy whose SPF failed is listed there
even when DMARC passed.

### Allow lists

An address set to accept only its allow list
([Allow and block lists](https://pidgeon.ai/docs/rules.md)) judges a forward by its original
sender:

- List the people who write to you, not your Gmail address. Listing
  `you@gmail.com` lets nothing in, because no forwarded message is from it.
- A listed sender gets in only when DMARC passes. Mail forwarded from a domain
  that signs nothing is refused, even from somebody on the list.
- List `forwarding-noreply@google.com` before you add the forwarding address,
  or Gmail's confirmation is refused.

## Answering

The agent answers as its own address. The person who wrote sees a reply from
`agent@yourdomain.com`, not from your Gmail, and you are not copied unless the
agent adds you. Pidgeon cannot send as `you@gmail.com`: it does not hold
Google's signing keys, so that mail would fail DMARC, and an address sends
only as itself or an address routed to it.

Gmail's **Send mail as** goes the other way. It lets you answer from Gmail as
the agent's address, through Pidgeon:

1. In Pidgeon, create an app password for the address
   ([IMAP and SMTP](https://pidgeon.ai/docs/mail-clients.md#app-passwords)).
2. In Gmail: **Settings → See all settings → Accounts and import → Send mail
   as → Add another email address.** Enter the agent's address.
3. Give Gmail the SMTP server, below.
4. Gmail sends a verification link to the agent's address. Read it the same
   way as the forwarding confirmation, and open it.

```text
SMTP server   smtp.pidgeon.ai
Port          465, SSL
Username      the agent's full address
Password      the app password
```

What it costs: the app password lives in your Google account, and it can
read the agent's inbox and send as its address. Revoke it in Pidgeon and Gmail
can no longer send as the agent. Mail you send this way counts against the
address's daily sending limit, and a reply you send in a thread the agent was
answering hands that thread to you.

Answering as your Workspace address, `support@acme.com` rather than the
agent's own, is not built yet. Today the agent answers as its Pidgeon address.
