Developer

Fix "Gmail API Has Not Been Used" in Apps Script

Apps Script says the Gmail API has not been used in project X? Enabling it may not be enough. Here's the consent screen and project switch that fixed it.

By Makeinfo Team
#google-apps-script #gmail-api #google-cloud #oauth #google-sheets-add-on

We hit “Gmail API has not been used in project” while testing the first real send from our mail merge add-on for Google Sheets. The code was fine. The problem was the Google Cloud project sitting behind the Apps Script project. Enabling the API was the obvious fix, and it wasn’t enough on its own.

Here’s the exact error, what we tried, and the two steps that got email flowing.


The error

Our add-on sends mail through the Gmail REST API. It calls it with UrlFetchApp and the user’s own OAuth token, not with GmailApp. We chose that route deliberately: GmailApp forces the restricted mail.google.com scope, while gmail.send is only sensitive. That difference means OAuth verification without a paid CASA security assessment.

The send looks roughly like this:

const res = UrlFetchApp.fetch(
  'https://gmail.googleapis.com/gmail/v1/users/me/messages/send',
  {
    method: 'post',
    contentType: 'application/json',
    headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() },
    payload: JSON.stringify({ raw: encodedMessage }),
    muteHttpExceptions: true,
  }
);

The first test email came back as a 403. Our sidebar translated it into:

Gmail rejected the test email: The Gmail API is turned off for this add-on’s Google Cloud project (8578xxxxxxx). Enable it under APIs & Services > Library > Gmail API, wait a few minutes, then try again.

Underneath is Google’s standard message: “Gmail API has not been used in project 8578xxxxxxx before or it is disabled.”

Nothing in the script mentioned that project number. It came from the default Google Cloud project that Apps Script creates for every new script.


Why the Gmail API was off

Every OAuth token a script gets is issued by the Cloud project the script is linked to. When you call a Google API directly over HTTP, that project must have the API enabled. Otherwise Google refuses the call, no matter what scopes the user granted.

Apps Script’s built-in services (SpreadsheetApp, GmailApp and so on) hide this from you. A raw UrlFetchApp call to gmail.googleapis.com doesn’t. Advanced services turn their API on for you. Plain HTTP calls don’t.

New scripts are linked to a default project that Apps Script manages. You don’t get to fully configure it, and it has no Gmail API enabled.


Attempt one: enable the API

The error names the project, so we opened the Gmail API page for it in the Cloud Console and clicked Enable.

The Console then showed this:

To call this API from your own applications, you may need to create credentials.

That line reads like there’s another step. There isn’t, for Apps Script. It’s aimed at standalone apps that bring their own OAuth client or API key. Apps Script already supplies the credential through ScriptApp.getOAuthToken(). You don’t need to create credentials.

Enabling the API on a hidden default project is still a fragile fix, though. We needed a project we controlled anyway, because a Marketplace listing requires a standard Cloud project for OAuth verification. So we moved the script to one.


In the Google Cloud project you want to use:

  1. Go to APIs & Services → Library, find Gmail API, and enable it.
  2. Go to APIs & Services → OAuth consent screen (now under Google Auth Platform in newer consoles).
  3. Fill in the app name, support email and developer contact.
  4. Add the scopes the script uses. Take them from the oauthScopes list in appsscript.json, and add nothing else.
  5. While testing, add your own account as a test user.

This step is what unblocks the next one. Apps Script refuses to link a project that has no consent screen configured.

  1. In the Cloud Console dashboard, copy the project number. Use the number, not the project ID.
  2. Open the script, then go to Project Settings (the gear icon).
  3. Under Google Cloud Platform (GCP) Project, click Change project.
  4. Paste the project number and confirm.

Step 3: Re-authorize

Reload the spreadsheet and open the add-on again. Google shows a fresh permissions prompt, because the old token was issued by the old project. Accept it, then send the test.

The test email went through on the first try.


Quick checklist

If you call a Google API with UrlFetchApp from Apps Script:

  • The API is enabled on the project the script is actually linked to. Check the number under Project Settings.
  • That project has an OAuth consent screen with your script’s scopes.
  • The script points at your standard project, not the default one.
  • You re-authorized after switching.
  • You waited a few minutes after enabling. The change isn’t instant.
  • You ignored the “create credentials” prompt.

What we’d do differently

We’d create the standard Cloud project before writing the first UrlFetchApp call. Every add-on headed for the Google Workspace Marketplace needs one eventually. The default project only delays the moment you find out.

The project switch has one more cost: everyone who already authorized the script has to authorize again. Doing it at the start means that “everyone” is just you.

Google’s own write-up is Google Cloud projects for Apps Script. If you’re building Sheets add-ons, see how we store API keys with PropertiesService and using Google Sheets as a database with Apps Script.