Skip to main content

Gmail API Scopes Reference

When using EmailEngine with Gmail, you must choose which OAuth2 scopes to request. Google requires applications to follow the principle of least privilege - request only the scopes your application actually needs. The scope selection also determines what Google verification process your application must pass.

This page covers the Gmail scope configurations supported by EmailEngine, what each enables, and how to set them up.

Prerequisites

This page assumes you have already created a Google Cloud project and OAuth2 credentials. If not, see Setting Up Gmail API or Setting Up Gmail with OAuth2 (IMAP/SMTP) first.

Quick Reference

ConfigurationScopesReadSendModify/Move/TrashManage LabelsPub/Sub WebhooksGoogle Classification
Full Accesshttps://mail.google.com/YesYesYes (+ permanent delete)YesIMAP onlyRestricted
Gmail API Full Accessgmail.modifyYesYesYesYesYesRestricted
Read + Sendgmail.readonly + gmail.send + gmail.labelsYesYesNoYesYesRestricted
Read-Onlygmail.readonly + gmail.labelsYesNoNoYesYesRestricted
Send-Onlygmail.sendNoYesNoNoNoSensitive

Manage Labels refers to creating, renaming, and deleting labels (folders). The gmail.labels scope is part of the Read-Only and Read + Send presets so that label listing and modification work consistently - listing labels also works with gmail.readonly alone.

Google's Scope Classifications

Google classifies OAuth2 scopes into three tiers. The classification determines what verification your application needs before it can be published:

ClassificationVerification RequiredGmail Scopes in This Tier
RestrictedSecurity audit (CASA assessment)https://mail.google.com/, gmail.modify, gmail.readonly, gmail.compose, gmail.metadata
SensitiveBrand verification onlygmail.send
Non-sensitiveNo verificationgmail.labels

The overall classification of your application is determined by its most restrictive scope. For example, if you request both gmail.send (Sensitive) and gmail.readonly (Restricted), your application is classified as Restricted.

Send-Only avoids the Restricted tier

The Send-Only configuration using gmail.send is the only Gmail scope combination that avoids the Restricted tier. It requires brand verification (Sensitive) rather than a security assessment.

How Scope Configuration Works in EmailEngine

EmailEngine uses three fields to determine which scopes are requested during OAuth2 authentication:

FieldPurposeAPI ParameterWeb UI Field
Base scopesSelects the default scope setbaseScopes"Base scopes" radio buttons
Additional scopesAdds scopes on top of the defaultsextraScopes"Additional scopes" textarea
Disabled scopesRemoves scopes from the defaultsskipScopes"Disabled scopes" textarea

