> ## Documentation Index
> Fetch the complete documentation index at: https://pigeonpost-developer.27communication.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Gmail and Google Workspace (IMAP)

> Connect Gmail and Google Workspace mailboxes over IMAP and SMTP with an app password: what the user needs, how to connect, Gmail's behaviour and limits, and troubleshooting.

Gmail and Google Workspace mailboxes connect over **IMAP and SMTP**, signed in with a Google **app password**. The engine then syncs the mailbox like any IMAP account: new mail arrives in seconds, sending goes through Gmail's SMTP server, and every change sends its webhook.

<Info>
  **At a glance**

  * **Sign-in:** the user's Gmail address plus a 16-character **app password**. Their normal Google password doesn't work.
  * **Requires:** 2-Step Verification on the Google account. For Google Workspace, the admin must allow IMAP and app passwords.
  * **Servers** are filled in automatically for `@gmail.com` and `@googlemail.com`. For Workspace (custom domains), use `imap.gmail.com` and `smtp.gmail.com`.
  * **"Continue with Google"** (Google sign-in) isn't offered. Gmail always connects with an app password.
</Info>

## How a user signs in to Gmail

| Method | Works? | Notes |
| - | - | - |
| Normal Google password | ❌ | Google turned off password sign-in for IMAP ("less secure apps") for every account |
| **App password** | ✅ **This guide** | A separate 16-character password for one app. Needs 2-Step Verification. The user can revoke it at any time |
| Google sign-in (OAuth) | Not offered | Not available on this platform |

An app password only works for mail (IMAP and SMTP). It can't be used to sign in to the Google account, change settings or see other Google data. Revoking it disconnects only this integration.

## Step 1: Turn on 2-Step Verification (the user)

App passwords exist only for accounts with 2-Step Verification.

