title: Why does Gmail API fail with a 403 error, using code that works properly for Google Calendar API?
body: <p>I'm following these guides: <a href="https://developers.google.com/google-apps/calendar/quickstart/python" rel="nofollow noreferrer">https://developers.google.com/google-apps/calendar/quickstart/python</a>, <a href="https://developers.google.com/gmail/api/quickstart/python" rel="nofollow noreferrer">https://developers.google.com/gmail/api/quickstart/python</a>.</p>
  
  <p>I've completed all the setup steps for both, and the calendar API code works fine, while the Gmail API code fails with a 403 error. What's causing this? What's different between these two APIs?</p>
  
  <p>I've combined the code from these two different examples, so they are sharing as much of the API setup code as possible, to rule out a mistake there.</p>
  
  <p>I've disabled and re-enabled Gmail API in Google Dev Console.</p>
  
  <p>As mentioned <a href="https://stackoverflow.com/a/23904532/137838">here</a>, I've enabled the Contacts and Google+ APIs.</p>
  
  <p>As mentioned <a href="https://stackoverflow.com/questions/32143126/how-do-i-get-around-httperror-403-insufficient-permission-gmail-api-python">here</a>, I've tried all three combinations for Gmail scopes - just the scope from the example, just '<a href="https://mail.google.com/" rel="nofollow noreferrer">https://mail.google.com/</a>', or both.</p>
  
  <p><a href="https://stackoverflow.com/a/22872526/137838">This</a> answer, as well as several other sources, suggest 'setting the "Referers" to "Any referer allowed"', but there is no page in Dev Console I can find that contains this option. I can add a domain through the "domain verification" tab, but this does not seem to affect anything.</p>
  
  <p>Code:</p>
  
  <pre><code>import httplib2
  import os
  from pprint import pprint
  
  from apiclient import discovery
  import oauth2client
  from oauth2client import client
  from oauth2client import tools
  
  import datetime
  
  try:
      import argparse
      flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
  except ImportError:
      flags = None
  
  
  class GoogleApi(object):
      client_secret_file = 'client_secret.json'
      application_name = 'test_app'
  
      def __init__(self):
          self.credentials = self.get_credentials()
          self.http = self.credentials.authorize(httplib2.Http())
          self.service = discovery.build(self.api_name, self.api_version, http=self.http)
  
      def get_credentials(self):
          """Gets valid user credentials from storage.
  
          If nothing has been stored, or if the stored credentials are invalid,
          the OAuth2 flow is completed to obtain the new credentials.
  
          Returns:
              Credentials, the obtained credential.
          """
          home_dir = os.path.expanduser('~')
          credential_dir = os.path.join(home_dir, '.credentials')
          if not os.path.exists(credential_dir):
              os.makedirs(credential_dir)
          credential_path = os.path.join(credential_dir,
                                         'test-app.json')
  
          store = oauth2client.file.Storage(credential_path)
          credentials = store.get()
          if not credentials or credentials.invalid:
              flow = client.flow_from_clientsecrets(self.client_secret_file, self.scopes)
              flow.user_agent = self.application_name
              if flags:
                  credentials = tools.run_flow(flow, store, flags)
              else:  # Needed only for compatability with Python 2.6
                  credentials = tools.run(flow, store)
              print 'Storing credentials to ' + credential_path
          return credentials
  
  
  class CalendarApi(GoogleApi):
      scopes = 'https://www.googleapis.com/auth/calendar.readonly'
      api_name = 'calendar'
      api_version = 'v3'
  
      def get_calendar_ids(self):
          cl = self.service.calendarList().list().execute()
          ids = [x['id'] for x in cl['items']]
          return ids
  
  
  class GmailApi(GoogleApi):
  
      scopes = 'https://mail.google.com/'
      #scopes = 'https://www.googleapis.com/auth/gmail.readonly'
      api_name = 'gmail'
      api_version = 'v1'
  
      def get_labels(self):
          ml = self.service.users().labels().list(userId='me').execute()
          labels = results.get('labels', [])
          return labels
  
  
  def main():
      cc = CalendarApi()
      ids = cc.get_calendar_ids()
      print(ids)
  
      m = GmailApi()
      labels = m.get_labels()
      print(labels)
  
  
  if __name__ == '__main__':
      main()
  </code></pre>
  
  <p>Current error ("Insufficient Permission"):</p>
  
  <pre><code>Traceback (most recent call last):
    File "gmail_api_test.py", line 92, in &lt;module&gt;
      main()
    File "gmail_api_test.py", line 87, in main
      labels = m.get_labels()
    File "gmail_api_test.py", line 76, in get_labels
      ml = self.service.users().labels().list(userId='me').execute()
    File "/usr/local/lib/python2.7/site-packages/oauth2client/util.py", line 140, in positional_wrapper
      return wrapped(*args, **kwargs)
    File "/usr/local/lib/python2.7/site-packages/googleapiclient/http.py", line 729, in execute
      raise HttpError(resp, content, uri=self.uri)
  googleapiclient.errors.HttpError: &lt;HttpError 403 when requesting https://www.googleapis.com/gmail/v1/users/me/labels?alt=json returned "Insufficient Permission"&gt;
  </code></pre>
  
  <p>Error from a previous version of the code ("Access Not Configured. The API (Gmail API) is not enabled for your project. Please use the Google Developers Console to update your configuration."):</p>
  
  <pre><code>Traceback (most recent call last):
    File "gmail_demo.py", line 71, in &lt;module&gt;
      main()
    File "gmail_demo.py", line 59, in main
      results = service.users().labels().list(userId='me').execute()
    File "/usr/local/lib/python2.7/site-packages/oauth2client/util.py", line 142, in positional_wrapper
      return wrapped(*args, **kwargs)
    File "/usr/local/lib/python2.7/site-packages/googleapiclient/http.py", line 729, in execute
      raise HttpError(resp, content, uri=self.uri)
  googleapiclient.errors.HttpError: &lt;HttpError 403 when requesting https://www.googleapis.com/gmail/v1/users/me/labels?alt=json returned "Access Not Configured. The API (Gmail API) is not enabled for your project. Please use the Google Developers Console to update your configuration."&gt;
  </code></pre>