How they combine:

  1. Start with the default scope for the selected base ("imap" = https://mail.google.com/, "api" = gmail.modify)
  2. Add any scopes from Additional scopes that are not already included
  3. Remove any scopes that match Disabled scopes. A disabled scope can be written in full or as the part after https://www.googleapis.com/auth/, so gmail.modify and https://www.googleapis.com/auth/gmail.modify both match

EmailEngine also adds the OpenID Connect scopes openid, email, and profile to every user-facing Gmail OAuth2 flow. These provide the signed-in user's address and name without any Gmail scope, and do not need to be configured. Service account applications do not get them.

Web UI Preset Buttons

When the base scope is set to Gmail API, the OAuth2 application form shows an Account Type Helper card with four preset buttons that populate the Additional scopes and Disabled scopes fields:

  • Normal (Full Access) - clears both fields, so gmail.modify is used as-is
  • Read-Only - adds gmail.readonly + gmail.labels, disables gmail.modify
  • Read-Only + Send - adds gmail.readonly + gmail.send + gmail.labels, disables gmail.modify
  • Send-Only - adds gmail.send, disables gmail.modify

These presets preserve any third-party scopes you may have added manually (such as Google Calendar or Drive scopes).

How EmailEngine Classifies an Account

After authorization, EmailEngine stores the scopes Google actually granted with the account and reads them on every initialization. An account counts as having read access when the granted scopes include any of gmail.modify, gmail.readonly, gmail.labels or https://mail.google.com/, and as having send access when they include gmail.send. An account with send access and no read access runs in send-only mode. Adding gmail.labels to a send-only application therefore turns it into a read account in EmailEngine's eyes, and message listing then fails at Google.


Full Access

Scope: https://mail.google.com/

This is the broadest Gmail scope. It grants full access to all Gmail operations, including permanent message deletion, which no other scope allows. This scope is accepted by every Gmail API endpoint and also enables IMAP and SMTP protocol access.

In EmailEngine, this scope is used with the IMAP/SMTP backend (baseScopes: "imap"). EmailEngine connects via IMAP for reading and SMTP for sending, providing raw protocol-level access.

What this enables

OperationSupported
List and read messagesYes
Send messages (with full SMTP envelope control)Yes
Modify message labels/flagsYes
Move messages between labelsYes
Trash messagesYes
Permanently delete messagesYes
List, create, rename, delete labelsYes
Raw SMTP features (custom envelope-from, etc.)Yes

What this does not enable

  • Cloud Pub/Sub push notifications (EmailEngine uses IMAP IDLE for real-time updates instead)

When to use

  • You need permanent message deletion (not just trash)
  • You need raw SMTP features (custom envelope-from, direct SMTP control)
  • You want to use EmailEngine's IMAP/SMTP proxy, which lets legacy clients and scripts connect with password authentication while EmailEngine handles OAuth2 behind the scenes
  • You are migrating from an existing IMAP-based integration
  • Your organization restricts Cloud Pub/Sub permissions
  • You can justify the full scope to Google during verification

Google classification

Restricted - requires a security audit (CASA assessment) for public applications.

Setup via Web UI

  1. Go to Integrations > OAuth2 Apps > Create OAuth2 app and select Gmail
  2. Click Load configuration from the JSON file and select your Google credentials file, or enter the Client ID and Client Secret manually
  3. Under Base scopes, select IMAP and SMTP
  4. Leave Additional scopes and Disabled scopes empty
  5. Click Register app

Setup via API

curl -X POST "https://emailengine.example.com/v1/oauth2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider": "gmail",
"name": "Gmail IMAP/SMTP",
"baseScopes": "imap",
"clientId": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"clientSecret": "YOUR_CLIENT_SECRET",
"redirectUrl": "https://emailengine.example.com/oauth"
}'

See also

Setting Up Gmail with OAuth2 (IMAP/SMTP) - complete step-by-step setup guide.


Gmail API Full Access

Scope: https://www.googleapis.com/auth/gmail.modify

This is the default scope when using the Gmail API backend. It provides full read, send, and modify access through Google's REST API, with Cloud Pub/Sub for real-time push notifications.

What this enables

OperationGmail API EndpointSupported
List and read messagesmessages.list, messages.getYes
Send messagesmessages.sendYes
Modify message labels/flagsmessages.modifyYes
Move messages between labelsmessages.modifyYes
Trash messagesmessages.trashYes
List labelslabels.listYes
Create, rename, delete labelslabels.create, labels.patch, labels.deleteYes
Cloud Pub/Sub push notificationsusers.watchYes
Reply and forward (with reference)via messages.send + messages.getYes

What this does not enable

  • Permanent message deletion (only trash). Requires https://mail.google.com/ scope.
  • Raw SMTP features (custom envelope-from). Requires IMAP/SMTP mode.

EmailEngine behavior

  • Pub/Sub watch for real-time webhook notifications, when the application has a linked service account
  • History tracking for incremental sync
  • Fallback polling about every 10 minutes in case Pub/Sub notifications are missed, or when no service account is linked
  • Locale detection for the account
  • After sending, fetches back the Message-ID that Gmail assigned

When to use

  • Default choice for Gmail API integration
  • You need full email operations (read, send, modify, move, trash)
  • You want Cloud Pub/Sub push notifications for real-time updates

