Send data to a Google Sheet automatically (without Zapier)

An Apps Script webhook, the Sheets API directly, or a tool that writes natively. Code for all three, and why the paid connector is surplus.

Martin Riedweg Cofondateur de Rowbase 29 July 2026 · 5 min read

Short answer: there are three paths. A script hosted by Google, free, 15 minutes, no infrastructure. A direct call to the Sheets API, cleanest if you have code. Or a tool that writes into your sheet natively. The per-task third-party connector is the one option you almost never need.

Three ways to feed a Google Sheet automatically Three paths compared: manual copy-paste, a third-party connector billed per task, and writing straight to the Google Sheets API. Path 1 Copy and paste by hand Your tool a human The Sheet Free, never current and nobody knows when it was last done Path 2 A third-party connector Your tool Connectorbilled per task The Sheet One more subscription and an outage you do not control Path 3 Writing straight to the Google Sheets API Your tool OAuth The Sheet A single dependency a sync log, and an alert when it breaks In all three cases your formulas, charts and pivot tables stay in the Sheet. What changes is the entry point.

Option 1 · An Apps Script webhook (free, serverless)

Fastest route when you just want an external source to push rows into a file. Three moves, from inside your Sheet:

  1. Open the script editor. Extensions, then Apps Script. Paste the code below, swapping the secret and the tab name for your own.
  2. Deploy it as a web app. Deploy, New deployment, Web app, with "Execute as: me" and "Who has access: anyone". Google hands you a URL.
  3. POST to that URL from your data source, with the secret in the request body.
const SECRET = 'replace-me';

function doPost(e) {
  const body = JSON.parse(e.postData.contents);

  if (body.secret !== SECRET) {
    return ContentService
      .createTextOutput(JSON.stringify({ ok: false, error: 'unauthorized' }))
      .setMimeType(ContentService.MimeType.JSON);
  }

  SpreadsheetApp
    .getActiveSpreadsheet()
    .getSheetByName('Orders')
    .appendRow([new Date(), body.customer, body.amount, body.status]);

  return ContentService
    .createTextOutput(JSON.stringify({ ok: true }))
    .setMimeType(ContentService.MimeType.JSON);
}

Then, from anywhere:

curl -X POST "https://script.google.com/macros/s/YOUR_ID/exec" \
  -H 'Content-Type: application/json' \
  -d '{"secret":"replace-me","customer":"Lumen Studio","amount":860.5,"status":"In progress"}'

What to know before committing to it. A deployment set to "anyone" is a public URL: the shared secret isn't decorative, it's your only authentication. Apps Script is subject to daily quotas and a maximum execution time, so this is not the path for importing 50,000 rows. And if you're pushing several rows at once, replace the appendRow loop with a single setValues call, which is the difference between two seconds and two minutes.

Option 2 · The Google Sheets API directly (if you have code)

If the data already leaves your own application, go through the API. A POST to the append endpoint adds a row after the existing data:

POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/Orders!A1:append
  ?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS
{ "values": [["2026-03-14", "Lumen Studio", 860.5, "In progress"]] }

You'll need an OAuth token with the https://www.googleapis.com/auth/spreadsheets scope.

The real decision here isn't technical, it's practical: OAuth or a service account? A service account is simpler to run server-side, but it forces the user to manually share their file with a cryptic email address, and nine out of ten people won't do it correctly. With OAuth, the user picks their file in a Google window and it works first time. If a non-technical human has to wire the connection up themselves, use OAuth.

valueInputOption deserves thirty seconds of attention. USER_ENTERED interprets the value as if it were typed: 2026-03-14 becomes a real date, 860.5 becomes a number. RAW writes plain text, and your dates will never sort. It's the number-one cause of "why are my dates text?"

Option 3 · A tool that writes into your Sheet natively

If nobody on the team is going to write that code, which is the usual case, the question becomes: where is the data typed in the first place? An entry tool that pushes into your sheet itself removes the automation question entirely, because there's no integration left to maintain.

This is also the point to check what you're really after. If the Sheet is your shared record, feeding it automatically only solves half the problem: the six limits of a Sheet used as a database are still there, and four questions will tell you whether they apply to you.

That's what Rowbase does: connect your Google account, pick the destination file and tab, and every row you add lands in your Sheet within seconds, with a sync log and an alert when a write fails.

So why not Zapier or Make?

They're good tools, and they're entirely justified when you're joining two SaaS products you control neither of. Three reservations when all you're doing is writing to a Sheet:

  • Per-task billing turns growing volume into a growing bill, for an operation that objectively costs nothing.
  • You add a dependency whose failures you can't see: when the row doesn't arrive, you go looking for why in a log that isn't yours.
  • Typing slips out of your hands. A generic connector writes what it receives, often as RAW, and you end up with text dates and no idea where they came from.

For a flow that goes from your own tool into your own Sheet, the middleman adds nothing.

One thing to set up whichever path you choose

An automatic write that fails silently is worse than manual copy-paste: you make decisions on a file you believe is current. From day one, put a "last successful write" timestamp in the Sheet itself. One cell at the top is enough. It's the only safeguard that works, because it's the only one you see without going to look for it.

Rowbase is a collaborative database that feeds your Google Sheets natively: a typed grid, as many users as you like, free viewers, data hosted in the European Union. Your formulas and charts don't change.

Try it free →

FAQ

Can you write to a Google Sheet without using Apps Script? Yes, with the Google Sheets API and an OAuth token carrying the spreadsheets scope. Apps Script is simply the no-infrastructure route.

Is an Apps Script webhook secure? Not by default. A deployment open to anyone answers anyone: check a shared secret in the request body, and rotate it if the URL has been passed around.

How many rows can I send per day? It depends on Apps Script quotas and the Sheets API rate limits, both of which Google revises: check them before sizing an import. For large volumes, batch rows into a single request instead of one request per row.

Why are my dates arriving as text? You're probably writing with RAW. Use valueInputOption=USER_ENTERED so Google interprets the value as if a human had typed it.

Can the sync run both ways? Writing to a Sheet is easy; reading it back reliably means detecting changes on Google's side, which the API doesn't push to you. Plan for periodic re-reads, and a clear rule about which side wins on a conflict.

Try it on your own list.

14 days, no credit card. CSV import from Airtable in two minutes.

Try it free
Share
LinkedIn

À lire ensuite