Working with Drafts

Drafts represent unsent messages with the DRAFT system label applied. The message contained within the draft cannot be edited once created, but it can be replaced. In this sense, the draft resource is simply a container that provides a stable ID because the underlying message IDs change every time the message is replaced.

Message resources inside a draft have similar behavior to other messages except for the following differences:

  • Draft messages cannot have any label other than the DRAFT system label.
  • When the draft is sent, the draft is automatically deleted and a new message with an updated ID is created with the SENT system label. This message is returned in the drafts.send response.


Creating draft messages

Your application can create drafts using the drafts.create method. The general process is to:

  1. Create a MIME message that complies with RFC 2822.
  2. Convert the message to a base64url encoded string.
  3. Create a draft, setting the value of the drafts.message.raw field to the encoded string.

The following code examples demonstrate the process.


Creating an email message can be greatly simplified with the MimeMessage class in the javax.mail.internet package. The following example shows how to create the email message, including the headers (download the example):

     * Create a MimeMessage using the parameters provided.
     * @param to email address of the receiver
     * @param from 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
    public static MimeMessage createEmail(String to,
                                          String from,
                                          String subject,
                                          String bodyText)
            throws MessagingException {
        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);

        MimeMessage email = new MimeMessage(session);

        email.setFrom(new InternetAddress(from));
                new InternetAddress(to));
        return email;

The next step is to encode the MimeMessage, instantiate a Message object, and set the base64url encoded message string as the value of the raw property.

     * 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
     * @throws MessagingException
    public static Message createMessageWithEmail(MimeMessage emailContent)
            throws MessagingException, IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        byte[] bytes = buffer.toByteArray();
        String encodedEmail = Base64.encodeBase64URLSafeString(bytes);
        Message message = new Message();
        return message;

Once you have a created a Message, you can create a Draft object and pass it to the drafts.create method.

     * Create draft email.
     * @param service an authorized Gmail API instance
     * @param userId user's email address. The special value "me"
     * can be used to indicate the authenticated user
     * @param emailContent the MimeMessage used as email within the draft
     * @return the created draft
     * @throws MessagingException
     * @throws IOException
    public static Draft createDraft(Gmail service,
                                    String userId,
                                    MimeMessage emailContent)
            throws MessagingException, IOException {
        Message message = createMessageWithEmail(emailContent);
        Draft draft = new Draft();
        draft = service.users().drafts().create(userId, draft).execute();

        System.out.println("Draft id: " + draft.getId());
        return draft;


The following code sample demonstrates creating a MIME message, encoding to a base64url string, and assigning it to the raw field of the Message resource (download example):

def create_message(sender, to, subject, message_text):
  """Create a message for an email.

    sender: Email address of the sender.
    to: Email address of the receiver.
    subject: The subject of the email message.
    message_text: The text of the email message.

    An object containing a base64url encoded email object.
  message = MIMEText(message_text)
  message['to'] = to
  message['from'] = sender
  message['subject'] = subject
  return {'raw': base64.urlsafe_b64encode(message.as_string())}

Once you have created a Message object, you can pass it to the drafts.create method to create a Draft object.

def create_draft(service, user_id, message_body):
  """Create and insert a draft email. Print the returned draft's message and id.

    service: Authorized Gmail API service instance.
    user_id: User's email address. The special value "me"
    can be used to indicate the authenticated user.
    message_body: The body of the email message, including headers.

    Draft object, including draft id and message meta data.
    message = {'message': message_body}
    draft = service.users().drafts().create(userId=user_id, body=message).execute()

    print 'Draft id: %s\nDraft message: %s' % (draft['id'], draft['message'])

    return draft
  except errors.HttpError, error:
    print 'An error occurred: %s' % error
    return None

Updating drafts

Similarly to creating a draft, to update a draft you must supply a Draft resource in the body of your request with the draft.message.raw field set to a base64url encoded string containing the MIME message. Because messages cannot be updated, the message contained in the draft is destroyed and replaced by the new MIME message supplied in the update request.

You can retrieve the current MIME message contained in the draft by calling drafts.get with the parameter format=raw.

For more information, see drafts.update.

Sending drafts

When sending a draft, you can choose to send the message as-is or as with an updated message. If you are updating the draft content with a new message, supply a Draft resource in the body of the drafts.send request; set the of the draft to be sent; and set the draft.message.raw field to the new MIME message encoded as a base64url encoded string. For more information, see drafts.send.