---
title: "Post new leads to your own database"
description: "Post every lead capture submission as JSON to your own endpoint, which validates the payload and inserts a row in your leads table the moment it arrives."
url: "https://www.formformform.com/automations/webhooks-leads-to-your-database"
type: static
generatedAt: "2026-08-23T18:56:58.727Z"
---
![Webhooks logo](/logos/integrations/webhooks.svg)

# Write new leads straight into your own database

Each lead capture submission reaches your endpoint as JSON and becomes a row in your own leads table, seconds after it is sent.

When this happens

New submission on your lead capture form

Do this

POST the submission JSON to your /webhooks/leads endpoint, which validates the payload and inserts a row into your leads table

One-directional. A submission triggers the action — nothing is written back into your form.

A lead is worth most in the minute it arrives, and a startup running its own CRM has nowhere useful to put one until the row exists. This flow sends each submission as a JSON POST to an endpoint you own, so the contact is written to your leads table before anyone opens a notification.

It suits a small engineering team that would rather keep a third-party tool out of the path between form and database. Your handler decides what counts as a valid lead, what gets normalised, and which duplicates are merged.

## Setting it up

1.  1
    
    Publish your lead capture form with Work Email required — a payload with no address gives your handler nothing to key a lead row on.
    
2.  2
    
    Add a route at /webhooks/leads that accepts POST with a JSON body, and have it return 200 before you write any database code.
    
3.  3
    
    Open the form's settings in formformform, enable the outgoing webhook, and paste the full https URL of /webhooks/leads.
    
4.  4
    
    Submit one test lead and log the raw body, so you can read the exact keys the payload uses for Work Email, Company Name and Company Size.
    
5.  5
    
    Write the validation next: return a 4xx when Work Email is missing, and trim and lowercase Company Name before you compare it against existing rows.
    
6.  6
    
    Insert the row inside a transaction, keyed on Work Email, so a second submission from the same person updates the contact rather than duplicating it.
    
7.  7
    
    Store "What problem are you trying to solve?" in a text column rather than an enum — it is free text and will not fit a fixed set of values.
    
8.  8
    
    Return 2xx only after the commit succeeds, so a failed insert is recorded as a failed delivery instead of disappearing quietly.
    

## What maps where

Using the [Lead Generation Form](https://www.formformform.com/templates/lead-generation-form) as the starting point. These are its real fields — swap in your own and the mapping works the same way.

Form field

Webhooks

Work Email

email column, the unique key on your leads table

Full Name

name column on the lead row

Company Name

company column, normalised before insert

Company Size

segment column, mapped to your own bands

How did you hear about us?

source column on the lead row

What problem are you trying to solve?

notes text column on the lead row

## Variations worth knowing

Keep the raw payload as well as the row

Insert the whole JSON body into a payloads table with a received-at timestamp before you parse anything. When a lead looks wrong three weeks later you can read what actually arrived rather than guessing at your own parser. It also lets you replay a batch after a schema change without asking anyone to fill the form in again.

Route the largest companies differently

Branch inside the handler on Company Size: the top bands are inserted with an owner already set and a row on your assignments table, everything else lands unassigned. Doing the branching in code rather than in the form keeps the routing rules in one place, so sales can change the bands without anyone republishing the form.

## If something isn't arriving

The endpoint receives nothing after a test submission.

Check that the URL saved in the form's settings is the full https address of the route, with no typo in the path, and that the route accepts POST rather than only GET. A server that answers on / but 404s on /webhooks/leads is a failed delivery, not a missing one.

Rows are inserted twice for the same person.

The connection runs one way, so nothing is written back to the form to mark a submission as processed — your database has to own that. Put a unique constraint on the email column and upsert on conflict, or store the submission id from the payload and ignore one you have already seen.

## Frequently asked questions

What does the JSON body actually look like?

It carries the form's fields and the values submitted for them. Rather than coding against a shape you have guessed at, send one test lead and log the raw body, then write your parser against the exact keys that arrived. The shape is the same on every submission of that form.

Can my endpoint write anything back into the form?

No. The submission is posted out and nothing is read back beyond the HTTP status your route returns. There is no two-way sync, so a lead score or an owner your database works out stays in your database. Anything the respondent should see has to be on the form itself.

Do I need Zapier for this?

No. Webhooks are native: enable the outgoing webhook in the form's settings, paste your URL, and the POST goes straight from formformform to your server. Zapier is only worth adding when the destination is an app you do not run yourself.

## Related automations

-   [Deliver job applications to your hiring service](https://www.formformform.com/automations/webhooks-applications-to-hiring-service)
    
    Every application is posted as JSON to your applicant tracking service, which validates the fields before it creates a candidate.
    
-   [Fan event sign-ups out to your own services](https://www.formformform.com/automations/webhooks-signups-to-attendee-service)
    
    One POST per RSVP writes the attendee to your database and publishes a message the rest of your services can listen for.
    
-   [Push support requests onto your own job queue](https://www.formformform.com/automations/webhooks-support-tickets-to-queue)
    
    Every support submission is posted to an endpoint that enqueues the request and sets its priority from the answer on the form.
    
-   [Send custom orders to your fulfilment backend](https://www.formformform.com/automations/webhooks-orders-to-fulfilment-api)
    
    Each order submission is posted to your orders API, which records the items and starts fulfilment with nothing rekeyed by hand.
    
-   [Stream feedback scores into your analytics pipeline](https://www.formformform.com/automations/webhooks-feedback-into-your-warehouse)
    
    Each NPS response is posted to an ingestion endpoint that normalises the score and streams the record into your warehouse.
    
-   [Deliver a lead magnet with a Kit sequence](https://www.formformform.com/automations/kit-lead-magnet-delivery)
    
    An ebook request drops the reader into a Kit sequence that sends the download link and nurtures from there.
    

-   [All Webhooks integration details →](https://www.formformform.com/integrations/webhooks)
-   [Start from the Lead Generation Form →](https://www.formformform.com/templates/lead-generation-form)
-   [Browse every automation →](https://www.formformform.com/automations)

## Build the form first

The automation needs somewhere to fire from. Publish a form, connect it once, and every submission from then on runs this flow.

[Start free](https://app.formformform.com/register?utm_source=landing&utm_medium=bottom&utm_campaign=automations&utm_content=webhooks-leads-to-your-database)
