How do I send Google Forms responses to a Notion database?

Send Google Forms responses to a Notion database with Zapier, a free Apps Script trigger that calls the Notion API, or a form that writes to Notion.

Nookesh KarriNovember 6, 20267 min read
Light cover card with the title 'How do I send Google Forms responses to a Notion database?' in dark text and a blue accent bar

To send Google Forms responses to a Notion database, you need something in the middle, because Google Forms has no Notion export. The three routes are an automation tool such as Zapier, a free Apps Script trigger that calls the Notion API on every submission, or a form builder that writes each response straight into Notion. Pick by how much you want to pay and maintain.

Three ways to get Google Forms data into a Notion database

The three working routes differ mostly in cost and in who fixes things when they break. As of November 2026, there is still no native export, and most ranking guides only cover the automation tools. The script route is free and rarely mentioned.

Zapier Apps Script + Notion API Form that writes to Notion
Cost Zapier’s plan Free The form tool’s plan
Setup time Minutes About an hour Minutes
Who maintains it Zapier You The form tool
Field mapping Point and click In code Built from your Notion properties
Old responses New ones only New ones only New ones only

Option 1: Zapier’s ready-made template

Zapier is the fastest way to send form responses to Notion if you already pay for it. Its ready-made template “automatically adds each new response” as an item in a Notion database.

The template uses the New Form Response trigger, which Zapier labels Instant, and a Create Data Source Item action. You connect both accounts, pick the form and the database, then match each question to a property.

The catch is the middleman. Every response passes through another account with its own task limits and billing.

Option 2: a free Apps Script trigger that calls the Notion API

An Apps Script trigger is the free route: a few lines of script attached to your form create a Notion page each time someone submits. Google’s docs say an installable form submit trigger “runs when a user responds to a form”, and the trigger’s event hands your code the full response.

What you need first

  • A Notion connection with access to the database. Create an internal connection, copy its token, then open the database, click the ••• menu, choose Add connections and pick yours. I walk through this in the Typeform webhook guide.
  • The database ID, from the database’s URL.
  • Property names you know by heart. The Create a page endpoint says property names must match the parent data source’s schema exactly.

Steps

  1. Open your form, click the three-dot menu and choose Apps Script.
  2. In Project Settings, add a script property called NOTION_TOKEN with your token.
  3. Paste the script below and replace the database ID and property names.
  4. Click Triggers, then Add Trigger, choose onFormSubmit with the form submit event, and click Save.
  5. Submit a test response and check the database.
const NOTION_TOKEN = PropertiesService.getScriptProperties().getProperty('NOTION_TOKEN');
const DATABASE_ID = 'paste-your-database-id';

function onFormSubmit(e) {
  const a = {};
  e.response.getItemResponses().forEach(r => {
    a[r.getItem().getTitle()] = r.getResponse();
  });
  const text = v => [{ text: { content: String(v || '').slice(0, 2000) } }];
  const res = UrlFetchApp.fetch('https://api.notion.com/v1/pages', {
    method: 'post',
    contentType: 'application/json',
    headers: { Authorization: 'Bearer ' + NOTION_TOKEN, 'Notion-Version': '2026-03-11' },
    payload: JSON.stringify({
      parent: { database_id: DATABASE_ID },
      properties: {
        Name: { title: text(a['Name']) },
        Email: { email: a['Email'] || null },
        Message: { rich_text: text(a['Message']) }
      }
    }),
    muteHttpExceptions: true
  });
  if (res.getResponseCode() !== 200) throw new Error(res.getContentText());
}

The keys of a are your question titles. Notion’s versioning page says the Notion-Version header is required, and 2026-03-11 is the latest version shown in the reference.

How to check it worked

A working Apps Script trigger adds a new row within seconds of each test submission. When the script throws, Google emails you a message titled “Summary of failures for Apps Script”, which includes Notion’s error text. That’s why the script throws instead of failing quietly.

The limits that decide whether the script route holds up

The Apps Script route has hard quotas, and they are generous for a normal form. According to Google’s quota page, a gmail.com account gets 20,000 URL Fetch calls a day and a Workspace account 100,000. Each response uses one call.

The others:

  • Trigger runtime: 90 min / day on a consumer account, 6 hr / day on Workspace. One short Notion call per response rarely gets near it.
  • Notion text size: Notion’s request limits cap text.content at 2000 characters, which is why the script trims long answers.
  • Notion rate limit: 180 requests per minute, an average of 3 per second, on most plans. A sudden burst can return HTTP 429; Notion asks you to respect the Retry-After header.
  • Who it runs as: installable triggers “always run under the account of the person who created them”. If that person leaves, the sync stops.

That last one is the script route’s real weakness. The sync belongs to one person’s Google account, and nobody else on the team can see the trigger.

Option 3: use a form that writes to Notion directly

A form builder that saves into Notion skips the sync step entirely, because the form is generated from your database. nDBForms reads your database properties, builds matching fields, and each submission becomes a new row. Respondents don’t need a Notion account, and the free plan covers 3 forms and 100 responses a month.

This only helps if you can replace the Google Form. If you’re stuck with an existing Google Form, Option 1 or 2 is the answer. For a side-by-side of the two form tools, see my comparison of Notion forms and Google’s form builder.

Mapping fields and moving old responses

Field mapping in any of these setups works best when every question has a matching property of the right type. Use an email property for email answers, a select property for multiple choice, and a text property for open answers. My field mapping guide covers each type.

None of the three routes copies responses you already have. The cleanest fix is a one-time import. Link the form to a sheet (Responses, Summary, More, then Select destination for responses), download it as CSV, and import the CSV into Notion before you switch the sync on.

My take: if your Google Form already has live traffic, use the Apps Script route. It costs nothing, and the code is short enough to read in one sitting. If rows still don’t show up, work through why a form isn’t syncing to Notion.

FAQ

Can a Google Form send responses to Notion without any tool?

No. Google’s form builder has no built-in Notion export. You need an automation tool, your own Apps Script, or a form builder that writes to Notion itself.

Is the Apps Script route free?

Yes. It runs on your Google account. A gmail.com account gets 20,000 URL Fetch calls a day, and each response uses one call.

Will old responses move over too?

No. A form submit trigger only fires on new responses. Older ones need a one-time import, for example from the linked Google Sheet as a CSV.

Why did my script stop sending responses?

Check the failure email titled “Summary of failures for Apps Script”. Common causes are a renamed Notion property, a database no longer shared with the connection, or text over 2000 characters.

Sources