1. Open [myaccount.google.com/security](https://myaccount.google.com/security).
2. Under **How you sign in to Google**, open **2-Step Verification** and turn it on (a phone, an authenticator app or a security key).

<Note>
  Accounts in Google's **Advanced Protection Program** can't create app passwords, so they can't connect over IMAP.
</Note>

## Step 2: Create an app password (the user)

1. Open [myaccount.google.com/apppasswords](https://myaccount.google.com/apppasswords). Google may ask for the password again.
2. Type a name that says where it's used, for example **"CRM mailbox sync"**, and click **Create**.
3. Google shows a **16-character password** (four groups of four letters), only once. Copy it, and enter it **without the spaces**.
4. Use it in [Step 3](#step-3-connect-the-mailbox) instead of the normal password.

If **App passwords** doesn't appear, see [Troubleshooting](#troubleshooting).

## Step 2b: Google Workspace (company accounts, the admin)

For a mailbox on a company domain (`ana@acme.com` run by Google), the company's Google Workspace admin must allow it once, in the [Google Admin console](https://admin.google.com):

| Setting | Where | Value |
| - | - | - |
| IMAP access | **Apps → Google Workspace → Gmail → End User Access → POP and IMAP access** | **Enable IMAP access** for the users (or organizational unit) who connect |
| 2-Step Verification | **Security → Authentication → 2-Step Verification** | **Allow users to turn on 2-Step Verification** |
| App passwords | Allowed with 2-Step Verification, unless the org enforces **security keys only** or **Advanced Protection** | If either is enforced, those users can't create app passwords |

Then each user does Steps 1 and 2 for their own account. Changes in the Admin console can take up to 24 hours to apply.

## Step 3: Connect the mailbox

### With the API

Your app asks the user for the Gmail address and the app password, then sends them with [`POST /api/v1/auth/intent`](/accounts/imap).

<CodeGroup>
  ```bash Gmail (@gmail.com) theme={null}
  curl -X POST "$EE_URL/api/v1/auth/intent" \
    -H "X-API-KEY: $EE_KEY" -H "Content-Type: application/json" \
    -d '{
      "provider": "imap",
      "email": "ana@gmail.com",
      "password": "abcdefghijklmnop",
      "state": "user-42"
    }'
  ```

  ```bash Google Workspace theme={null}
  curl -X POST "$EE_URL/api/v1/auth/intent" \
    -H "X-API-KEY: $EE_KEY" -H "Content-Type: application/json" \
    -d '{
      "provider": "imap",
      "email": "ana@acme.com",
      "password": "abcdefghijklmnop",
      "imap_host": "imap.gmail.com", "imap_port": 993,
      "smtp_host": "smtp.gmail.com", "smtp_port": 465,
      "state": "user-42"
    }'
  ```
</CodeGroup>

* **`@gmail.com` and `@googlemail.com` addresses:** the address and the app password are enough. The server settings are filled in for you.
* **Workspace addresses:** pass `imap.gmail.com` and `smtp.gmail.com` ([below](#server-settings)).

The engine signs in to both servers before saving anything. The response is the account (`201`), and an `account.add` event is sent with your `state`. If Google rejects the password, the answer is `401 errors/invalid_credentials` and nothing is saved. Show your user a reminder to use an app password, not their normal Google password.

To also import recent mail, add an [initial sync](/accounts/initial-sync): `"config": { "initial_sync_enable": true, "initial_sync_days": 30 }`.

### From the dashboard

In the dashboard, open **Accounts → Add account**, enter the Gmail address and the app password, and save. For Workspace addresses, also enter `imap.gmail.com` and `smtp.gmail.com` in the server settings. See [From the dashboard](/accounts/imap#from-the-dashboard).

### Server settings

| | Server | Port | Security |
| - | - | - | - |
| Incoming (IMAP) | `imap.gmail.com` | `993` | `SSL` |
| Outgoing (SMTP) | `smtp.gmail.com` | `465` | `SSL` |
| Username | The full email address | | |
| Password | The app password | | |

SMTP on port `587` with `STARTTLS` works too.

## How Gmail behaves over IMAP

### Labels are folders

Gmail has **labels**, not folders. Over IMAP, Gmail shows each label as a folder:

| Gmail | Folder in the API | `role` |
| - | - | - |
| Inbox | `INBOX` | `INBOX` |
| Sent | `[Gmail]/Sent Mail` | `SENT` |
| Drafts | `[Gmail]/Drafts` | `DRAFTS` |
| Spam | `[Gmail]/Spam` | `SPAM` |
| Trash (Bin) | `[Gmail]/Trash` | `TRASH` |
| Your labels, e.g. `Clients` | `Clients` | `UNKNOWN` |
| All Mail, Starred, Important | Not synced: they're views of the folders above | — |

<Warning>
  **An email with several labels is synced once per label.** For example, an email in the Inbox that also has the label `Clients` appears twice in the API, once in each folder, with two `email.new` events. Both share the same `message_id`, so you can group them. Emails with only one label (the usual case for the Inbox) appear once.

  To avoid copies, users can hide labels from IMAP: Gmail **Settings → Labels → Show in IMAP**, unticked for labels you don't need.
</Warning>

### Moving, archiving and deleting

* **Moving** to a folder through the API (`PATCH /emails/{id}` with `folder`) moves it in Gmail: that label is added and the old one removed.
* **Archiving** in Gmail removes the Inbox label. Over IMAP the email leaves `INBOX`, so you get `email.delete` for the Inbox copy. It's still in Gmail's All Mail, which isn't synced.
* **Deleting** through the API (`DELETE /emails/{id}`) moves it to `[Gmail]/Trash`, and you get `email.update` with `role: "TRASH"`. Gmail empties the Trash after 30 days.

### Sending

Emails sent through the API go out through `smtp.gmail.com` from the user's address. **Gmail saves the copy in Sent Mail itself**, so the engine doesn't save a second one. The copy then syncs back with `email.new` and `role: "SENT"`. To send from another address, it must be set up in Gmail as a **"Send mail as"** alias.

### Real-time

The engine keeps an IMAP IDLE connection on the **Inbox**, so new mail there arrives within **a few seconds**. Other folders (Sent, labels, Spam) are checked every **30 seconds**, and **Sync now** checks at once.

## Gmail limits

| Limit | Value (Google's, subject to change) | What happens |
| - | - | - |
| Sending | **500 recipients a day** (Gmail), **2,000 a day** (Google Workspace) | Gmail refuses further sends until the next day; the API answers with an error carrying Gmail's message |
| Email size | **25 MB** in total, attachments included | Larger emails are refused |
| IMAP connections | **15** at once per account, shared with the user's other email apps | Too many apps on the same account can block new connections |
| IMAP download | About **2.5 GB a day** per account | A very large [initial sync](/accounts/initial-sync) can hit it. Gmail then refuses downloads until the next day, and after 5 failed tries the import ends as `failed` (what it imported stays, and new mail keeps syncing) |

## Security

* The app password is **encrypted** in the engine's database and is never returned by the API or written to logs.
* **To disconnect,** delete the account (`DELETE /api/v1/accounts/{id}`) and, as the user, revoke the app password at [myaccount.google.com/apppasswords](https://myaccount.google.com/apppasswords).
* **Changing the Google account password revokes every app password.** The account then becomes `disconnected`. The user creates a new app password, and you send it with the account's `account_id` ([Reconnect or change settings](/accounts/imap#reconnect-or-change-settings)), or a workspace admin enters it with **Update connection** on the account's page in the dashboard.

## Troubleshooting

| Problem | Cause | Fix |
| - | - | - |
| "The server rejected the email or password" | The normal password was used, or the app password has a typo or was revoked | Create a new app password (Step 2) and use it |
| **App passwords** page says the setting isn't available | 2-Step Verification is off, or the account uses Advanced Protection or security keys only | Turn on 2-Step Verification (Step 1). With Advanced Protection, Gmail can't connect over IMAP |
| Workspace user: "IMAP access is disabled" or sign-in refused | The admin hasn't enabled IMAP, or blocks app passwords | The admin changes the settings in [Step 2b](#step-2b-google-workspace-company-accounts-the-admin) |
| Account becomes `disconnected` later | The user changed their Google password, or revoked the app password | The user creates a new app password; send it with the account's `account_id` ([reconnect](/accounts/imap#reconnect-or-change-settings)), or use **Update connection** in the dashboard |
| Same email twice in the API | It has two labels (e.g. Inbox + `Clients`) | Expected over IMAP ([above](#labels-are-folders)); group by `message_id`, or hide the label from IMAP |
| Sending fails with Gmail's message | Gmail's daily sending limit or size limit | Wait until the next day, or send smaller emails |
| A folder is missing | The label is hidden from IMAP in Gmail settings | Gmail **Settings → Labels → Show in IMAP** |

## See also

* [Connect a mailbox](/accounts/imap): every setting, and other providers
* [Initial sync](/accounts/initial-sync): import the last 30 days when connecting
* [Account status](/accounts/status): `running`, `errored`, `disconnected`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.