Google classification

Restricted - requires a security audit (CASA assessment) for public applications.

Setup via Web UI

  1. Go to Integrations > OAuth2 Apps > Create OAuth2 app and select Gmail
  2. Click Load configuration from the JSON file and select your Google credentials file, or enter the Client ID and Client Secret manually
  3. Under Base scopes, select Gmail API
  4. Click the Normal (Full Access) preset button, or leave Additional scopes and Disabled scopes empty
  5. Click Register app

Setup via API

curl -X POST "https://emailengine.example.com/v1/oauth2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider": "gmail",
"name": "Gmail API - Full Access",
"baseScopes": "api",
"clientId": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"clientSecret": "YOUR_CLIENT_SECRET",
"redirectUrl": "https://emailengine.example.com/oauth"
}'

No extraScopes or skipScopes needed - gmail.modify is the default for the "api" base scope.

See also

Setting Up Gmail API - complete step-by-step setup guide including Cloud Pub/Sub configuration.


Read + Send

Scopes:

  • https://www.googleapis.com/auth/gmail.readonly
  • https://www.googleapis.com/auth/gmail.send
  • https://www.googleapis.com/auth/gmail.labels

Uses three separate scopes instead of the broader gmail.modify. This provides read and send access but cannot modify existing messages (flags, labels, moves, or trash).

What this enables

OperationGmail API EndpointSupported
List and read messagesmessages.list, messages.getYes
Send messagesmessages.sendYes
Modify message labels/flagsmessages.modifyNo
Move messages between labelsmessages.modifyNo
Trash messagesmessages.trashNo
List labelslabels.listYes
Create, rename, delete labelslabels.create, labels.patch, labels.deleteYes
Cloud Pub/Sub push notificationsusers.watchYes
Reply and forward (with reference)via messages.send + messages.getYes

What this does not enable

  • Modifying labels on existing messages (marking as read/unread, starring, categorizing)
  • Moving messages between folders/labels
  • Trashing or deleting messages
  • These operations require gmail.modify; Google rejects them with an insufficient authentication scopes error

EmailEngine behavior

Identical to Gmail API Full Access: Pub/Sub watch, history tracking, fallback polling, locale detection, and Message-ID resolution after sending all work, and incoming-message webhooks fire normally.

Operations that will fail

With this scope combination, EmailEngine API calls that attempt to modify, move, or trash messages fail, because Google rejects the underlying request for insufficient authentication scopes. This includes:

  • PUT /v1/account/{account}/message/{message} (updating flags)
  • PUT /v1/account/{account}/message/{message}/move (moving messages)
  • DELETE /v1/account/{account}/message/{message} (trashing messages)

When to use

  • Google's verification process requires you to justify each scope separately
  • Your application reads emails and sends responses but does not need to modify or organize them
  • You want the narrowest scopes that still allow both reading and sending

Google classification

Restricted - the gmail.readonly scope is Restricted, which sets the overall classification. The gmail.send scope alone is Sensitive and gmail.labels is Non-sensitive, but the combination is Restricted.

Setup via Web UI

  1. Go to Integrations > OAuth2 Apps > Create OAuth2 app and select Gmail (or edit an existing Gmail application)

  2. Under Base scopes, select Gmail API

  3. Click the Read-Only + Send preset button

    This sets:

    • Additional scopes:
      https://www.googleapis.com/auth/gmail.readonly
      https://www.googleapis.com/auth/gmail.send
      https://www.googleapis.com/auth/gmail.labels
    • Disabled scopes:
      https://www.googleapis.com/auth/gmail.modify
  4. Click Register app (or Update app when editing)

Setup via API

