Send email from Airtable without relying on a native marketplace app: use an Airtable Automation with its Run a script action, then call Volanea’s REST API from that script. This guide shows a production-minded setup that maps Airtable record fields into an email, keeps your API key secret, and prevents duplicate sends when an automation is retried or re-run.

Volanea does not ship a native Airtable app, Airtable Marketplace listing, or one-click connector. That is not a blocker. Airtable Automations can run JavaScript in the background, and that script can make an outbound HTTPS request with fetch() to Volanea’s POST /v1/send endpoint.

The practical result is straightforward: a record moves into a state such as Ready to send, Airtable starts an automation, the script reads selected values from that record, and Volanea queues and sends the message from your verified domain.

What this integration uses—and what it does not

This is a direct Airtable-to-Volanea integration, but it is not an Airtable extension or a webhook action configured through a marketplace UI. The integration uses these real Airtable building blocks:

  1. An Airtable Automation.
  2. The When record matches conditions trigger.
  3. A Run a script action.
  4. Airtable Automation input variables for record values.
  5. An Airtable secret for the Volanea API key.
  6. JavaScript fetch() to call Volanea’s email API.

Airtable’s incoming-webhook trigger is for the opposite direction: another service makes a request to Airtable to start an automation. It is useful when you want delivery events or other external events to update Airtable, but it is not the outbound email-send mechanism in this guide.

Airtable also has a Webhooks API for developers that need change notifications from a base. That is a different architecture: it is suited to an external application that subscribes to Airtable changes and then processes webhook payloads. For a single record-triggered email workflow, the Automation plus Run a script route is simpler because the outbound HTTP call happens in Airtable.

There is one plan constraint worth making explicit: Airtable lists the Run a script automation action as unavailable on the Free plan. If your workspace is on Free, you cannot use the direct script approach below. Use Zapier, Make, or your own middleware to receive the Airtable event and call Volanea instead. On a plan where Run a script is available, no extra integration platform is required.

The recommended Airtable trigger: When record matches conditions

For transactional messages, use Airtable’s When record matches conditions trigger rather than When record created.

The record-created trigger fires as soon as a new record is created. That can be too early when a user is still filling in fields, when an Airtable form creates a partial record before another process enriches it, or when another automation adds the recipient email later. Airtable specifically recommends a condition-based trigger or a record-enters-view trigger when an automation should wait for a preset state.

The condition-based trigger is a better email boundary because it represents a business decision, not merely database activity.

Example table design

Assume a table named Invoices with these fields:

Airtable fieldField typePurpose
Invoice numberSingle line text or formulaCustomer-facing identifier, such as INV-1042
Customer emailEmailRecipient address
Customer nameSingle line textGreeting personalization
Amount dueCurrencyAmount shown in the message
Payment URLURLHosted payment link
Email statusSingle selectControls the workflow state
Email sent atDate with timeOptional audit trail
Volanea email IDSingle line textOptional provider message identifier

Configure the trigger as follows:

  • Table: Invoices
  • Trigger: When record matches conditions
  • Conditions:
    • Email status is Ready to send
    • Customer email is not empty
    • Invoice number is not empty
    • Payment URL is not empty

The concrete event that starts the send is therefore: an Invoice record changes into a state where Email status is Ready to send and the required fields are populated. Airtable runs this trigger when a record changes into the matching state; records that already matched when the automation was switched on do not automatically trigger it.

This structure also lets people work normally in the base. A finance teammate can create and edit an invoice, then intentionally change Email status from Draft to Ready to send when the content is complete.

Why a status field is safer than a view alone

You can also trigger on When record enters view, but that approach ties a sending workflow to a view’s filters. If someone edits the view filters, records may enter or leave unexpectedly. Airtable recommends locking a view used as an automation trigger to reduce accidental changes.

A single-select status makes the state transition visible on the record itself. It also makes the workflow easier to audit:

  • Draft means the message should not send.
  • Ready to send means the automation is eligible to send.
  • Sent means the business event has been handed off successfully.
  • Send failed means the record needs attention.

