Google Sheets API returns "The caller does not have permission" when using server key

Google ApiGoogle SheetsGoogle Sheets-Api

Google Api Problem Overview


I've generated a server key in the API Manager and attempted to execute the following on my Mac:

curl 'https://sheets.googleapis.com/v4/spreadsheets/MySheetID?ranges=A1:B5&key=TheServerKeyIGeneratedInAPIManager'

But this is what it returns:

{
 "error": {
    "code": 403,
    "message": "The caller does not have permission",
    "status": "PERMISSION_DENIED"
  }
}

What am I doing wrong here?

Google Api Solutions


Solution 1 - Google Api

To solve this issue, try to:

  1. Create a service account: https://console.developers.google.com/iam-admin/serviceaccounts/
  2. In options, create a key: this key is your usual client_secret.json - use it the same way
  3. Make the role owner for the service account (Member name = service account ID = service account email ex: [email protected]
  4. Copy the email address of your service account = service account ID
  5. Simply go in your browser to the Google sheet you want to interact with
  6. Go to SHARE on the top right of your screen
  7. Go to advanced settings and share it with an email address of your service account ex: [email protected]

Solution 2 - Google Api

I know it is a little late to answer but for other people struggling with the same issue.
Just change the permission of the sheet to public on your drive so it can be accessed without authentication via API calls.

To change access:

  1. Open sheet in google drive
  2. On top right corner, click share
  3. On bottom of prompt window, click advanced
  4. Change permission to public or people with link (no signin required)

Send API request to fetch data from sheets without authentication.

Note: if the sheet contains sensitive data then it is not safe to make it public and rather do it with Authenticated access.

Solution 3 - Google Api

Make sure to pay attention to @KishanPatel's comment:

> Also, you can share this sheet with specific email Ex. your service > account (project) email. "client_email": > "[email protected]", This will allow > to access sheet by your script.

Solution 4 - Google Api

The easiest way is to fix using gcloud cli. More docs here https://cloud.google.com/pubsub/docs/quickstart-cli#before-you-begin

install gcloud

sudo apt-get install google-cloud-sdk

then call

gcloud init

then check your active project and credentials

gcloud config configurations list

If it is not ok, make sure you are authenticated with the correct account:

gcloud auth list
* account 1
  account 2

Change to the project's account if not:

gcloud config set account `ACCOUNT`

Depending on the account, the project list will be different:

gcloud projects list

- project 1
- project 2...

Switch to intended project:

gcloud config set project `PROJECT NAME`

Then Create Application Default Credentials with gcloud auth application-default login, and then google-cloud will automatically detect such credentials.

Solution 5 - Google Api

Visual Simplification of the Answers:

Option 1 - Turn the file into public (if sheets the sheet contains sensitive data) enter image description here

Option 2 - Share file with Service Account Email (IAM & Admin -> Service Accounts -> Details -> Email)

enter image description here enter image description here

Solution 6 - Google Api

My 10 cents... A simple example to read the sheet using Java.

    private Credential getCredentials() throws IOException {
            final InputStream accessKey = new ByteArrayInputStream("<credential json>");
            final GoogleCredential credential = GoogleCredential.fromStream(accessKey)
                    .createScoped(Collections.singleton(SheetsScopes.SPREADSHEETS_READONLY));
            return credential;
        }

    private HttpTransport httpTransport() {
            try {
                return GoogleNetHttpTransport.newTrustedTransport();
            } catch (GeneralSecurityException | IOException e) {
                throw new SpreadSheetServiceException(e);
            }
        }


    Sheets service = new Sheets.Builder(httpTransport(), JSON_FACTORY, getCredentials())
                    .setApplicationName("app-name")
                    .build();
            ValueRange response = service.spreadsheets().values()
                    .get("<spread_sheet_id>", "A1:A")
                    .execute();

Solution 7 - Google Api

In my case, solving this problem turned out to be trivial. You just have to:

  1. Enter the google sheet that we want to remotely edit.
  2. In the upper right corner, set - anyone who has the link can enter
  3. Most importantly - on the right side you need to set permissions for people who have the link as 'editor'

if you still do not have permission, it means that you have to go to the website: https://console.developers.google.com/iam-admin/iam/ then select your project, then select "Service accounts" and create a new one as role "owner" or" editor" for the project for example (or use one that already exists and click "create new key")

The "key" is a json file that will be downloaded when you create the account (or use "create new key" there).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionInstabriteView Question on Stackoverflow
Solution 1 - Google ApiThomas BeaudouinView Answer on Stackoverflow
Solution 2 - Google ApiWLatifView Answer on Stackoverflow
Solution 3 - Google ApiHorenView Answer on Stackoverflow
Solution 4 - Google ApiYuliia AshomokView Answer on Stackoverflow
Solution 5 - Google ApiEmanuelView Answer on Stackoverflow
Solution 6 - Google ApiPalma DiasView Answer on Stackoverflow
Solution 7 - Google ApiWojciech MoszczyńskiView Answer on Stackoverflow