curl -X POST "https://emailengine.example.com/v1/oauth2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider": "gmail",
"name": "Gmail API - Read + Send",
"baseScopes": "api",
"clientId": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"clientSecret": "YOUR_CLIENT_SECRET",
"redirectUrl": "https://emailengine.example.com/oauth",
"extraScopes": [
"https://www.googleapis.com/auth/gmail.readonly",
"https://www.googleapis.com/auth/gmail.send",
"https://www.googleapis.com/auth/gmail.labels"
],
"skipScopes": [
"https://www.googleapis.com/auth/gmail.modify"
]
}'

Read-Only

Scopes:

  • https://www.googleapis.com/auth/gmail.readonly
  • https://www.googleapis.com/auth/gmail.labels

Provides read access to messages and labels. Cannot send, modify, or delete messages.

What this enables

OperationGmail API EndpointSupported
List and read messagesmessages.list, messages.getYes
Send messagesmessages.sendNo
Modify message labels/flagsmessages.modifyNo
Move messages between labelsmessages.modifyNo
Trash messagesmessages.trashNo
List labelslabels.listYes
Create, rename, delete labelslabels.create, labels.patch, labels.deleteYes
Cloud Pub/Sub push notificationsusers.watchYes
Reply and forward (with reference)-No

What this does not enable

  • Sending emails (the submit API endpoint will fail)
  • Modifying labels on existing messages
  • Moving or trashing messages

EmailEngine behavior

Identical to Gmail API Full Access for everything except sending: Pub/Sub watch, history tracking, fallback polling and locale detection work, and incoming-message webhooks such as messageNew fire normally.

gmail.labels is recommended

The gmail.labels scope is included in this preset so that label listing and label management behave consistently. Listing labels also works with gmail.readonly alone, but keeping gmail.labels is recommended - it is a non-sensitive scope and does not add to Google's verification requirements.

When to use

  • Email monitoring or archival applications
  • Helpdesk systems that only need to read incoming emails
  • Analytics that process email content without modifying it
  • You do not need to send, modify, or organize emails through EmailEngine

Google classification

Restricted - the gmail.readonly scope is Restricted. The gmail.labels scope is Non-sensitive, but the combination is Restricted.

Setup via Web UI

  1. Go to Integrations > OAuth2 Apps > Create OAuth2 app and select Gmail (or edit an existing Gmail application)

  2. Under Base scopes, select Gmail API

  3. Click the Read-Only preset button

    This sets:

    • Additional scopes:
      https://www.googleapis.com/auth/gmail.readonly
      https://www.googleapis.com/auth/gmail.labels
    • Disabled scopes:
      https://www.googleapis.com/auth/gmail.modify
  4. Click Register app (or Update app when editing)

Setup via API

curl -X POST "https://emailengine.example.com/v1/oauth2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider": "gmail",
"name": "Gmail API - Read Only",
"baseScopes": "api",
"clientId": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"clientSecret": "YOUR_CLIENT_SECRET",
"redirectUrl": "https://emailengine.example.com/oauth",
"extraScopes": [
"https://www.googleapis.com/auth/gmail.readonly",
"https://www.googleapis.com/auth/gmail.labels"
],
"skipScopes": [
"https://www.googleapis.com/auth/gmail.modify"
]
}'

Send-Only

Scope: https://www.googleapis.com/auth/gmail.send

The most restrictive configuration. Can only send emails - no access to read messages, list labels, or modify anything.

What this enables

OperationGmail API EndpointSupported
List and read messagesmessages.list, messages.getNo
Send messagesmessages.sendYes
Modify message labels/flagsmessages.modifyNo
Move messages between labelsmessages.modifyNo
Trash messagesmessages.trashNo
List labelslabels.listNo
Create, rename, delete labelslabels.create, labels.patch, labels.deleteNo
Cloud Pub/Sub push notificationsusers.watchNo
Reply and forward (with reference)-No

What this does not enable

  • Reading any email content
  • Listing mailboxes or labels
  • Any modification or deletion of messages
  • Receiving webhook notifications for incoming emails
  • Reply/forward with reference.action (returns ReferenceNotSupported because EmailEngine cannot read the original message)

