All posts
Blog

Securing SheetsAPI Endpoints with API Keys

How to create and use API keys in GKit SheetsAPI to protect private Google Sheet data from unauthorized access.

2 min read

Public by default — intentionally

A new SheetsAPI endpoint requires no authentication. Hit the URL and you get JSON back. That's not an oversight — it's the right default for public data. A team roster on a marketing site, a public product catalog, an open dataset: these don't need access control, and forcing auth on them would add friction with no benefit.

When you have data that isn't meant to be public — internal pricing, customer records, anything with PII — that's when you create an API key.

How the switch works

The moment you create your first API key in the SheetsAPI dashboard, all of your endpoints require authentication. There's no per-endpoint toggle. It's a single switch: no keys exist means everything is public; a key exists means everything requires a valid sk_ token.

This is deliberate. Partial auth — some endpoints protected, some not — is a footgun. You forget to protect one tab, and the data you thought was private is readable by anyone who guesses the URL. The all-or-nothing model is harder to misconfigure.

Keys are prefixed sk_ so they're immediately recognizable in logs, config files, and environment variables.

Creating a key

Sign in at GKit with your Google account. From the dashboard, find the API Keys section and generate a new key. Copy it immediately — it's only shown once in full. Keys are stored encrypted in Cloudflare KV; GKit can verify a key without being able to read it back to you.

You can create multiple keys and revoke them individually. The typical pattern is one key per environment: one for local development, one for staging, one for production. That way, if a key leaks from one environment, you revoke only that one without touching the others.

Passing the key in requests

Every authenticated request needs the key in an Authorization header as a Bearer token.

curl:

curl "https://sheetsapi.gkit.mreshank.com/api/spreadsheets/{userKey}/{sheetName}" \
  -H "Authorization: Bearer sk_your_key_here"

fetch (JavaScript):

const res = await fetch(
  "https://sheetsapi.gkit.mreshank.com/api/spreadsheets/{userKey}/{sheetName}",
  {
    headers: {
      Authorization: "Bearer sk_your_key_here",
    },
  }
);
const data = await res.json();

With writes (POST):

await fetch(
  "https://sheetsapi.gkit.mreshank.com/api/spreadsheets/{userKey}/{sheetName}",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: "Bearer sk_your_key_here",
    },
    body: JSON.stringify({ name: "Ada Obi", email: "ada@example.com" }),
  }
);

A request without a valid Bearer token returns 401 Unauthorized. The key must match exactly — no extra whitespace, no sk_ prefix stripped.

Keep keys off the client

An API key in browser-side JavaScript is not a secret. Anyone who opens devtools can read it. If you're building a frontend-only app, either keep the Sheet public (and accept that anyone can read it), or proxy requests through your own backend so the sk_ token never leaves your server.

In Next.js, that means calling SheetsAPI from a Route Handler or a server component — not from a useEffect. In a pure static site, it means a serverless function in front of your Sheet.

Rotating keys

Keys leak. A .env file committed by accident, a screenshot in a bug report, a CI log that prints environment variables — any of these can expose a key. Rotation is how you recover:

  1. Create a new key from your dashboard.
  2. Update all environments that use the old key.
  3. Confirm requests are flowing with the new key.
  4. Revoke the old one.

Because creating a new key doesn't invalidate existing ones, you have a window to roll out the change without downtime. Get into the habit of rotating on a schedule regardless — and immediately whenever a key may have been exposed anywhere.


The full authentication reference, including how OAuth and API keys interact, is in the authentication docs. If you haven't created your first key yet, sign in here — your endpoints go private the moment you do.

Share