Gmail API Send Email in 5 Lines
npm install unipile-node-sdkUNIPILE_DSN and UNIPILE_TOKEN to your .env file.client.email.send()account_id, to, subject, and body. Done.tracking_id confirming delivery via the Gmail API.import { UnipileClient } from 'unipile-node-sdk';
const client = new UnipileClient(
process.env.UNIPILE_DSN,
process.env.UNIPILE_TOKEN
);
const result = await client.email.send({
account_id: 'acc_xxxxxxxxxxxxxxxx',
to: [{
display_name: 'Alice Martin',
identifier: 'alice@acme.com'
}],
subject: 'Hello from Gmail API',
body: '<p>Sent via Unipile!</p>'
});
console.log(result); // { tracking_id: 'msg_...' }
Gmail API Send Email,
Python & Node.js
Code Examples
A complete developer guide to sending emails programmatically with Gmail API: OAuth 2.0 setup, code examples, rate limits, and SMTP comparison.
# Send email with Gmail API
import base64
from email.mime.text import MIMEText
from googleapiclient.discovery import build
def send_email(service, to, subject, body):
msg = MIMEText(body)
msg['to'] = to
msg['subject'] = subject
raw = base64.urlsafe_b64encode(
msg.as_bytes()
).decode()
return service.users().messages().send(
userId='me',
body={'raw': raw}
).execute()
What is Gmail API Send Email?
Sending emails via the Gmail API involves using HTTP requests to interact with Gmail's backend systems. Instead of manually composing and sending emails through the Gmail interface, developers can automate the process within their applications.
The API provides endpoints that allow developers to create and send email messages in various formats, including plain text, HTML, and emails with attachments. It also supports more advanced features like threading and managing email labels, making it a comprehensive solution for programmatic email communication. For multi-provider sending (Gmail, Outlook, IMAP), see the unified send email API guide. For a cross-provider approach, explore the send email API.
Why Use Gmail API for Sending Emails?
Using the Gmail API for sending emails offers several advantages that make it a powerful choice for modern applications.
Automation
Automate routine email tasks, saving time and reducing manual errors across your entire workflow.
Integration
Integrate email sending directly into your app's workflow, enhancing user experience with a seamless flow.
Customization
Customize email content dynamically based on user data or application state for truly personalized messaging.
Scalability
Efficiently manage high-volume email sending, ideal for applications that require large-scale communication.
Setting Up Gmail API for Sending Emails
Google OAuth DocsGoogle mandates third-party applications to submit their app for verification of Google user data usage. Follow the 10 steps below to configure OAuth, enable Gmail API, and get your credentials ready for production. See also: securing your email API integration.
Access Google Developers Console
Sign in to the Google Developers Console to start your project setup. You'll need a Google account with admin privileges.
Create a New Google Project
Sign up on the Google Developers Console and either create a new project or use an existing Google project. Click on NEW PROJECT in the project selector to get started.
Create OAuth Client ID Credentials
Navigate to APIs & Services > Credentials, then click CREATE CREDENTIALS > OAuth client ID.
- Application type: Web application
- Name: Your internal name
- Add 2 Authorised redirect URIs using your Unipile DSN (available in the Unipile Dashboard):
https://{{YOUR_DSN_less_port}}/api/v1/hosted/google_auth_request_callback/port{{YOUR_PORT}}
Once created, add the Client ID and Client Secret to Unipile Dashboard > Settings > Google OAuth.
Enable the Gmail API Library
Go to APIs & Services > Library, search for Gmail API, and click ENABLE.
Configure OAuth Consent Screen, User Type
Choose your User Type based on your testing phase:
- Internal: Limited to Google Workspace users within your organization.
- External & In Testing: Requires adding Test Users. Tokens expire in 7 days.
For details on User Types, see the Google documentation.
Fill in App Information
In the OAuth consent screen, provide the following:
- Application Name: Your app's display name.
- User Support Email: A contact email or distribution list for user questions.
- App Logo: Upload your application logo for visual identification.
Set App Domain Information
- Application Homepage URL: A true homepage, not just a login page.
- Privacy Policy Link: Make sure it meets Google's specific requirements, particularly the Limited Use section.
- Terms of Service Link: Public terms of service URL.
Add Authorised Domains
- Add your production app domain (not the dev or staging domain).
- Add unipile.com as a second authorised domain.
Enter Developer Contact Information
Provide an email address Google can use for verification notifications. Use a distribution list so all relevant team members receive updates. Monitor it regularly, as Google's emails can end up in spam folders.
Add Required Scopes
Click ADD OR REMOVE SCOPES and add the following (refresh the page if they don't appear):
Note: gmail.modify is only required if you need to move or delete emails. If you don't use it, contact Unipile support to remove it from your account manually.
11
Generate Your Demonstration Video
Required only once your integration is fully live in production
Produce and host a demonstration video that adheres to Google's stipulations. Upload it as an Unlisted YouTube video, only one video link is permitted.
- Your app and OAuth flow are presented in English, as indicated in Google documentation.
- The demonstration is conducted in a production-level domain.
- In Google Project settings, confirm Publishing status is "In Production" and User Type is "External".
- Display your application's homepage with the complete URL.
- Illustrate how a Google customer can connect their account via the official Google sign-in button.
- During the OAuth flow, highlight the URL and reveal the CLIENT ID.
- Sequentially showcase each scope being requested, tailored to your specific use case.
- Demonstrate bi-directional functionality by showing sync between your app and Gmail (sending, receiving, and Sent mail list updates).
- Add the final video to your Google Project as an unlisted YouTube video link.
- Submit the YouTube URL to your Customer Success Manager for review.
- After review, proceed with the app verification submission.
Timeline: verification can take anywhere from 2 to 8 weeks depending on Google's queue and the number of remediation rounds.
12
Whitelisting & Security Review for Restricted Scopes
Applies only if your application uses restricted scopes
If your application uses restricted scopes, additional steps are required.
Apps requesting access to restricted scope Google user data must undergo a security assessment via the CASA (Cloud Application Security Assessment) program. Google categorizes your app as either Tier 2 or Tier 3.
Apps accessing restricted scopes must complete a security assessment every 12 months to maintain access. If you introduce a new restricted scope that wasn't previously approved, your app may require reassessment.
Google's review team will initiate contact via email. Keep your Project Owner and Project Editor information up to date in Cloud Console so the right team members receive these notifications.
As an alternative to the standard security review, you may have your application whitelisted. This bypasses the usual procedures but applies only if your application meets very specific criteria:
- Majority of Customers using Google Workspace: most customers should have emails in the format @company.com.
- Admin-initiated whitelisting: your end users' administrators allow access via their Admin Console using your Google Client ID.
- Limited Personal Gmail Usage: fewer than 100 personal Gmail accounts (@gmail.com) should authenticate.
- Unverified projects have a 100 lifetime user limit. Workspace accounts don't count against this limit, but personal Gmail accounts always do.
- Free trial users must use their Workspace email address and whitelist the application.
Whitelisting is a workaround and may not suit all use cases. Evaluate the criteria carefully before choosing this path.
Gmail API for CRM, ATS, Outreach & iPaaS
Automate email sending, sync conversations, and centralize customer communication across every type of B2B SaaS platform.
Log and send emails without leaving your CRM
Automate email communication, track interactions, and enhance customer engagement. Log customer emails, send personalized messages, and centralize all conversations within your pipeline.
Send candidate emails from one unified inbox
Streamline candidate communication, schedule interviews, and send offer letters directly from your recruiting platform. Every reply is automatically attached to the right candidate profile.
Power multi-step email sequences at scale
Build multi-channel sequences with Gmail as the core email engine. Send personalized messages, track opens and replies, and trigger follow-ups based on prospect behavior.
Trigger Gmail actions inside any workflow
Embed Gmail send capabilities into automation builders. Let end users connect their Gmail account and trigger emails as part of multi-step workflows, without building the OAuth flow from scratch.
Key Features of Gmail API Send Email
Retrieve emails, compose and send new messages, manage labels, and receive real-time webhook notifications. Four core capabilities that cover every email workflow in your application.
List All Emails
Retrieve and display emails from a user's Gmail account. Filter by folder, date, sender, or read status for powerful search and management.
List Email FeatureSend New Email
Programmatically compose and send emails directly from your app. Support HTML, plain text, attachments, CC, BCC, and thread replies.
Send Email FeatureList & Get Labels
Manage Gmail labels and folders by listing or retrieving individual label details. Organize and categorize emails for smarter workflow routing.
List and Get LabelWebhook Tracking
Set up webhooks to receive real-time updates on email activity. Trigger instant actions on new messages, opens, replies, or bounces.
Webhook NotificationEverything you can do with the Gmail API
A complete overview of the Gmail endpoints available through Unipile, from account connection to webhook tracking.
How to Send an Email with Gmail API
Complete Python and Node.js examples for sending plain text, HTML, and emails with attachments via the Gmail API. Copy-paste ready with OAuth 2.0 authentication included.
1 Send a Plain Text Email (Python)
Use the official google-api-python-client and google-auth libraries. The function constructs a MIME message, encodes it to base64url, and posts it to the Gmail API send endpoint.
import base64 from email.mime.text import MIMEText from google.oauth2.credentials import Credentials from googleapiclient.discovery import build def send_email(to, subject, body, credentials_dict): creds = Credentials(**credentials_dict) service = build('gmail', 'v1', credentials=creds) message = MIMEText(body) message['to'] = to message['subject'] = subject raw = base64.urlsafe_b64encode(message.as_bytes()).decode() result = service.users().messages().send( userId='me', body={'raw': raw} ).execute() print(f"Message sent. ID: {result['id']}") return result # Usage send_email( to='recipient@example.com', subject='Hello from Gmail API', body='This email was sent via Gmail API send email.', credentials_dict={ 'token': 'YOUR_ACCESS_TOKEN', 'refresh_token': 'YOUR_REFRESH_TOKEN', 'client_id': 'YOUR_CLIENT_ID', 'client_secret': 'YOUR_CLIENT_SECRET', 'token_uri': 'https://oauth2.googleapis.com/token' } )
2 Send a Plain Text Email (Node.js)
Use the googleapis npm package. The message is constructed as a raw RFC 2822 string, encoded in base64url, and sent via the Gmail API.
const { google } = require('googleapis'); async function sendEmail(auth, to, subject, body) { const gmail = google.gmail({ version: 'v1', auth }); const message = [ `To: ${to}`, `Subject: ${subject}`, '', body ].join('\n'); const encodedMessage = Buffer.from(message) .toString('base64') .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, ''); const result = await gmail.users.messages.send({ userId: 'me', requestBody: { raw: encodedMessage } }); console.log(`Message sent. ID: ${result.data.id}`); return result.data; } // OAuth2 setup const oauth2Client = new google.auth.OAuth2( 'YOUR_CLIENT_ID', 'YOUR_CLIENT_SECRET', 'YOUR_REDIRECT_URI' ); oauth2Client.setCredentials({ access_token: 'YOUR_ACCESS_TOKEN', refresh_token: 'YOUR_REFRESH_TOKEN' }); sendEmail(oauth2Client, 'recipient@example.com', 'Hello', 'Sent via Gmail API send email!');
3 Send an HTML Email (Python)
Use MIMEMultipart('alternative') with both a text/plain fallback and a text/html part. Gmail clients will render the HTML version; other clients fall back to plain text.
from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import base64 def send_html_email(service, to, subject, html_body): message = MIMEMultipart('alternative') message['to'] = to message['subject'] = subject # Plain text fallback text_part = MIMEText('Please view this email in an HTML-compatible client.', 'plain') # HTML version html_part = MIMEText(html_body, 'html') message.attach(text_part) message.attach(html_part) raw = base64.urlsafe_b64encode(message.as_bytes()).decode() return service.users().messages().send( userId='me', body={'raw': raw} ).execute() # Usage html_content = """Hello!
This email was sent with Gmail API send email.
""" send_html_email(service, 'to@example.com', 'HTML Email via Gmail API', html_content)
4 Send an Email with Attachments (Python)
Attach any file type by reading the file bytes, guessing the MIME type, and appending it to a MIMEMultipart message. Maximum attachment size is 25 MB per message.
import base64 import mimetypes from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders def send_email_with_attachment(service, to, subject, body, file_path): message = MIMEMultipart() message['to'] = to message['subject'] = subject message.attach(MIMEText(body, 'plain')) # Detect MIME type and attach file content_type, encoding = mimetypes.guess_type(file_path) main_type, sub_type = content_type.split('/', 1) with open(file_path, 'rb') as f: attachment = MIMEBase(main_type, sub_type) attachment.set_payload(f.read()) encoders.encode_base64(attachment) attachment.add_header( 'Content-Disposition', f'attachment; filename="{file_path.split("/")[-1]}"' ) message.attach(attachment) raw = base64.urlsafe_b64encode(message.as_bytes()).decode() return service.users().messages().send( userId='me', body={'raw': raw} ).execute()
Unipile's Email API lets you send emails from Gmail, Outlook, and IMAP accounts with a single unified endpoint - no provider-specific OAuth setup required. Link accounts in minutes, not days.
Gmail API vs SMTP, Which Should You Use?
Both the Gmail API and Gmail SMTP let you send emails programmatically, but they serve very different use cases. Here is a direct comparison to help you choose.
| Feature | Gmail API | Gmail SMTP |
|---|---|---|
| Authentication | OAuth 2.0 | App Password or OAuth |
| Daily sending limit | 2,000 Workspace, 500 free | 500/day free Gmail |
| Attachments | Up to 25 MB | Up to 25 MB |
| HTML emails | Yes | Yes |
| Thread tracking | Labels & threads | No |
| Read receipts | Yes | No |
| Programmatic access | Full, search, labels, drafts, webhooks | Send only |
| Setup complexity | High OAuth + Cloud Console | Low App Password only |
| Best for | SaaS apps, CRM, ATS integration | Simple scripts, personal use |
Gmail API Rate Limits and Quotas
Understanding Gmail API rate limits is essential before going to production. Exceeding these quotas returns a 429 rateLimitExceeded error - always implement exponential backoff.
Handling Rate Limit Errors with Exponential Backoff
When the Gmail API returns a 429 status, wait before retrying. Use exponential backoff to avoid hammering the API and triggering longer blocks.
import time from googleapiclient.errors import HttpError def send_with_retry(service, user_id, message, max_retries=3): for attempt in range(max_retries): try: return service.users().messages().send( userId=user_id, body=message ).execute() except HttpError as error: if error.resp.status == 429: # Rate limited wait_time = (2 ** attempt) * 1 # Exponential backoff: 1s, 2s, 4s print(f"Rate limited. Waiting {wait_time}s before retry {attempt + 1}/{max_retries}...") time.sleep(wait_time) else: raise # Re-raise non-rate-limit errors immediately raise Exception(f"Gmail API send email failed after {max_retries} retries")
Common Gmail API Errors and How to Fix Them
Most Gmail API send email errors fall into three categories: authentication failures (401), permission issues (403), and malformed request errors (400). Here is a reference table with causes and fixes.
| HTTP Code | Error Message | Cause | Solution |
|---|---|---|---|
| 401 | Unauthorized | Access token expired |
Use your
refresh_token to obtain a new access token via oauth2.googleapis.com/token
|
| 403 | Forbidden | Insufficient OAuth scopes |
Add
https://www.googleapis.com/auth/gmail.send scope and re-authorize the user
|
| 403 | rateLimitExceeded | Daily quota exceeded |
Implement exponential backoff - wait 1s, 2s, 4s between retries. See rate limits section above.
|
| 400 | invalid_grant | Refresh token revoked or expired |
User must re-authenticate and re-authorize your app. Prompt a new OAuth consent flow.
|
| 400 | Bad Request | Malformed MIME message |
Verify the message is encoded with
base64.urlsafe_b64encode() - not standard base64
|
| 403 | insufficientPermissions | Service account missing delegation |
Enable domain-wide delegation in Google Workspace Admin and grant Gmail API scopes to the service account
|
Looking for a unified solution? The Unipile Email API Guide covers Gmail, Outlook, IMAP and more from a single integration - one endpoint, one authentication flow, three providers.
Read the Email API GuideConnect Outlook and IMAP with the same API
Unipile goes beyond Gmail. Link Microsoft 365, Outlook.com, and any IMAP mailbox through a single unified API, with OAuth handled for you on Microsoft and flexible credential-based auth for IMAP.
Microsoft Graph API
Mail.Read
Mail.Send
offline_access
Link Microsoft accounts with Unipile using OAuth. Register your application in Azure Active Directory, configure Unipile with your AAD application ID, and start sending emails through Outlook.com, Microsoft 365, and Exchange Online.
IMAP API
For any IMAP-compatible mailbox, configure server settings and choose the appropriate authentication method within Unipile. Input host, port, and credentials to establish a secure connection, no OAuth flow required.
Gmail API Send Email, Frequently Asked Questions
Answers to the most common questions about sending emails programmatically with the Gmail API.
gmail.send scope, construct a MIME message, encode it in base64url format, then POST to the users.messages.send endpoint. See the Python example and Node.js code examples above for a complete, copy-paste ready implementation.
MIMEMultipart, attach files using MIMEBase, encode the full message in base64url, and send via the Gmail API send email endpoint. Maximum attachment size is 25 MB per message. See the attachments code example in the section above.
userId='target@domain.com' to users().messages().send(). For individual user delegation, see our complete send email on behalf of user guide.
429 rateLimitExceeded errors gracefully, see the rate limits section above for a complete code example.
MIMEMultipart('alternative') with both a text/plain fallback and a text/html part. Encode the complete MIME message in base64url format before sending via the Gmail API send email endpoint. Gmail clients render the HTML version; other clients fall back to plain text automatically.
401 Unauthorized, your access token expired: use the refresh_token to obtain a new one via oauth2.googleapis.com/token. 403 Forbidden, missing gmail.send scope: re-authorize with correct scopes. 400 invalid_grant, refresh token revoked: the user must re-authenticate your app from scratch.
You may also like
OAuth Email API: Authenticate User Mailboxes the Right Way (2026)
Implementation Build vs Buy: Hosted OAuth Email API in 5 Minutes Instead of building 3 separate OAuth flows, Unipile provides a hosted authentication link that handles Google OAuth, Microsoft Identity, and IMAP OAuth for you. Your app generates a link, redirects the user, and receives a webhook...
Calendar Sync API for SaaS: Real-Time Google & Outlook Integration
For CRM, ATS, outreach platforms, and AI-driven software, a reliable Calendar API is no longer a nice-to-have. It is now an essential building block that drives productivity, booking workflows, follow-ups, automated sequences, and team coordination. Yet implementing calendar synchronization is one...
The Complete Developer’s Guide to Calendar API Integration
Modern software runs on connections, between people, systems, and time itself. At the heart of this connectivity lies the Calendar API, a vital component enabling apps to read, create, and synchronize calendar events seamlessly. Whether you’re building a CRM, recruiting platform, or productivity...


