Create and send email messages

This document explains how to create and send email messages using the Gmail API.

There are two ways to send email using the Gmail API:

  • You can send it directly using the messages.send method.
  • You can send it from a draft, using the drafts.send method. For more information on sending a draft message, see Send drafts.

Gmail messages are sent as base64URL encoded strings within the raw field of a messages resource. To send an email message:

  1. Create the email content and encode it as a base64URL string.
  2. Create a new message resource and set its raw property to the base64URL string you just created.
  3. Call the messages.send method, or, if sending a draft, call the drafts.send method, to send the message.

The details of this workflow can vary depending on your choice of client library and programming language.

Create messages

The Gmail API requires MIME email messages compliant with RFC 2822 and encoded as base64URL strings. Many programming languages have libraries or utilities that simplify the process of creating and encoding MIME messages.

The following code samples show how to create a MIME message using Google API client libraries for various languages:

Java

Creating an email message can be simplified with the MimeMessage class in the javax.mail.internet package. The following code sample shows how to create the email message, including the headers:

gmail/snippets/src/main/java/CreateEmail.java
importjava.util.Properties;
importjavax.mail.MessagingException;
importjavax.mail.Session;
importjavax.mail.internet.InternetAddress;
importjavax.mail.internet.MimeMessage;
/* Class to demonstrate the use of Gmail Create Email API */
publicclass CreateEmail{
/**
 * Create a MimeMessage using the parameters provided.
 *
 * @param toEmailAddress email address of the receiver
 * @param fromEmailAddress email address of the sender, the mailbox account
 * @param subject subject of the email
 * @param bodyText body text of the email
 * @return the MimeMessage to be used to send email
 * @throws MessagingException - if a wrongly formatted address is encountered.
 */
publicstaticMimeMessagecreateEmail(StringtoEmailAddress,
StringfromEmailAddress,
Stringsubject,
StringbodyText)
throwsMessagingException{
Propertiesprops=newProperties();
Sessionsession=Session.getDefaultInstance(props,null);
MimeMessageemail=newMimeMessage(session);
email.setFrom(newInternetAddress(fromEmailAddress));
email.addRecipient(javax.mail.Message.RecipientType.TO,
newInternetAddress(toEmailAddress));
email.setSubject(subject);
email.setText(bodyText);
returnemail;
}
}

Next, encode the MimeMessage, instantiate a messages object, and set the base64URL encoded message string as the value of the raw property.

gmail/snippets/src/main/java/CreateMessage.java
importcom.google.api.services.gmail.model.Message;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjavax.mail.MessagingException;
importjavax.mail.internet.MimeMessage;
importorg.apache.commons.codec.binary.Base64;
/* Class to demonstrate the use of Gmail Create Message API */
publicclass CreateMessage{
/**
 * Create a message from an email.
 *
 * @param emailContent Email to be set to raw of message
 * @return a message containing a base64url encoded email
 * @throws IOException - if service account credentials file not found.
 * @throws MessagingException - if a wrongly formatted address is encountered.
 */
publicstaticMessagecreateMessageWithEmail(MimeMessageemailContent)
throwsMessagingException,IOException{
ByteArrayOutputStreambuffer=newByteArrayOutputStream();
emailContent.writeTo(buffer);
byte[]bytes=buffer.toByteArray();
StringencodedEmail=Base64.encodeBase64URLSafeString(bytes);
Messagemessage=newMessage();
message.setRaw(encodedEmail);
returnmessage;
}
}

Python

The following code sample shows how to create a MIME message, encode it to a base64URL string, and assign it to the raw field of the messages resource:

gmail/snippet/send mail/create_draft.py
importbase64
fromemail.messageimport EmailMessage
importgoogle.auth
fromgoogleapiclient.discoveryimport build
fromgoogleapiclient.errorsimport HttpError
defgmail_create_draft():
"""Create and insert a draft email.
 Print the returned draft's message and id.
 Returns: Draft object, including draft id and message meta data.
 Load pre-authorized user credentials from the environment.
 TODO(developer) - See https://developers.google.com/identity
 for guides on implementing OAuth2 for the application.
 """
 creds, _ = google.auth.default()
 try:
 # create gmail api client
 service = build("gmail", "v1", credentials=creds)
 message = EmailMessage()
 message.set_content("This is automated draft mail")
 message["To"] = "gduser1@workspacesamples.dev"
 message["From"] = "gduser2@workspacesamples.dev"
 message["Subject"] = "Automated draft"
 # encoded message
 encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode()
 create_message = {"message": {"raw": encoded_message}}
 # pylint: disable=E1101
 draft = (
 service.users()
 .drafts()
 .create(userId="me", body=create_message)
 .execute()
 )
 print(f'Draft id: {draft["id"]}\nDraft message: {draft["message"]}')
 except HttpError as error:
 print(f"An error occurred: {error}")
 draft = None
 return draft
if __name__ == "__main__":
 gmail_create_draft()

cURL

curl--requestPOST\
'https://gmail.googleapis.com/gmail/v1/users/me/drafts'\
--header'Authorization: Bearer ACCESS_TOKEN'\
--header'Accept: application/json'\
--header'Content-Type: application/json'\
--data'{"message":{"raw":"MESSAGE"}}'

Replace the following:

  • ACCESS_TOKEN: the access token that grants access to the API.
  • MESSAGE: the RFC 2822 formatted MIME message, encoded as base64URL.

Create messages with attachments

Creating a message with an attachment is like creating any other message, but the process of uploading the file as a multi-part MIME message depends on the programming language.

The following code samples show possible ways of creating a multi-part MIME message with an attachment:

Java

The following code sample shows how to create a multi-part MIME message. The encoding and assignment steps are the same as create messages.

