Operations

How to send form submissions to a database automatically

The short answer

To send form submissions to a database automatically, receive each submission by webhook, validate and normalize the fields in code, then upsert the row into Postgres, Supabase or Airtable using the form's submission ID as a unique key so retries never create duplicates. Log anything that fails to a dead-letter table for replay, and run a daily count that compares the form with the database. AI is optional and mainly useful for cleaning or classifying free-text answers.

What this automation does

Every submission from every form lands in the right table, in the right format, exactly once, and if anything fails you know about it the same day.

  1. Receive. Typeform, Jotform and Tally send each submission by webhook. Google Forms posts through a short Apps Script or a linked Sheet trigger.
  2. Acknowledge quickly. The receiver returns success right away and processes the submission afterward, so the form provider never times out and resends.
  3. Validate and normalize. Code checks required fields and converts formats: lowercase emails, phone numbers in E.164 format, ISO dates, two-letter state codes, and multi-select answers as arrays.
  4. Map. Stable field identifiers, not question labels, map to database columns. Renaming a question on the form does not break the mapping.
  5. Upsert. The row is inserted or updated using the submission ID as a unique key. A contact table is matched on email so the same person submitting twice links to one record.
  6. Enrich (optional). A small model classifies free-text answers or pulls structured details out of long responses.
  7. Notify and reconcile. The right team gets a Slack or email alert. Failures go to a dead-letter table, and a daily job compares submission counts between the form and the database.

When it is worth building

This is worth doing when form data drives real work, such as applications, service requests, registrations or intake, and the current setup is a Google Sheet that several people edit, filter and occasionally break. It is also worth it when several forms describe the same kinds of records and you want them in one place, or when other systems need to read the data.

It is not worth building for a single low-volume form that a native integration already handles well. A one-step Zapier connection or the form tool’s own Airtable integration will do. Build when reliability matters, when there are several forms, or when the target is a relational database with constraints. If the job is really keeping two business apps in step with each other, our data sync guide is the closer match.

Architecture

LayerWhat we useWhy
FormsTypeform, Jotform, Tally, Google FormsKeep whatever form tool your team already likes
Receivern8n Webhook node, or a Supabase Edge Function for simple casesA stable endpoint that answers quickly
ValidationCode with a schema per formBad data is rejected with a reason, not stored
DatabasePostgres or Supabase for relational data, Airtable for editable viewsConstraints, joins and history in one place
Dead-letter storeA failed submissions table with the raw payloadNothing is lost, everything can be replayed
AI (optional)Claude Haiku 5.5Fast, cheap classification of free-text answers
ReconciliationScheduled n8n job against each form’s APICatches anything webhooks missed

Choosing between Postgres and Airtable as the destination is covered in our Airtable vs Postgres comparison. If you prefer a managed Postgres with an admin UI, our Supabase notes explain the setup.

How to build it

  1. Design the data model first. Decide tables, column types and constraints before touching the forms. Model entities, such as contacts, organizations and requests, rather than one table per form.
  2. Use stable field identifiers. Map on field IDs or references, not question text. Typeform lets you set a custom reference on each question, which keeps mappings readable.
  3. Secure the webhook. Verify the payload signature where the provider supports one (Typeform does). Otherwise, include a long secret token in the webhook URL and reject requests without it.
  4. Write an idempotent upsert. In Postgres, use an insert with an on-conflict clause on the submission ID. Retries and replays then update the same row instead of adding a duplicate.
  5. Validate and route failures. Rejected submissions go to the dead-letter table with the raw payload and the reason. Someone reviews that table daily for the first month.
  6. Copy uploaded files. File links from form providers can expire or require a login. Download attachments to your own storage, such as Supabase Storage or S3, and store that path instead.
  7. Backfill history. Export past submissions through the form’s API and run them through the same pipeline, which doubles as a full test.
  8. Schedule reconciliation. Each night, compare counts and IDs for the last few days and insert anything missing.

The downloadable starter template below gives you the webhook receiver, validation and Postgres upsert to adapt to your forms.

What breaks in production

  • Form edits. Someone adds a question, deletes one or changes a dropdown option, and data stops landing in the right column. Alert when a payload contains a field the mapping does not know.
  • Duplicate rows. Webhook retries without a unique key create copies. The submission ID constraint is not optional.
  • Junk submissions. Bots find public forms. Use the form tool’s spam protection and reject entries that fail basic validation.
  • Type mismatches. “N/A” or “about 50” in a number field breaks inserts. Validate before writing and keep the original text alongside the parsed value.
  • Missing hidden fields. UTM parameters and referral codes are only present when the link included them. Treat them as nullable.
  • Sensitive data. Health, financial or identity information needs care. For healthcare data covered by HIPAA, every vendor that stores or processes it (form tool, automation host, database) must offer a BAA on the plan you use, or that data must not pass through them.

Timeline and cost

One to three forms writing into a single database typically take one to two weeks. Lumeor builds this in the range of $2,500 to $6,000. The upper end covers several forms, file handling, AI enrichment and reconciliation jobs. If you self-host n8n, our cloud vs self-hosted comparison covers the trade-offs, and running costs are mostly hosting.

How to measure success

  • Submissions in the form tool versus rows in the database (these should match exactly)
  • Minutes from submission to row available
  • Failed submissions per week and time to replay them
  • Duplicate records found in periodic audits
  • Hours of manual copying and cleanup removed
  • Share of rows passing validation on the first attempt

Free starter template

Import a working n8n workflow that implements the core of this guide, then adapt it to your systems.

Frequently asked questions

Why not use the form tool's built-in integration?

For low volume and a single form, you often should. Typeform and Jotform both offer native connections to Google Sheets and Airtable. A custom workflow makes sense when you need validation, several forms writing to the same tables, a real relational database, reliable deduplication, or a guarantee that no submission is silently lost.

Does Google Forms support webhooks?

Not as a simple webhook. The Google Forms API can push new-response notifications, but only through Google Cloud Pub/Sub, without the answers themselves, and with a watch you must renew weekly. The usual approaches are to link the form to a Google Sheet and trigger on new rows, or to add a small Apps Script that runs on submit and posts the response to your workflow. The Apps Script route is faster and carries the response ID, which helps with deduplication.

Should the data go into Postgres or Airtable?

Airtable is friendlier for non-technical teams who want to view and edit records directly. Postgres or Supabase is better when volumes grow, when you need proper relationships between tables, or when other applications read the data. Many teams start in Airtable and move to Postgres once reporting and integrations pile up.

What happens if the webhook fails or our workflow is down?

Some form providers, such as Typeform, retry failed webhooks for a limited time and then disable them; others retry little or not at all. The workflow writes anything it cannot process to a dead-letter table, and a daily reconciliation job pulls recent submissions from the form's API and inserts any that are missing. Together these close the gap.

Do I need AI for this at all?

Often not. Moving structured form data into a database is plain integration work. AI helps with free-text fields, for example classifying a "how can we help?" answer into a request type, extracting a company name and budget from a paragraph, or normalizing messy job titles.

Next steps