PasteSheet icon PasteSheet logo mark — a spreadsheet grid with a curly brace on a green rounded square PasteSheet

Google Sheets API authentication: API key vs OAuth vs service account

Use an API key for public data, OAuth when a person grants access to their own sheets, and a service account for an unattended workload with files shared to that bot identity. The credential is only half the decision: the scope and where the code runs matter just as much.

Last updated

Key facts

  • A standard API key does not authenticate a principal. It associates a public request with a Cloud project for quota and restrictions. source
  • Google recommends drive.file for per-file access. It is non-sensitive; spreadsheets.readonly can see every spreadsheet the user can access and is sensitive. source
  • Sheets authorization scopes apply to the whole spreadsheet file. They cannot be limited to one tab. source
  • Cloud IAM roles do not grant access to Google Workspace files. A service account opens a specific sheet only after that file is shared with its email address. source
  • Google recommends avoiding user-managed service-account keys when an attached service account or Workload Identity Federation can provide short-lived credentials instead. source

Which Google Sheets API credential should you use?

Choose based on whose data the app reads, not which setup tutorial looks shortest. An API key has no user identity, so it only works for data already public. OAuth represents a person who consented to let your app act on their behalf. A service account represents the application itself, like a bot with its own email address.

All three start with a Google Cloud project and the Sheets API enabled. What changes is who Google believes is calling, which spreadsheets that identity can open, and which secrets or tokens you must keep safe.

The decision in one table

API key OAuth client Service account
Identity No principal; identifies the Cloud project The person who grants consent A non-human Google identity
Data it can read Publicly available sheets Sheets the consenting user can access Sheets shared directly with the service-account email
User interaction None Consent screen and redirect None at runtime
Best fit Public read-only data Multi-user apps and private user files Scheduled jobs and backend automation
Credential to protect Restricted API key Client secret and refresh tokens Prefer attached identity or federation; otherwise a JSON private key
Wrong fit Private sheets or write access One fixed sheet read by one server A consumer app acting as many unrelated users

API keys: public data, not private access

A standard Google API key does not authenticate a principal. It associates the request with your Cloud project for quota and API restrictions. With no person or service account attached to the request, Google cannot use private file permissions to let it through. That is why an API key is appropriate only for a sheet already shared publicly.

The key still needs protection from quota theft. Restrict it to the Google Sheets API and restrict where it can be used: HTTP referrers for a browser app, IP addresses for a server, or the matching mobile application restriction. A browser key is visible to anyone using developer tools, so the restriction is the control. Hiding it in minified JavaScript is not.

A public read with an API key

For a public spreadsheet, the key travels as the key query parameter. This reads a range through the official spreadsheets.values.get method:

terminal
curl 'https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID/values/Sheet1!A1:D10?key=YOUR_API_KEY'

OAuth: when the user owns the sheet

Use OAuth when your application needs to open private spreadsheets belonging to the person using it. Your app redirects the user to Google, the user approves specific scopes, and Google returns an authorization code. Your server exchanges that code for an access token and, when offline access is requested, a refresh token.

The access token belongs in an Authorization: Bearer header. Access tokens expire; the refresh token is what lets a server continue reading after the user leaves. Treat refresh tokens like passwords: store them encrypted, never put them in browser storage, and handle revocation by sending the user through consent again.

Google's current Auth Platform separates setup into Branding, Audience, Data Access, and Clients. In Testing mode, only listed test users can authorize the app, and grants involving Sheets scopes expire after seven days. Moving a public app to production can require verification depending on the scopes it requests.

OAuth and service accounts send the same header

OAuth and service accounts differ in how they obtain a token, not how the Sheets request uses it. Both ultimately call the API with a short-lived bearer token:

terminal
curl \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  'https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID/values/Sheet1!A1:D10'

Service accounts: an application identity, not an API key

A service account is a separate, non-human identity. It does not automatically inherit access to your spreadsheets. For one private sheet, share the file with the service account's email address just as you would share it with a colleague. Google Cloud IAM roles do not grant access to Google Workspace files; the file share is the permission that matters.

This is a good fit for a scheduled import, an internal backend, or a job that always reads the same small set of sheets without a person present. It is usually the wrong identity for a SaaS product whose customers each expect to connect their own Drive. OAuth preserves which user granted access and lets that user revoke it.

