Contents
Prerequisites
All you need is a Google account (a regular Gmail account works fine). No credit card is required anywhere in this flow: both the Gmail API and Calendar API have generous free quotas, more than enough for individual developers.
Create a Google Cloud project
Open https://console.cloud.google.com/projectcreate (or click "New Project" from the project dropdown at the top of the console).
- In "Project name" enter something memorable, e.g. api-course-demo (a project ID is auto-generated below the name and cannot be changed later).
- For a personal account, leave "Location" as "No organization".
- Click Create. After about 10 seconds the bell icon in the top right shows a notification "Creating project: api-course-demo ✔".
- Click "Select project" in the notification, or switch to the new project via the project dropdown at the top. From here on, always confirm the top-left corner shows this project.
Enable the Gmail API
Top-left menu ☰ → APIs & Services → Library, search "Gmail"; or open directly https://console.cloud.google.com/apis/library/gmail.googleapis.com.
After clicking Enable, it spins for about 5–10 seconds, then automatically lands on the "API/Service Details" page, showing Enabled. A banner at the top will suggest "You may need credentials to call this API from your own application" — we'll create credentials in step 5.
Enable the Google Calendar API
Same process: search the library for "Calendar" and choose Google Calendar API; or open directly https://console.cloud.google.com/apis/library/calendar-json.googleapis.com.
Click Enable; once the status changes to "Enabled" you're done. The project now has both APIs available — next we handle authorization.
Configure the OAuth consent screen (Google Auth Platform)
Left sidebar APIs & Services → OAuth consent screen, which takes you to the "Google Auth Platform". A new project will show "Google Auth Platform not configured" — click Get Started.
The setup wizard has 4 steps (as tested):
- App Information: for "App name" enter something like API Course Demo (this is what users see on the consent screen); for "User support email" pick your own Gmail from the dropdown. Click "Next".
- Audience: choose External. A personal Gmail account has no Workspace organization, so External is the only option; the app will launch in "Testing" mode, usable only by accounts on the test user list. Click "Next".
- Contact Information: enter your email (used for Google project change notifications). Click "Next".
- Finish: check "I agree to the Google API Services: User Data Policy" → click "Continue" → click Create. A "OAuth configuration created!" message appears at the bottom.
CreateCancel
Create an OAuth client ID (credentials)
Google Auth Platform left sidebar → Clients → Create Client (or APIs & Services → Credentials → Create Credentials → OAuth client ID).
After clicking Create, an "OAuth client created" dialog pops up:
ⓘ Only test users listed on the OAuth consent screen have OAuth access
| Client ID | 1454707•••••-9t3e7t•••••••••••••.apps.googleusercontent.com 📋 |
|---|
Configure data access (scopes)
Google Auth Platform → Data Access → Add or Remove Scopes. A "Update selected scopes" panel slides out from the right, listing all scopes for your enabled APIs (which is why we did steps 2 and 3 first).
- In "Filter" type gmail.send and press Enter, then check the Gmail API scope .../auth/gmail.send ("Send email on your behalf").
- Clear the filter, type calendar.events, and check the Google Calendar API scope .../auth/calendar.events ("View and edit events on all your calendars").
- Scroll to the bottom of the panel and click Update, then back on the page click Save.
| API | Scope | User-facing description |
|---|---|---|
| Gmail API | .../auth/gmail.send | Send email on your behalf 🗑 |
| Google Calendar API | .../auth/calendar.events | View and edit events on all your calendars 🗑 |
Add a test user
While your app is in "Testing" status, only accounts on the test user list can complete OAuth authorization. Google Auth Platform → Audience → in the test users section click + Add users.
| User info |
|---|
| your-account@gmail.com 🗑 |
Enter the Gmail address you'll use for testing (usually your own account) and click Save. The limit is 100 users.
Call the API (Python example)
Put the credentials.json file downloaded in step 5 in the same folder as your script, then install the packages:
pip install google-auth-oauthlib google-api-python-client
The first run automatically opens a browser; sign in with your test user account and grant consent (you'll see "Google hasn't verified this app" — just click "Continue", since it's your own app). After authorizing, the token is cached locally so you won't need to sign in again.
# demo.py — send an email + create a calendar event from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build import base64, os.path, pickle from email.mime.text import MIMEText SCOPES = [ "https://www.googleapis.com/auth/gmail.send", "https://www.googleapis.com/auth/calendar.events", ] # --- OAuth authorization (opens a browser the first time) --- creds = None if os.path.exists("token.pickle"): with open("token.pickle", "rb") as f: creds = pickle.load(f) if not creds or not creds.valid: flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES) creds = flow.run_local_server(port=0) with open("token.pickle", "wb") as f: pickle.dump(creds, f) # --- Gmail: send an email --- gmail = build("gmail", "v1", credentials=creds) msg = MIMEText("Hello, this email was sent via the Gmail API!") msg["to"] = "someone@example.com" msg["subject"] = "Gmail API test" raw = base64.urlsafe_b64encode(msg.as_bytes()).decode() gmail.users().messages().send(userId="me", body={"raw": raw}).execute() print("Email sent!") # --- Calendar: create an event --- cal = build("calendar", "v3", credentials=creds) event = { "summary": "API course exercise", "start": {"dateTime": "2026-07-20T10:00:00+08:00"}, "end": {"dateTime": "2026-07-20T11:00:00+08:00"}, } created = cal.events().insert(calendarId="primary", body=event).execute() print("Event created:", created.get("htmlLink"))
FAQ
Q1: "Access denied" error during authorization (403: access_denied)?
The signed-in account isn't on the test user list. Go back to step 7 and add it.
Q2: "Google hasn't verified this app" warning appears?
Normal for testing mode. Click "Continue" (sometimes hidden under an "Advanced" link) — it's fine since this is your own app.
Q3: The token stops working after a few days and asks you to sign in again?
In testing mode, the refresh token is valid for 7 days. Delete token.pickle and re-authorize, or publish the app to production.
Q4: Can't find the "OAuth consent screen" menu item?
Since 2024, Google folded it into "Google Auth Platform". Path: APIs & Services → OAuth consent screen, or open console.cloud.google.com/auth/overview directly.
Q5: The API is enabled, but the program still reports "API not enabled"?
You likely selected the wrong project. Check the project name in the top-left of the console, and confirm credentials.json was downloaded from that same project.