---
title: "Email to Airtable | WebhookRelay"
meta:
  "og:description": "Turn inbound emails into Airtable records automatically. Webhook Relay parses email to JSON, then a transform maps it into the Airtable API format."
  "og:title": "Email to Airtable"
  description: "Turn inbound emails into Airtable records automatically. Webhook Relay parses email to JSON, then a transform maps it into the Airtable API format."
---

![Stripes](https://webhookrelay.com/docs/tutorials/email/airtable/images/stripes.svg)

Documentation

**Fundamentals**

# **Email to Airtable**

Turn inbound emails into Airtable records automatically. Webhook Relay parses email to JSON, then a transform maps it into the Airtable API format.

A lot of structured information still arrives as **email**: inbound leads, order confirmations, job applications, vendor notifications, form submissions that only email you. Each one is a row you wish were in **Airtable** — but instead it sits in an inbox waiting to be copied across by hand.

[Webhook Relay](https://webhookrelay.com) can [receive emails as webhooks](https://webhookrelay.com/docs/tutorials/email/airtable/docs/email/). You give an inbox a unique address, every message sent to it is parsed into JSON, and a small **transform** reshapes it into the format the [Airtable Web API](https://airtable.com/developers/web/api/introduction) expects before delivery — no mail server, no parsing of raw MIME, no polling.

## [How it works](#how-it-works)

The whole path is a single hop with a transform in the middle:

```
inbound email  ──▶  Webhook Relay (parse + transform)  ──▶  Airtable API  ──▶  new record
```

When an email hits your Webhook Relay address, it's parsed into a structured JSON document and POSTed to the bucket's outputs. The Airtable API doesn't understand that shape — it accepts a `{ "fields": { ... } }` body with a bearer token — so the transform converts one into the other in flight.

The parsed email looks like this:

```
{
  "from": "jon@example.com",
  "from_name": "Jon Snow",
  "recipient": "<uuid>@in.webhookrelay-mail.com",
  "to": ["<uuid>@in.webhookrelay-mail.com"],
  "subject": "New lead: Acme Corp",
  "date": "Sun, 28 Jun 2026 11:27:41 +0400",
  "message_id": "<abc@mail.example.com>",
  "text": "plain body",
  "html": "<p>html body</p>",
  "spf": "pass",
  "dkim": "pass",
  "dmarc": "pass",
  "attachments": [
    { "name": "resume.pdf", "content_type": "application/pdf", "size": 48213, "content": "<base64>" }
  ]
}
```

See the full [payload reference](https://webhookrelay.com/docs/tutorials/email/airtable/docs/email/payload/) for every field, including `cc` and the raw `headers` map.

## [Setup](#setup)

**1. Create a bucket.** This is the container that ties an input to its outputs.

**2. Add an email input.** Webhook Relay gives you back a unique address of the form `<uuid>@in.webhookrelay-mail.com`. Anything sent there is parsed and forwarded to the bucket's outputs.

**3. Add an output pointing at the Airtable API.** Create an Airtable personal access token with the `data.records:write` scope, then add an output whose destination is `https://api.airtable.com/v0/<BASE_ID>/<TABLE_NAME>`. Put the credentials in the output's headers: `Authorization: Bearer <your-token>` and `Content-Type: application/json`.

**4. Attach the transform.** Add the [transform function](https://webhookrelay.com/docs/tutorials/email/airtable/docs/webhooks/functions/) below so the parsed email is reshaped into an Airtable record before it's delivered.

**5. Send a test email.** Email your `<uuid>@in.webhookrelay-mail.com` address from any client. Within a second or two a new row appears in your table. If it doesn't, open the request log in your dashboard to see exactly what was received and delivered.

## [The transform](#the-transform)

Webhook Relay [functions](https://webhookrelay.com/docs/tutorials/email/airtable/docs/webhooks/functions/) hand you the incoming request body as a string in `r.body`. Parse it, build the Airtable payload, and write it back with `r.setBody`:

```
const e = JSON.parse(r.body);

r.setBody(JSON.stringify({
  fields: {
    From: e.from,
    Subject: e.subject,
    Body: e.text,
    Received: e.date
  }
}));

r.setHeader("Authorization", "Bearer " + "YOUR_AIRTABLE_TOKEN");
r.setHeader("Content-Type", "application/json");
```

That's the complete bridge: the sender, subject, body and date become a single Airtable record. Each key under `fields` must match a column in your table and use a compatible value type (single line text, long text, date, single select). For cleaner data, prefer `e.from_name` over `e.from` for a display name, and trim or truncate `e.text` if your column has limits.

To handle **attachments**, remember each entry in `e.attachments` carries base64 `content` — upload it to your own storage first, then put the resulting URL in an Airtable attachment field, since Airtable fetches attachments by URL.

> In production, keep the token in the output's configured headers rather than hardcoding it in the function, so it never lives in your transform source.

## [Get started](#get-started)

Turning inbound mail into Airtable records is one case of a broader pattern: [Email to Webhook](https://webhookrelay.com/docs/tutorials/email/airtable/email-to-webhook/). Once an email is JSON, you can route it anywhere a webhook can go.

[Create a free Webhook Relay account](https://my.webhookrelay.com/register), add an email input, and have leads, orders and applications flowing into Airtable in a few minutes.

Did this page help you?