gmail/snippets/src/main/java/CreateDraftWithAttachment.java
importcom.google.api.client.googleapis.json.GoogleJsonError;
importcom.google.api.client.googleapis.json.GoogleJsonResponseException;
importcom.google.api.client.http.HttpRequestInitializer;
importcom.google.api.client.http.javanet.NetHttpTransport;
importcom.google.api.client.json.gson.GsonFactory;
importcom.google.api.services.gmail.Gmail;
importcom.google.api.services.gmail.GmailScopes;
importcom.google.api.services.gmail.model.Draft;
importcom.google.api.services.gmail.model.Message;
importcom.google.auth.http.HttpCredentialsAdapter;
importcom.google.auth.oauth2.GoogleCredentials;
importjava.io.ByteArrayOutputStream;
importjava.io.File;
importjava.io.IOException;
importjava.util.Properties;
importjavax.activation.DataHandler;
importjavax.activation.DataSource;
importjavax.activation.FileDataSource;
importjavax.mail.MessagingException;
importjavax.mail.Multipart;
importjavax.mail.Session;
importjavax.mail.internet.InternetAddress;
importjavax.mail.internet.MimeBodyPart;
importjavax.mail.internet.MimeMessage;
importjavax.mail.internet.MimeMultipart;
importorg.apache.commons.codec.binary.Base64;
/* Class to demonstrate the use of Gmail Create Draft with attachment API */
publicclass CreateDraftWithAttachment{
/**
 * Create a draft email with attachment.
 *
 * @param fromEmailAddress - Email address to appear in the from: header.
 * @param toEmailAddress - Email address of the recipient.
 * @param file - Path to the file to be attached.
 * @return the created draft, {@code null} otherwise.
 * @throws MessagingException - if a wrongly formatted address is encountered.
 * @throws IOException - if service account credentials file not found.
 */
publicstaticDraftcreateDraftMessageWithAttachment(StringfromEmailAddress,
StringtoEmailAddress,
Filefile)
throwsMessagingException,IOException{
/* Load pre-authorized user credentials from the environment.
 TODO(developer) - See https://developers.google.com/identity for
 guides on implementing OAuth2 for your application.*/
GoogleCredentialscredentials=GoogleCredentials.getApplicationDefault()
.createScoped(GmailScopes.GMAIL_COMPOSE);
HttpRequestInitializerrequestInitializer=newHttpCredentialsAdapter(credentials);
// Create the gmail API client
Gmailservice=newGmail.Builder(newNetHttpTransport(),
GsonFactory.getDefaultInstance(),
requestInitializer)
.setApplicationName("Gmail samples")
.build();
// Create the email content
StringmessageSubject="Test message";
StringbodyText="lorem ipsum.";
// Encode as MIME message
Propertiesprops=newProperties();
Sessionsession=Session.getDefaultInstance(props,null);
MimeMessageemail=newMimeMessage(session);
email.setFrom(newInternetAddress(fromEmailAddress));
email.addRecipient(javax.mail.Message.RecipientType.TO,
newInternetAddress(toEmailAddress));
email.setSubject(messageSubject);
MimeBodyPartmimeBodyPart=newMimeBodyPart();
mimeBodyPart.setContent(bodyText,"text/plain");
Multipartmultipart=newMimeMultipart();
multipart.addBodyPart(mimeBodyPart);
mimeBodyPart=newMimeBodyPart();
DataSourcesource=newFileDataSource(file);
mimeBodyPart.setDataHandler(newDataHandler(source));
mimeBodyPart.setFileName(file.getName());
multipart.addBodyPart(mimeBodyPart);
email.setContent(multipart);
// Encode and wrap the MIME message into a gmail message
ByteArrayOutputStreambuffer=newByteArrayOutputStream();
email.writeTo(buffer);
byte[]rawMessageBytes=buffer.toByteArray();
StringencodedEmail=Base64.encodeBase64URLSafeString(rawMessageBytes);
Messagemessage=newMessage();
message.setRaw(encodedEmail);
try{
// Create the draft message
Draftdraft=newDraft();
draft.setMessage(message);
draft=service.users().drafts().create("me",draft).execute();
System.out.println("Draft id: "+draft.getId());
System.out.println(draft.toPrettyString());
returndraft;
}catch(GoogleJsonResponseExceptione){
// TODO(developer) - handle error appropriately
GoogleJsonErrorerror=e.getDetails();
if(error.getCode()==403){
System.err.println("Unable to create draft: "+e.getDetails());
}else{
throwe;
}
}
returnnull;
}
}

Python

Similar to the create messages example, this example also handles encoding the message to base64URL and assigning it to the raw field of the messages resource.

gmail/snippet/send mail/create_draft_with_attachment.py
importbase64
importmimetypes
importos
fromemail.messageimport EmailMessage
fromemail.mime.audioimport MIMEAudio
fromemail.mime.baseimport MIMEBase
fromemail.mime.imageimport MIMEImage
fromemail.mime.textimport MIMEText
importgoogle.auth
fromgoogleapiclient.discoveryimport build
fromgoogleapiclient.errorsimport HttpError
defgmail_create_draft_with_attachment():
"""Create and insert a draft email with attachment.
 Print the returned draft's message and id.
 Returns: Draft object, including draft id and message meta data.
 Load pre-authorized user credentials from the environment.
 TODO(developer) - See https://developers.google.com/identity
 for guides on implementing OAuth2 for the application.
 """
 creds, _ = google.auth.default()
 try:
 # create gmail api client
 service = build("gmail", "v1", credentials=creds)
 mime_message = EmailMessage()
 # headers
 mime_message["To"] = "gduser1@workspacesamples.dev"
 mime_message["From"] = "gduser2@workspacesamples.dev"
 mime_message["Subject"] = "sample with attachment"
 # text
 mime_message.set_content(
 "Hi, this is automated mail with attachment.Please do not reply."
 )
 # attachment
 attachment_filename = "photo.jpg"
 # guessing the MIME type
 type_subtype, _ = mimetypes.guess_type(attachment_filename)
 maintype, subtype = type_subtype.split("/")
 with open(attachment_filename, "rb") as fp:
 attachment_data = fp.read()
 mime_message.add_attachment(attachment_data, maintype, subtype)
 encoded_message = base64.urlsafe_b64encode(mime_message.as_bytes()).decode()
 create_draft_request_body = {"message": {"raw": encoded_message}}
 # pylint: disable=E1101
 draft = (
 service.users()
 .drafts()
 .create(userId="me", body=create_draft_request_body)
 .execute()
 )
 print(f'Draft id: {draft["id"]}\nDraft message: {draft["message"]}')
 except HttpError as error:
 print(f"An error occurred: {error}")
 draft = None
 return draft