Do not casually download a service-account JSON key because an old tutorial says to. Google recommends avoiding user-managed service-account keys when possible. On Google Cloud, attach the service account to the workload. Outside Google Cloud, prefer Workload Identity Federation when your platform supports it. Create a JSON key only when those options do not fit, keep it out of the repository and filesystem where possible, and rotate it like any other long-lived secret.

The scope often matters more than the credential

OAuth users and service accounts still need authorization. Ask for the narrowest scope that supports the product:

Scope Access Google classification
drive.file Only files the user opens, creates, or shares with the app Recommended, non-sensitive
spreadsheets.readonly Read every spreadsheet the user can access Sensitive
spreadsheets Read and write every spreadsheet the user can access Sensitive
drive.readonly Read and download every Drive file Restricted
drive Read, create, edit, and delete every Drive file Restricted

Two scope details most implementations miss

First, spreadsheets.readonly sounds conservative, but it can see all spreadsheets the user can access and is classified as sensitive. For an app that lets a user choose specific files, Google recommends drive.file. It is non-sensitive and file-scoped, which is a much smaller blast radius.

Second, the Sheets scopes apply to an entire spreadsheet file, not one tab inside it. If your product promises tab-level access or read-only behaviour while holding a broader scope, that guarantee must be enforced by your application. A scope is the maximum Google permits; it is not proof that your code uses every permitted operation.

The failures that look like API bugs

  • "This app isn't verified": the OAuth client is requesting sensitive or restricted scopes without the required production verification. During development, keep the app in Testing and list the accounts that should have access.
  • The token worked last week and suddenly stopped: Testing-mode grants involving Sheets scopes expire after seven days, or the user revoked access. Refresh when possible; otherwise ask the user to authorize again.
  • origin_mismatch: the browser origin, including scheme and port, does not exactly match an authorized JavaScript origin in the OAuth client.
  • Insufficient authentication scopes: the token is valid, but it was minted without a scope that permits the attempted Sheets operation. Changing the scope in code does not upgrade an existing token; request consent again.
  • A service account cannot find the spreadsheet: share the file with the service-account email. Giving the account a Cloud IAM role does not grant Workspace file access.

When you do not need to own this authentication stack

If the job is simply "make this sheet readable as JSON," building Google authentication may be work around the actual problem. A link-shared sheet can be published through PasteSheet by pasting its URL. A restricted sheet can stay restricted: connect Google, choose the exact file in Google Picker, and PasteSheet handles the file-scoped grant.

The result is a cached, typed, row-oriented REST API with filtering, sorting, pagination, and an MCP endpoint. PasteSheet has no write path to the source sheet. Use Google's API directly when you need writes, custom spreadsheet operations, or a first-party integration across many user files. Use the hosted endpoint when you need one sheet published safely and quickly.

Publish a sheet without your own Google credentials

MCP is included on the Free plan. Connect any public endpoint over MCP with no Google Cloud project and no credit card. Private endpoints and the account-wide workspace server need a paid plan (from Starter ($9/mo)) for the keys and OAuth they authenticate with.

Pro adds full-text search and aggregation (count, sum, avg, group_by) that your AI agent can call through query_rows.

Free

For side projects and trying things out.

$0 /mo
Endpoints
3
Requests / mo
2,000
Row cap
500
  • MCP for AI agents
  • Private endpoints & keys
  • Custom cache TTL

Frequently asked questions

Can a Google Sheets API key read a private spreadsheet?

No. A standard API key identifies the Cloud project but not a user or service account, so it cannot satisfy a private file permission. Use OAuth or share the file with a service account.

Is a service-account JSON file the same as an API key?

No. An API key identifies a project for public requests. A service-account JSON file contains a private key used to obtain OAuth access tokens as a non-human identity. It is much more sensitive.

Should I use OAuth or a service account for Google Sheets?

Use OAuth when people connect sheets from their own accounts. Use a service account for unattended backend work against files explicitly shared with that bot identity.

Which Google Sheets scope should I request?

For an app that works with files the user explicitly selects, Google recommends drive.file. Use spreadsheets.readonly only when the app genuinely needs read access to every spreadsheet the user can access.

Do I need a Google Cloud project to turn one sheet into an API?

The official Sheets API requires a Cloud project and credentials. PasteSheet does not require your own project: paste a public sheet URL, or connect Google and select a restricted file in Picker.

Sources

Related guides

Turn your sheet into an API in minutes

Paste a Google Sheet URL and get a live REST API and MCP server — no backend, no code, free to start.