Authorize an application to access Gmail
Choose Gmail OAuth scopes, complete user consent, and configure a server-side client without exposing mailbox tokens or changing MX records.
Reviewed
The Gmail API connects an application to an existing hosted mailbox. Access is authorized through Google OAuth, not through a MailKite API key or a generic Google Cloud service-account key. Keep Gmail as the mailbox host; an API integration does not require changing its MX records.
Choose the smallest permission set
| Workflow | Starting scope | Boundary |
|---|---|---|
| Send messages only | https://www.googleapis.com/auth/gmail.send | Does not authorize reading incoming mail |
| Read mailbox content and synchronize changes | https://www.googleapis.com/auth/gmail.readonly | Broad read access; Google classifies it as restricted |
| Read metadata without message bodies | https://www.googleapis.com/auth/gmail.metadata | Cannot retrieve full body content |
Do not request https://mail.google.com/ merely because a sample does. Google classifies sending as sensitive and several reading scopes as restricted; verification and security-assessment obligations depend on the scopes, data handling, and application’s distribution. Consult the current scope policy before promising a public launch date.
Google Workspace administrators can restrict third-party applications. Personal Gmail accounts do not have Workspace domain-wide delegation. A service account cannot simply impersonate either kind of mailbox without the appropriate supported authorization arrangement.
Complete consent before running API calls
- Enable the Gmail API in your Google Cloud project.
- Configure the OAuth consent application, audience/test users, and required scopes.
- Create the correct OAuth client type for your app. For a backend web application, register its exact HTTPS callback URI.
- Initiate Google’s authorization-code flow from an authenticated application session. Bind a cryptographically random, expiring, one-time
statevalue to that session. - At the callback, handle denial, validate and consume
state, exchange the code through the Google client library, and verify the actually granted scopes. - Store refresh tokens encrypted in a backend secret/token store associated with the correct application user. Never send them to frontend storage or print them to logs.
Request offline access only when background processing needs it. A refresh token is not guaranteed on every authorization response; preserve an existing valid token when the response omits one. Handle revocation and expired grants by asking the user to reconnect instead of retrying indefinitely.
The complete web-server flow is documented by Google Identity. This article does not replace the callback/session implementation with a token pasted into a page.
Configure the shared server client
After consent has produced an approved refresh token, the following module is used by the sending and receiving guides. Install the official Node.js client:
npm install googleapis
Save as gmail-client.mjs. Supply the listed values from your backend configuration and secret store; do not commit a token file or a .env containing real credentials.
import { google } from "googleapis";
for (const name of [
"GMAIL_CLIENT_ID", "GMAIL_CLIENT_SECRET",
"GMAIL_REDIRECT_URI", "GMAIL_REFRESH_TOKEN",
]) {
if (!process.env[name]) throw new Error(`Missing ${name}`);
}
const auth = new google.auth.OAuth2(
process.env.GMAIL_CLIENT_ID,
process.env.GMAIL_CLIENT_SECRET,
process.env.GMAIL_REDIRECT_URI,
);
auth.setCredentials({ refresh_token: process.env.GMAIL_REFRESH_TOKEN });
export const gmail = google.gmail({ version: "v1", auth });
The library refreshes access tokens using this existing grant; it does not obtain consent or grant missing scopes. Use the same OAuth application that issued the refresh token. In a multi-user application, resolve credentials per authenticated connection instead of using one environment-wide mailbox token.
Verify and choose the next task
Confirm the connected mailbox and approved scopes in your own consent/connection record. Test sending only with an approved recipient, or continue to incoming-change notifications if read access was granted.
If all you need is future incoming messages forwarded to a webhook, the Gmail forwarding guide offers a separate route with different mailbox-history and policy boundaries. MailKite cannot bypass Google consent or administrative forwarding restrictions.
References