Do not change a record to Sent merely because Airtable started the script. Only mark it sent after the Volanea API call returns a successful response, ideally in a following Airtable Update record action or through a more complete script design.

Configure the Airtable Automation

Open the relevant base, select Automations, create an automation, and add the trigger described above. Next, add the action named Run a script.

A Run a script action executes in the background when the automation runs. It is different from Airtable’s Scripting extension, which is intended for scripts a user runs manually from the base interface. For an automatic email send, use the automation action.

Add input variables before pasting code

The script does not automatically receive every field in a record as a universal JSON object. In the Run a script action, configure input variables in the Variables sidebar and map each one from the trigger output.

Create these ordinary input variables:

Input variable nameMap from the trigger
recordIdAirtable record ID
invoiceNumberInvoice number
customerEmailCustomer email
customerNameCustomer name
amountDueAmount due
paymentUrlPayment URL

Also create one secret:

Secret nameValue
VOLANEA_API_KEYYour Volanea secret API key beginning with sk_ or sk_test_

In the script, ordinary inputs are read with input.config(). Secrets are read with input.secret.<secretName>.

The actual payload in this integration

It is important to be precise about payload shape. Airtable does not have a native outbound webhook action that automatically emits an Airtable-defined record JSON payload to Volanea. Instead, the Automation script constructs the outbound JSON body from the values that you mapped in the Variables sidebar.

For the example Invoice record, the request body sent from Airtable to Volanea has this shape:

{
  "from": "Billing <billing@your-verified-domain.com>",
  "to": ["ada@example.com"],
  "subject": "Invoice INV-1042 is ready",
  "html": "<p>Hi Ada,</p><p>Your invoice...</p>",
  "text": "Hi Ada,\n\nYour invoice..."
}

Volanea’s single-message endpoint is POST https://api.volanea.com/v1/send. It accepts a sender, recipient array, subject, HTML content, text fallback, authentication, and an Idempotency-Key header for safe retries. Read the email API reference and setup guides before switching from a test key to a live sending domain.

Working Airtable script: map a record into a Volanea email

Paste the following JavaScript into the Run a script action after configuring the inputs and secret above. Replace the from address with an address at a domain you have verified in Volanea.

// Airtable Automation > Run a script
// Required input variables:
//   recordId, invoiceNumber, customerEmail, customerName, amountDue, paymentUrl
// Required secret:
//   VOLANEA_API_KEY

const config = input.config();
const apiKey = input.secret.VOLANEA_API_KEY;

const {
  recordId,
  invoiceNumber,
  customerEmail,
  customerName,
  amountDue,
  paymentUrl,
} = config;

// Validate the values that must exist before making an email API call.
if (!recordId) {
  throw new Error("Missing Airtable record ID.");
}

if (!customerEmail) {
  throw new Error("Missing Customer email.");
}

if (!invoiceNumber) {
  throw new Error("Missing Invoice number.");
}

if (!paymentUrl) {
  throw new Error("Missing Payment URL.");
}

if (!apiKey) {
  throw new Error("Missing VOLANEA_API_KEY secret.");
}

// Airtable values can be empty. Use a safe fallback for the greeting.
const firstName = customerName ? String(customerName).trim() : "there";
const formattedAmount = amountDue ? String(amountDue) : "the outstanding amount";

// This must identify one logical email, not one HTTP attempt.
// Reusing it when Airtable retries or the automation is manually rerun
// lets Volanea recognize the same send request.
const idempotencyKey = `airtable-invoice-${recordId}-v1`;

// This is the exact JSON request body Airtable sends to Volanea.
const message = {
  from: "Billing <billing@your-verified-domain.com>",
  to: [String(customerEmail).trim()],
  subject: `Invoice ${invoiceNumber} is ready`,
  html: `
    <p>Hi ${escapeHtml(firstName)},</p>
    <p>Your invoice <strong>${escapeHtml(invoiceNumber)}</strong> is ready.</p>
    <p>Amount due: <strong>${escapeHtml(formattedAmount)}</strong></p>
    <p><a href="${escapeAttribute(paymentUrl)}">View and pay your invoice</a></p>
    <p>Thank you,<br>Billing</p>
  `,
  text: [
    `Hi ${firstName},`,
    "",
    `Your invoice ${invoiceNumber} is ready.`,
    `Amount due: ${formattedAmount}`,
    "",
    `View and pay your invoice: ${paymentUrl}`,
    "",
    "Thank you,",
    "Billing",
  ].join("\n"),
};

