Sheetspin logoSheetspin
Data5 min read

How to Turn a Google Sheet into a JSON API

A Google Sheet is a great place to keep content that changes often — a menu, a directory, a price list, a set of FAQs. The trouble is getting it onto your website without copy-pasting.

The answer is to serve the Sheet as JSON your site can fetch. Services like SheetDB and Sheety do this for a monthly fee; you can also do it yourself for free, or provision an owned endpoint in one click.

The DIY way
  • Put your data under a header row in a tab called "data"
  • Write a doGet(e) that reads the range and builds objects
  • Return it with ContentService as JSON
  • Deploy as a Web App (anyone can access)
  • fetch() the URL from your site and render
The owned way
  • Pick the app from the catalog
  • Fill in a short form — no code
  • One click provisions it into your Google account
  • It runs as you, in your Drive, yours to keep
Spin up Sheet API in one click

The DIY way

The DIY route is an Apps Script web app with a doGet that maps each row to an object keyed by the header row.

function doGet(e) {
  var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('data');
  var values = sh.getDataRange().getValues();
  var headers = values[0].map(function (h) { return String(h); });
  var rows = [];
  for (var i = 1; i < values.length; i++) {
    var obj = {}, empty = true;
    for (var c = 0; c < headers.length; c++) {
      var v = values[i][c];
      if (v !== '' && v != null) empty = false;
      obj[headers[c]] = v;
    }
    if (!empty) rows.push(obj);
  }
  return ContentService.createTextOutput(JSON.stringify(rows))
    .setMimeType(ContentService.MimeType.JSON);
}
A read-only JSON API over a Sheet, keyed by the header row.

The DIY way, step by step

Name a tab "data" and give it a header row — those headers become your JSON keys. Paste the doGet above, then Deploy → New deployment → Web app with "Who has access: Anyone", and copy the /exec URL.

Every non-empty row is returned as an object. Add columns or rows in the Sheet and the endpoint reflects them (after Apps Script’s brief cache) — no redeploy needed.

Fetch it from your site

Because it is a GET request with no custom headers, there is no CORS preflight to worry about — you can fetch it directly from the browser.

const rows = await (await fetch(WEB_APP_URL)).json();
// rows: Array<Record<string, string | number>>
rows.forEach(render);

SheetDB and Sheety charge a subscription for this

The hosted services are convenient, but they sit between you and your own data, cap your request volume, and bill monthly. When the subscription lapses, your site’s data source goes with it.

An owned endpoint has none of those strings attached — it lives in your account and answers as long as your Sheet exists.

The one-click alternative: Sheet API

The Sheet API app provisions this endpoint into your own Google account. You name your columns in a short form; it creates the Sheet, deploys the web app, and hands you the live JSON URL. Edit the Sheet, and the API updates.

It is read-only by design (ideal for content your site displays), free, and yours — a SheetDB/Sheety alternative with no subscription and no middleman.

Provision Sheet API into your own Google account

A JSON endpoint backed by a Sheet in your own account. Edit rows and columns in the Sheet; they are served as JSON, keyed by the header row. Perfect for a menu, a directory, a price list, or any content your site fetches.

Frequently asked questions

Can I use a Google Sheet as an API?

Yes. An Apps Script web app with a doGet can serve the Sheet as JSON keyed by its header row, giving your site a live, fetchable endpoint.

Is this an alternative to SheetDB or Sheety?

Yes — for read-only use it does the same job without a subscription, and the endpoint lives in your own Google account instead of a third party’s.

Is the endpoint read-only?

The one-click Sheet API is read-only by design, which is what most sites need for menus, directories, and price lists. You edit data in the Sheet.

← All guidesBrowse the catalog →