EmailEngine behavior

EmailEngine runs an account in send-only mode when its granted scopes include gmail.send and none of the read scopes (see How EmailEngine Classifies an Account). The account object reports sendOnly: true, and the admin interface shows a Send-only badge on the account page.

  • No Pub/Sub watch - push notifications are not set up since there is nothing to monitor
  • No history tracking - incremental sync is disabled
  • No fallback polling - no periodic checks for new messages
  • No locale detection - user locale is not resolved
  • No incoming email webhooks - messageNew, messageUpdated, and similar webhook events are not fired
  • Email detection - uses the Google UserInfo endpoint (/oauth2/v2/userinfo), which works with the OpenID Connect scopes, instead of the Gmail profile endpoint to determine the user's email address
  • After sending - cannot fetch back the Gmail-assigned Message-ID because that requires read access. The Message-ID from the submitted message headers is reported instead, so a bounce Gmail reports against its own Message-ID cannot be matched to the sent message
  • Reply/forward - using reference.action in the submit API fails with a 400 response and code ReferenceNotSupported, since EmailEngine cannot read the referenced message to build the reply chain

When to use

  • Transactional email (order confirmations, password resets, notifications)
  • Applications that only need to send emails and have no need to read or manage the user's mailbox
  • You want the least demanding Google verification path (Sensitive instead of Restricted)

Google classification

Sensitive - this is the only Gmail scope configuration that avoids the Restricted tier. Sensitive scopes require brand verification but not a security audit (CASA assessment).

Setup via Web UI

  1. Go to Integrations > OAuth2 Apps > Create OAuth2 app and select Gmail (or edit an existing Gmail application)

  2. Under Base scopes, select Gmail API

  3. Click the Send-Only preset button

    This sets:

    • Additional scopes:
      https://www.googleapis.com/auth/gmail.send
    • Disabled scopes:
      https://www.googleapis.com/auth/gmail.modify
  4. Click Register app (or Update app when editing)

Setup via API

curl -X POST "https://emailengine.example.com/v1/oauth2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider": "gmail",
"name": "Gmail API - Send Only",
"baseScopes": "api",
"clientId": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"clientSecret": "YOUR_CLIENT_SECRET",
"redirectUrl": "https://emailengine.example.com/oauth",
"extraScopes": [
"https://www.googleapis.com/auth/gmail.send"
],
"skipScopes": [
"https://www.googleapis.com/auth/gmail.modify"
]
}'

Updating an Existing OAuth2 Application

To change scopes on an existing OAuth2 application, use the PUT /v1/oauth2/{app} endpoint:

curl -X PUT "https://emailengine.example.com/v1/oauth2/YOUR_APP_ID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"extraScopes": [
"https://www.googleapis.com/auth/gmail.readonly",
"https://www.googleapis.com/auth/gmail.labels"
],
"skipScopes": [
"https://www.googleapis.com/auth/gmail.modify"
]
}'
Scope changes require re-authentication

Changing scopes on the OAuth2 application only affects new authorizations. Existing accounts keep the scopes that were granted when they authorized until the user re-authorizes. To apply new scopes to existing accounts, generate a new authentication link for the same account ID and have users complete the OAuth2 flow again.

Gmail API Endpoint Scope Requirements

For reference, here is which scopes are accepted by the Gmail API endpoints that EmailEngine uses:

Gmail API Endpointmail.google.comgmail.modifygmail.readonlygmail.sendgmail.labels
messages.listYesYesYes--
messages.getYesYesYes--
messages.sendYesYes-Yes-
messages.modifyYesYes---
messages.trashYesYes---
messages.delete (permanent)Yes----
messages.batchModifyYesYes---
labels.listYesYesYes-Yes
labels.getYesYesYes-Yes
labels.createYesYes--Yes
labels.patchYesYes--Yes
labels.deleteYesYes--Yes
users.watch (Pub/Sub)YesYesYes--

Source: Gmail API Reference

See Also