const response = await fetch("https://api.volanea.com/v1/send", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json",
    "Idempotency-Key": idempotencyKey,
  },
  body: JSON.stringify(message),
});

const responseText = await response.text();
let responseBody;

try {
  responseBody = responseText ? JSON.parse(responseText) : null;
} catch {
  responseBody = responseText;
}

if (!response.ok) {
  throw new Error(
    `Volanea send failed (${response.status}): ${responseText}`
  );
}

// Makes useful values available to later automation actions.
output.set("recordId", recordId);
output.set("idempotencyKey", idempotencyKey);
output.set("volaneaResponse", JSON.stringify(responseBody));

function escapeHtml(value) {
  return String(value)
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/\"/g, "&quot;")
    .replace(/'/g, "&#039;");
}

function escapeAttribute(value) {
  return escapeHtml(value);
}

The script deliberately sends both html and text. HTML gives the email its layout and payment link, while the plain-text fallback gives recipients and text-only clients a readable version of the same message.

The example also escapes record-provided values before placing them inside HTML. This matters even in internal workflows. A customer name, invoice label, or other text entered into Airtable can contain characters such as &, <, or >. Escaping prevents those characters from accidentally becoming markup in the outgoing email.

How the Airtable field mapping works

The code itself does not know your Airtable table name or field IDs. The mapping happens when you configure the script action’s input variables.

For example, map the Run a script input named customerEmail to the Customer email value coming from the When record matches conditions trigger. When Airtable executes the automation for a specific record, input.config().customerEmail contains that record’s email value.

The mapping chain is:

Invoice record field
  → Automation trigger output
    → Run a script input variable
      → input.config() value in JavaScript
        → Volanea POST /v1/send JSON field

For the example email, the concrete field mapping is:

Airtable sourceScript variableVolanea request field
Record IDrecordIdUsed in Idempotency-Key
Customer emailcustomerEmailto[0]
Invoice numberinvoiceNumbersubject, html, and text
Customer namecustomerNamehtml and text greeting
Amount dueamountDuehtml and text body
Payment URLpaymentUrlhtml link and text body
Static sender configurationNot an Airtable fieldfrom

Keep sender identity outside editable customer records. The from value should be a static value in the script or a controlled configuration value, such as Billing <billing@your-verified-domain.com>. Letting ordinary Airtable collaborators freely edit the sender address creates avoidable deliverability and authorization problems.

A note on linked records, lookups, and arrays

Airtable fields do not all reach scripts as simple strings. Linked-record, collaborator, attachment, lookup, and multi-select fields may have data structures or display values that need deliberate handling. For transactional email, map a dedicated Email field directly to customerEmail whenever possible.

If your recipient value comes from a lookup, test the trigger with records that contain one recipient, multiple recipients, and no recipient. Do not assume a lookup behaves exactly like a plain Email field. If you need a multi-recipient message, construct to as an array of valid addresses only after normalizing and validating the source values.

For example, a comma-separated plain-text field can be converted cautiously:

const recipients = String(config.recipientList || "")
  .split(",")
  .map((address) => address.trim())
  .filter(Boolean);

if (recipients.length === 0) {
  throw new Error("No recipient addresses were supplied.");
}

message.to = recipients;

Volanea’s single-send endpoint supports one recipient or up to 50 recipients. For a business event such as an invoice, one message per customer is normally clearer and safer than sharing a recipient list.

Keep the Volanea API key in an Airtable secret

The Volanea API key is a credential with permission to send mail through your account. Treat it as a password, not as an ordinary configuration field.

In the Run a script action, use the Variables sidebar to add a secret named VOLANEA_API_KEY, then access it in JavaScript with:

const apiKey = input.secret.VOLANEA_API_KEY;

Airtable’s scripting secrets have special protections: a user needs access to the relevant secret to edit the script that uses it. Airtable also supports managing secrets through Builder Hub, where sensitive values such as API keys and passwords can be securely stored for scripting extensions and Run a script automation actions.

Where the key must not live

Do not place the Volanea secret key in any of these locations:

  • A normal Airtable text field.
  • A public Airtable form’s hidden or prefilled data.
  • A formula field.
  • An Airtable Interface value that broad collaborators can inspect.
  • A browser-based front-end application.
  • A pasted code comment or shared screenshot.
  • A Zapier/Make step field if that platform has a proper connection or secret-storage option instead.

A public form visitor should be able to submit a record without ever receiving the API key. Likewise, a customer should never be able to inspect a webpage or client-side configuration and find a credential that can send messages as your domain.

Limit both Airtable base permissions and secret access. The Automation may be an operational tool, but it still sits on a security boundary: anyone who can alter its script, sender identity, or field mapping can affect emails leaving your organization.

Add an Airtable status update after a successful send

A successful API response means Volanea accepted the request and began processing it. It does not mean a recipient has read the email, and it is not necessarily proof of inbox placement. Still, it is the right point to record that the sending request succeeded.

After the Run a script action, add an Airtable Update record action. Select the record ID from the trigger or from the script’s output.set("recordId", recordId) output. Then update:

  • Email status → Sent
  • Email sent at → the automation’s current time token, if appropriate
  • Volanea email ID → a provider response value if your response schema and workflow need it

Do not put the update before the API call. If you mark a record sent first and the HTTP request then fails, the record will incorrectly state that the customer was notified.

For higher-stakes workflows, add a Send failed path. Airtable’s automation history lets you inspect failed runs and error messages. You can also configure subscriber coverage for a business-critical automation so failures do not depend on one person being available.

Avoid an automation loop

If your trigger condition is simply Email status is Sent, then updating Email status to Sent can cause unwanted behavior in a poorly designed automation. The recommended pattern avoids that:

  • Trigger when status changes into Ready to send.
  • Send through Volanea.
  • Update status to Sent.

Because Sent no longer matches the original trigger condition, the update does not initiate another email send.

If someone later changes the record back to Ready to send, Airtable can treat that as a new state transition. Decide whether that represents a legitimate resend. If not, include another condition such as Email sent at is empty, or use a separate explicit Resend requested checkbox with a distinct template and idempotency strategy.

Prevent duplicate email sends with an idempotency key

Airtable automations are not a guarantee that an external side effect happened exactly once. Any workflow that crosses an HTTP boundary has an ambiguity window: Volanea may receive and accept the request, while Airtable may fail to receive or process the response. A later retry, re-run, or repeated state change can otherwise create a second email.

That is why the script sends this header:

Idempotency-Key: airtable-invoice-recXXXXXXXXXXXX-v1

Volanea supports Idempotency-Key on POST /v1/send for safe retries. The critical design detail is that the key identifies the business send event, not the individual script execution.

This would be wrong:

const idempotencyKey = crypto.randomUUID();

A newly generated value every time the automation runs means a retry looks like a fresh email request. Volanea cannot know it is a duplicate of the earlier attempt.

This is better:

const idempotencyKey = `airtable-invoice-${recordId}-v1`;

That deterministic key remains stable for the same Airtable record and version of the invoice-ready email. If the same logical send is attempted again with the same body, Volanea can safely recognize the repeated request.

Design idempotency around the actual business event

A record ID alone is not universally sufficient. It is appropriate when each record should produce one invoice-ready email ever. But consider a record that can legitimately send a new version after a corrected invoice is issued.

In that case, include a stable event version field:

const idempotencyKey =
  `airtable-invoice-${recordId}-revision-${config.invoiceRevision}`;

Now revision 1 and revision 2 are intentionally different sends, while retries of revision 2 continue using the same key. This is better than appending the current timestamp, because timestamps turn every retry into a brand-new operation.

When this breaks: Airtable-to-Volanea failure modes

A dependable integration plans for the failures between the record update and the outbound email request. This section focuses on the Airtable Automation → script → Volanea hop.

A retry or re-run causes duplicate sends

The failure mode is simple: the first HTTP request reaches Volanea, but Airtable does not receive a clean response or the automation is re-run. Without idempotency, the next script execution sends the email again.

Use a deterministic Idempotency-Key based on the Airtable record ID and the logical message revision. Do not create a random idempotency key per run. Also avoid telling teammates to “just run it again” unless the script is safe to retry.

If you intentionally need to resend a message, deliberately change the event version in the key and make that resend visible in Airtable. A resend should be a business decision, not an accidental side effect of troubleshooting.

The outbound request times out or returns a transient error

A script can fail because the remote endpoint is unavailable, a network path is interrupted, or the request takes longer than Airtable permits. Airtable documentation notes that script runs have limits on fetch calls, request duration, and allowed URL types.

The code throws on any non-success HTTP response. That behavior is useful because Airtable marks the automation run as failed instead of quietly recording a false success. Review Automation history, open the failed run, and inspect the script error before retrying.

For a temporary failure, retry only with the same deterministic idempotency key. For a 4xx validation error, fix the data or configuration first; retrying the same invalid payload will not help.

A required field is empty or not available in the script

The trigger can fire while a required value is blank if the conditions are too loose, a formula evaluates unexpectedly, or a field mapping was changed after the script was written. The script checks customerEmail, invoiceNumber, paymentUrl, and recordId before calling Volanea so it fails clearly rather than attempting an incomplete request.

This is also where plan differences matter. Airtable’s Free plan does not provide the Run a script action, so a direct script-based payload cannot be created on that plan. That is a capability limitation, not a reason to expose your Volanea API key in a client-visible workaround.

If you cannot use Run a script, route the event through Zapier, Make, or a small server-side endpoint. Put the Volanea secret in that platform’s secure credential store or server environment variable, not in Airtable fields.

The automation fires before a record is complete

This commonly happens with When record created. A form submission, manual entry, or other automation may create the record before the recipient email, URL, or supporting fields exist.

Use When record matches conditions with explicit non-empty checks. If another automation populates fields asynchronously, add a condition that represents final readiness, such as Email status is Ready to send, rather than triggering simply on creation.

A user edits the sending state again

Condition-based triggers fire when a record moves into the matching state. If someone changes Email status from Ready to send to Draft and then back to Ready to send, that can create another automation run.

Use an Email sent at is empty condition if only one send should ever happen. Alternatively, make resend behavior explicit with a Resend requested status or a revision field. Do not rely on human memory to prevent duplicate customer communications.

HTML displays broken or contains unexpected content

Airtable values are data, not trusted HTML. A customer name with special characters or an internal field containing copied markup can damage the layout if inserted directly into html.

Escape text values before interpolation, as the example script does. Keep payment URLs controlled where possible, validate that they use https, and do not insert untrusted rich text directly into the email HTML.

The sender address is not ready to send

The script can be valid while delivery still fails because the domain or sender identity is not configured for Volanea. Use a verified domain and an approved From address before enabling the automation for customers.

Start with a Volanea test key and a team-controlled recipient. After the request succeeds and the rendered message is correct, move to the live key and verified sender. This staged rollout lets you test Airtable mapping, HTML rendering, and idempotency without accidentally messaging real customers.

Testing the workflow before enabling it

Treat the Automation test as a real integration test, not a syntax check.

First, create a non-customer test record with your own email address. Populate every required field, including an invoice number and an HTTPS payment URL. Then use Airtable’s trigger test and action test controls to confirm the data mapped into the script is what you expect.

Use this checklist:

  1. Confirm the test record does not already match the trigger conditions before you activate the automation.
  2. Verify the input variable names exactly match the names used in input.config().
  3. Add the Volanea key as an Airtable secret, not an ordinary input value.
  4. Begin with a Volanea test key when available.
  5. Confirm the sender domain is verified before a live send.
  6. Trigger one send by changing Email status into Ready to send.
  7. Inspect Airtable Automation history for a successful script run.
  8. Inspect the received email on desktop and mobile, including the text fallback.
  9. Repeat the same logical run only if you are verifying idempotency, and confirm it does not create an unintended duplicate.
  10. Confirm the post-send Airtable status update targets the correct record.

Remember that Airtable counts an automation run whenever the trigger is invoked, including runs that later fail. Monitor the workspace’s automation-run allowance as the workflow scales. A Team workspace has a higher monthly run allowance than Free, and higher-tier plans provide larger limits; your actual plan determines the operational ceiling.

When to use Zapier, Make, or your own middleware instead

The direct Airtable script method is a good fit for a focused transactional workflow: a record becomes ready, one email is sent, and the relevant values live in the record.

Choose middleware instead when you need capabilities beyond that simple hop.

Use Zapier or Make when

  • Your Airtable plan cannot run automation scripts.
  • Your operations team needs a visual no-code workflow rather than JavaScript.
  • You need to connect several business tools around the send.
  • You want a managed queue or additional failure-routing steps.
  • You need a connector to normalize complex Airtable values before the email call.

Airtable identifies Zapier and Make among its third-party integration services. The same security rule applies: store the Volanea key in the middleware platform’s credential or secret mechanism, not in a regular Airtable field.

Use your own serverless middleware when

  • Email volume is high or bursty.
  • You need a durable queue, database-backed deduplication, or extended retry policy.
  • You want webhook verification, audit logs, or advanced observability.
  • The email is tied to payment, identity, legal, or other high-risk processes.
  • You need to receive delivery events and update Airtable in a controlled way.

For example, an Airtable Webhooks API subscription can notify a serverless function about base changes. That function can retrieve the relevant record, validate the state, compute an idempotency key, call Volanea, and write the result back to Airtable. This architecture is more work, but it gives engineering teams stronger control over queues, authentication, deployments, and monitoring.

For many teams, though, an Airtable Automation with a well-scoped script is the smallest reliable solution.

Production checklist for Airtable email sending

Before switching on a live workflow, verify these items:

  • The sender domain is verified in Volanea.
  • The Volanea secret key is stored as an Airtable secret.
  • The automation uses When record matches conditions, not an overly broad record-created trigger.
  • The trigger checks for a recipient and all message-critical fields.
  • The script validates inputs before calling the API.
  • The to value is an array of recipient addresses.
  • Both html and text message bodies are present.
  • Dynamic text is HTML-escaped before it enters html.
  • The Idempotency-Key is stable for one logical send event.
  • A successful response updates the correct Airtable record.
  • A failure remains visible in Automation history and has an owner.
  • Resend behavior is intentional and documented.
  • Test records use internal recipient addresses before customer records are enabled.

The important distinction is between an integration that merely sends email and one that is safe to operate. A status-driven trigger, secret storage, explicit input validation, and idempotency turn Airtable from a convenient spreadsheet-like database into a controlled source of transactional messages.

FAQ

Can I send email from Airtable without a native Volanea app?

Yes. Volanea has no native Airtable Marketplace app, but Airtable Automations can use the Run a script action to make an authenticated HTTPS request to Volanea’s POST /v1/send endpoint.

What Airtable trigger should start the email?

Use When record matches conditions for most transactional workflows. For example, send when Email status changes to Ready to send and the recipient, invoice number, and payment URL are not empty.

Can I use this on Airtable’s Free plan?

Not with the direct script method. Airtable lists the Run a script automation action as unavailable on Free. Use Zapier, Make, or server-side middleware if you need to send through Volanea from a Free workspace.

Where should I store the Volanea API key in Airtable?

Store it as an Airtable Automation secret and read it with input.secret.VOLANEA_API_KEY. Never store it in an Airtable text field, form configuration, browser-visible code, or shared document.

How do I stop Airtable retries from sending duplicate emails?

Send a stable Idempotency-Key with the Volanea request. Build the key from the Airtable record ID plus a meaningful send-event or revision value, then reuse that same key for retries of the same logical email.