defbuild_file_part(file):
"""Creates a MIME part for a file.
 Args:
 file: The path to the file to be attached.
 Returns:
 A MIME part that can be attached to a message.
 """
 content_type, encoding = mimetypes.guess_type(file)
 if content_type is None or encoding is not None:
 content_type = "application/octet-stream"
 main_type, sub_type = content_type.split("/", 1)
 if main_type == "text":
 with open(file, "rb"):
 msg = MIMEText("r", _subtype=sub_type)
 elif main_type == "image":
 with open(file, "rb"):
 msg = MIMEImage("r", _subtype=sub_type)
 elif main_type == "audio":
 with open(file, "rb"):
 msg = MIMEAudio("r", _subtype=sub_type)
 else:
 with open(file, "rb"):
 msg = MIMEBase(main_type, sub_type)
 msg.set_payload(file.read())
 filename = os.path.basename(file)
 msg.add_header("Content-Disposition", "attachment", filename=filename)
 return msg
if __name__ == "__main__":
 gmail_create_draft_with_attachment()

cURL

curl--requestPOST\
'https://gmail.googleapis.com/gmail/v1/users/me/drafts'\
--header'Authorization: Bearer ACCESS_TOKEN'\
--header'Accept: application/json'\
--header'Content-Type: application/json'\
--data'{"message":{"raw":"MESSAGE"}}'

Replace the following:

  • ACCESS_TOKEN: the access token that grants access to the API.
  • MESSAGE: the RFC 2822 formatted MIME message containing an attachment, encoded as base64URL.

Send messages

Once you have created a message, you can send it by supplying it in the request body of the messages.send method, as shown in the following examples:

Java

