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

118,838

Solution 1

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

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

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

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

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

Share:
118,838
Instabrite
Author by

Instabrite

Updated on July 08, 2022

Comments

  • Instabrite
    Instabrite almost 2 years

    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?

    • DaImTo
      DaImTo over 7 years
      Key is for accessing public data, what you are doing requires authenticated access.
    • dpkrai96
      dpkrai96 over 4 years
      In most of the cases there is some problem of scopes. Please check and verify which scopes are required by script.
    • Jason Ellis
      Jason Ellis over 2 years
      Also make sure your share settings are set to "Anyone with the link can view" - mine didn't work without that (even though it was published to the web).
  • Kishan Patel
    Kishan Patel almost 7 years
    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.
  • Maulik Dodia
    Maulik Dodia over 6 years
    Thanks bro. There is no written things in documentation to like you have mentioned.
  • Edward
    Edward about 6 years
    Agreed @MaulikDodia. Google API docs say it here, but it's not clear for people that just want to use the API to display data on a public website. I'm in the process of writing a how-to on all this. I'll send you a DM of it when I'm done.
  • Maulik Dodia
    Maulik Dodia about 6 years
    Thanks a lot friend@user3411192
  • Jason F
    Jason F about 5 years
    this worked for me. by the way: in google cloud admin go to... project > IAM & Admin > Service Accounts.... If you've setup service accounts, you'll see a special email for each respective service account. Make sure you've also enabled the Google Sheets API. Literally, you just share the service account email address from the google sheet "share" button.
  • user1102171
    user1102171 almost 5 years
    yes ...key is to just share the document with the service account email....
  • Cardinal System
    Cardinal System almost 5 years
    The key json is very different from the credentials json which I obtained from the Java quickstart guide (for the Sheets API). How do I implement it?
  • Stephen Phillips
    Stephen Phillips about 4 years
    How do you use the client secret? Can you make an API key with a service account instead?
  • Abdul Malik
    Abdul Malik over 3 years
    Thank you so much. This should be included in the documentation or something.
  • Kshitiz Sharma
    Kshitiz Sharma about 3 years
    Hi. What if I dont want to use 'share' feature. I want to use get/update any users files using oauth 2.0. User should not be required to know my clients service account to get me the access of his file. How can i achieve this?
  • Flavian Hautbois
    Flavian Hautbois over 2 years
    Hi, in case you did all the steps above and still get a 403, check if the service account appears greyed out when you click on "share". If it does, a rule is excluding its access to the Sheet. In my case a DLP rule was disabling external sharing (and service accounts use an external domain). Issue tracked here: issuetracker.google.com/issues/209977112
  • machineghost
    machineghost almost 2 years
    I have a public sheet and I'm still getting this error.