How to Send Parsed Email Data to a Database (Webhook and API Methods)

Last updated July 2026

Try it now: extract email data to Excel, CSV, or JSON

Convert your email files
No install

Connect a mailbox to pull .eml/.msg in bulk, or paste a raw email to test the converter now.

or paste an email to test
Output format
Columns to extract
Extract your own custom fields
Popular:

Create a free account to download. No credit card required.

Straight from email to a database row

MailParse posts every parsed email to your endpoint as JSON, so you can insert a row the moment mail arrives. See the email parser API, or follow the two methods below.

Last updated July 2026

Plenty of the data a business runs on arrives as email: orders, leads, invoices, shipping updates, application forms. It is useful the moment it lands in a table you can query, and painful for as long as it lives in an inbox. The gap between the two is a parsing step and a database write. This guide covers both common ways to close it, the shape of the data you will handle, and the details that keep the pipeline from creating duplicate rows.

How do I send parsed email data to a database?

Parse each incoming email into named fields, then insert those fields as a database row using one of two methods: a webhook that fires on every parsed message, or the parser API that returns structured JSON your code inserts. The webhook suits real-time, hands-off loading; the API suits code you already run on a schedule. In both cases the parser turns the message into clean JSON and your side turns that JSON into an INSERT.

Method 1: webhook to your endpoint

This is the real-time path. The parser posts a JSON payload to a URL you control the instant an email is parsed, and a small handler inserts a row.

# the parser POSTs parsed fields to your webhook
payload = request.json
# payload = {"order_number": "10432", "total": "129.00",
#            "customer": "acme co", "email": "[email protected]"}

db.execute(
  "INSERT INTO orders (order_number, total, customer, email) "
  "VALUES (%s, %s, %s, %s) "
  "ON CONFLICT (order_number) DO NOTHING",
  (payload["order_number"], payload["total"],
   payload["customer"], payload["email"])
)

The ON CONFLICT clause is the part people skip and regret. Webhooks retry when your server hiccups, so the same email can arrive twice. Keying on a natural unique field, an order number, an invoice number, a message id, and ignoring duplicates makes the load idempotent, which means a retry is harmless.

Method 2: pull structured JSON from the API

If you already run a job on a schedule, fetch parsed results from the API and insert them in a batch. This suits teams that prefer to control timing, log every run, and handle their own retries rather than receive pushes.

rows = api.get("/parsed?since=last_run").json()
for r in rows:
    db.execute(
      "INSERT INTO leads (name, email, company, message) "
      "VALUES (%s, %s, %s, %s) ON CONFLICT (email) DO UPDATE "
      "SET message = EXCLUDED.message",
      (r["name"], r["email"], r["company"], r["message"])
    )

Which method should I use?

Method Best when Watch out for
WebhookYou want rows in real time with no polling loopHandle retries and duplicates with a unique key
API pullYou already run scheduled jobs and want controlTrack a "since" cursor so you do not re-read rows
No-code (Zapier, Make, n8n)You would rather not write a handler at allRow limits and per-task cost at high volume

If you would rather not write any code, a no-code step in Zapier, Make, or n8n can take the same JSON and insert a row into Postgres, MySQL, or Airtable. It is slower per record and costs per task, but it gets a working pipeline up in an afternoon.

What does the parsed JSON look like?

Clean and flat, which is what makes the insert simple. You name the fields you want, invoice_total, order_number, tracking_number, and the parser returns them as keys with string values, plus repeating rows as an array when a message carries a line-item table. Because you control the field names, they can match your column names, so the mapping is one to one. If you want a spreadsheet on the way to the database, the email to JSON and email to CRM pages show the same data feeding different destinations.

When the data is not really in the email

One caveat worth naming. If the numbers you want live in a monthly PDF statement rather than in per-transaction emails, parsing alert emails is the slow path. It is faster to convert the statement itself into a table first; a dedicated bank statement converter turns a PDF statement into clean rows in one pass, and you load that instead of stitching together dozens of notification emails. Match the tool to where the data actually lives.

The short version

Parse the email into named fields, then insert those fields as a row, either pushed to a webhook in real time or pulled from the API on a schedule, and key on a unique field so retries never duplicate. Start with the email parser API for the JSON contract, or read how to automate data entry from email for the wider workflow.