gmail/snippets/src/main/java/SendMessage.java
importcom.google.api.client.googleapis.json.GoogleJsonError;
importcom.google.api.client.googleapis.json.GoogleJsonResponseException;
importcom.google.api.client.http.HttpRequestInitializer;
importcom.google.api.client.http.javanet.NetHttpTransport;
importcom.google.api.client.json.gson.GsonFactory;
importcom.google.api.services.gmail.Gmail;
importcom.google.api.services.gmail.GmailScopes;
importcom.google.api.services.gmail.model.Message;
importcom.google.auth.http.HttpCredentialsAdapter;
importcom.google.auth.oauth2.GoogleCredentials;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.util.Properties;
importjavax.mail.MessagingException;
importjavax.mail.Session;
importjavax.mail.internet.InternetAddress;
importjavax.mail.internet.MimeMessage;
importorg.apache.commons.codec.binary.Base64;
/* Class to demonstrate the use of Gmail Send Message API */
publicclass SendMessage{
/**
 * Send an email from the user's mailbox to its recipient.
 *
 * @param fromEmailAddress - Email address to appear in the from: header
 * @param toEmailAddress - Email address of the recipient
 * @return the sent message, {@code null} otherwise.
 * @throws MessagingException - if a wrongly formatted address is encountered.
 * @throws IOException - if service account credentials file not found.
 */
publicstaticMessagesendEmail(StringfromEmailAddress,
StringtoEmailAddress)
throwsMessagingException,IOException{
/* Load pre-authorized user credentials from the environment.
 TODO(developer) - See https://developers.google.com/identity for
 guides on implementing OAuth2 for your application.*/
GoogleCredentialscredentials=GoogleCredentials.getApplicationDefault()
.createScoped(GmailScopes.GMAIL_SEND);
HttpRequestInitializerrequestInitializer=newHttpCredentialsAdapter(credentials);
// Create the gmail API client
Gmailservice=newGmail.Builder(newNetHttpTransport(),
GsonFactory.getDefaultInstance(),
requestInitializer)
.setApplicationName("Gmail samples")
.build();
// Create the email content
StringmessageSubject="Test message";
StringbodyText="lorem ipsum.";
// Encode as MIME message
Propertiesprops=newProperties();
Sessionsession=Session.getDefaultInstance(props,null);
MimeMessageemail=newMimeMessage(session);
email.setFrom(newInternetAddress(fromEmailAddress));
email.addRecipient(javax.mail.Message.RecipientType.TO,
newInternetAddress(toEmailAddress));
email.setSubject(messageSubject);
email.setText(bodyText);
// Encode and wrap the MIME message into a gmail message
ByteArrayOutputStreambuffer=newByteArrayOutputStream();
email.writeTo(buffer);
byte[]rawMessageBytes=buffer.toByteArray();
StringencodedEmail=Base64.encodeBase64URLSafeString(rawMessageBytes);
Messagemessage=newMessage();
message.setRaw(encodedEmail);
try{
// Create send message
message=service.users().messages().send("me",message).execute();
System.out.println("Message id: "+message.getId());
System.out.println(message.toPrettyString());
returnmessage;
}catch(GoogleJsonResponseExceptione){
// TODO(developer) - handle error appropriately
GoogleJsonErrorerror=e.getDetails();
if(error.getCode()==403){
System.err.println("Unable to send message: "+e.getDetails());
}else{
throwe;
}
}
returnnull;
}
}

Python

gmail/snippet/send mail/send_message.py
importbase64
fromemail.messageimport EmailMessage
importgoogle.auth
fromgoogleapiclient.discoveryimport build
fromgoogleapiclient.errorsimport HttpError
defgmail_send_message():
"""Create and send an email message
 Print the returned message id
 Returns: Message object, including message id
 Load pre-authorized user credentials from the environment.
 TODO(developer) - See https://developers.google.com/identity
 for guides on implementing OAuth2 for the application.
 """
 creds, _ = google.auth.default()
 try:
 service = build("gmail", "v1", credentials=creds)
 message = EmailMessage()
 message.set_content("This is automated draft mail")
 message["To"] = "gduser1@workspacesamples.dev"
 message["From"] = "gduser2@workspacesamples.dev"
 message["Subject"] = "Automated draft"
 # encoded message
 encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode()
 create_message = {"raw": encoded_message}
 # pylint: disable=E1101
 send_message = (
 service.users()
 .messages()
 .send(userId="me", body=create_message)
 .execute()
 )
 print(f'Message Id: {send_message["id"]}')
 except HttpError as error:
 print(f"An error occurred: {error}")
 send_message = None
 return send_message
if __name__ == "__main__":
 gmail_send_message()

cURL

curl--requestPOST\
'https://gmail.googleapis.com/gmail/v1/users/me/messages/send'\
--header'Authorization: Bearer ACCESS_TOKEN'\
--header'Accept: application/json'\
--header'Content-Type: application/json'\
--data'{"raw":"MESSAGE"}'

Replace the following:

  • ACCESS_TOKEN: the access token that grants access to the API.
  • MESSAGE: the RFC 2822 formatted MIME message, encoded as base64URL.

If you're trying to send a reply and want the email to be grouped into a thread, make sure that:

  1. The Subject headers match
  2. The References and In-Reply-To headers follow the RFC 2822 standard.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026年07月22日 UTC.