Fluent Forms email integration can mean more than sending a generic WordPress notification: it can turn a submitted form into a branded, trackable transactional email sent through Volanea. The reliable pattern is Fluent Forms → server-side webhook endpoint → Volanea REST API, with field mapping and duplicate protection handled deliberately.

What this integration does

A Fluent Forms form submission is the event that starts this workflow. A visitor completes a form, Fluent Forms records the submission, and a Webhook feed associated with that form sends an HTTP request to an endpoint you control. That endpoint validates the request, maps the submitted values into an email message, and calls Volanea.

This is not a native Volanea app or marketplace plugin. Fluent Forms’ relevant capability is its Webhook integration, which lets a form send outbound HTTP requests after submission. The webhook route is useful because it gives a developer control over email content, authorization, routing rules, retries, and observability without exposing a sending credential in browser code.

A typical use case is a contact form that sends two emails:

  • An internal notification to a sales or support inbox, containing the submitted details.
  • A confirmation email to the person who submitted the form, confirming receipt and setting expectations.

The same architecture also works for lead-routing alerts, quote requests, demo requests, registration acknowledgements, application notifications, and handoffs to a CRM. The important distinction is that Fluent Forms collects data and initiates a server-to-server request; Volanea is the system that delivers the email.

Why use a webhook rather than a browser-side API call

The browser should never send directly to an email API using a Volanea API key. Any API key placed in JavaScript, a public page source, a form hidden field, or a front-end environment variable can be extracted by a visitor. Once exposed, it could be used to send mail on your account until it is revoked.

Fluent Forms submits to WordPress on the server, and its Webhook feed is also server-side. That makes it an appropriate place for a webhook secret or other integration credential. For the strongest boundary, however, keep the Volanea API key in the environment configuration of a small middleware service rather than in WordPress.

This separates responsibilities cleanly:

  1. Fluent Forms accepts and validates the visitor’s form submission.
  2. The Webhook feed sends only the fields your email workflow needs to a dedicated endpoint.
  3. Middleware authenticates the webhook, validates and normalizes data, applies idempotency, and decides what email to send.
  4. Volanea accepts the final server-to-server REST request and delivers the message.

That extra hop is not needless complexity. It prevents a public form from becoming an open email relay, makes it possible to reject malformed payloads, and gives you a stable place to adjust logic without editing the form every time a template changes.

What you need before configuring Fluent Forms

Before building the Webhook feed, prepare the sending and receiving rules. A form integration is much easier to operate when the sender identity, recipient policy, and template ownership are decided before requests start flowing.

You need:

  • A Fluent Forms installation with access to its Webhook integration. Webhooks are a Fluent Forms Pro integration, so confirm your installed edition and license include the Webhook module before designing a direct workflow.
  • A form with stable input names. For this example, use fields named full_name, email, company, subject, and message.
  • A publicly reachable HTTPS endpoint that you control, such as https://forms.example.com/fluent/contact.
  • A Volanea API key with permission to send email.
  • A verified sending domain and a sender address, such as contact@example.com.
  • A random webhook secret shared only by Fluent Forms and your middleware.

Use a sender address at a domain you control. Do not put the visitor’s address in the message from field. Doing that can conflict with DMARC alignment and makes replies unpredictable. Instead, send from your verified domain and set reply_to to the visitor’s submitted email address after validating it.

For implementation details around authentication, domains, and sending requests, consult the email API reference and setup guides. Keep an API key scoped and stored like any other production secret: in a secrets manager or deployment environment, not in a repository or a WordPress page.

Define a small, explicit input contract

A contact form may have dozens of fields, but the email sender should not receive every field by default. Explicit mapping is safer than serializing an entire submission because it avoids leaking internal notes, consent fields, uploads, or irrelevant profile data into an email.

For the example below, the webhook body will have this shape:

{
  "event": "fluent_forms_submission",
  "form_id": "12",
  "submission_id": "{{submission.id}}",
  "full_name": "{inputs.full_name}",
  "email": "{inputs.email}",
  "company": "{inputs.company}",
  "subject": "{inputs.subject}",
  "message": "{inputs.message}"
}

The literal values in braces are Fluent Forms SmartCodes entered into the Webhook feed’s request body. At send time, Fluent Forms replaces them with the values from the submitted form. submission_id should use the submission-ID SmartCode offered by your installed Fluent Forms version; select it from the feed’s SmartCode picker rather than guessing a token. The point is to send the stored submission identifier, not a browser-generated value.

The payload shape is therefore intentionally defined by your Webhook feed. It should not be confused with a promise that every Fluent Forms installation posts one universal JSON schema automatically. Defining a minimal JSON body makes the contract visible, testable, and independent of fields you later add to the form.

Configure the Fluent Forms Webhook feed

Create the Webhook feed on the individual form that should trigger email. In Fluent Forms, open the form, go to its Integrations area, add a Webhook feed, and configure an outbound POST request. The exact labels can vary slightly by Fluent Forms release, so use the Webhook integration’s fields for request URL, request method, request format/body, headers, and conditional logic rather than trying to reproduce an unrelated automation UI.

Configure the feed with these values:

Webhook settingValue
Request URLhttps://forms.example.com/fluent/contact
Request methodPOST
Request formatJSON
Request bodyThe explicit JSON contract shown below
Content-Type headerapplication/json
X-Fluent-Webhook-Secret headerA long random secret stored in the feed configuration
Conditional logicOptional; use it only if the form should send email for selected responses

Use the form’s SmartCode picker to insert input values into the JSON request body. Do not type an assumed field token from a blog post if it does not appear in your form’s picker. SmartCode syntax and available submission tokens can differ by version and configuration, while the picker reflects the fields actually present in your form.

Here is a complete request-body example to enter in the feed, with the field SmartCodes selected from the form:

{
  "event": "fluent_forms_submission",
  "form_id": "12",
  "submission_id": "{{submission.id}}",
  "full_name": "{inputs.full_name}",
  "email": "{inputs.email}",
  "company": "{inputs.company}",
  "subject": "{inputs.subject}",
  "message": "{inputs.message}"
}

If a field can contain quotes, line breaks, or arbitrary text, test the resulting JSON with a real submission. A JSON request body must remain valid after values are substituted. If your Fluent Forms version offers a structured body or field mapper that serializes values safely, prefer that over manually composing JSON strings. The test endpoint should log only sanitized metadata in production; avoid logging message bodies or email addresses indefinitely.

Where the API key belongs

There are two valid designs, but one is usually preferable.

Recommended design: middleware owns the Volanea API key. Fluent Forms stores only X-Fluent-Webhook-Secret. Your endpoint compares that secret with its own environment variable and then reads VOLANEA_API_KEY from the middleware environment. The key never exists in the WordPress database or the browser.

Direct design: Fluent Forms calls Volanea. If your Volanea endpoint and payload requirements can be represented exactly in the Webhook feed, an authorization header can be configured in the server-side Webhook feed. In that case the API key lives in the Fluent Forms feed configuration, not in a client-visible form setting. Restrict WordPress administrator access, understand how your host backs up the database, and rotate the key if an administrator account or backup is exposed.

The middleware design is better for a contact form because it lets you reject suspicious recipients, escape HTML, suppress duplicates, and return a quick acknowledgment before email delivery completes.

Map the Fluent Forms submission into an email

Field mapping is an application decision, not an email-provider feature. Decide which recipient receives the email, which subject is allowed, and where submitted content can appear. Never let an anonymous visitor control the to address or raw HTML without constraints.

For an internal contact notification, a conservative mapping looks like this:

Fluent Forms payload fieldEmail fieldRule
full_nameHTML/text bodyEscape before embedding in HTML
emailreply_toValidate as an email address
companyHTML/text bodyOptional; render a fallback if blank
subjectSubject suffix/bodyDo not let it replace the complete subject unchecked
messageHTML/text bodyEscape HTML and preserve line breaks safely
fixed server valuetoSet to your owned support or sales inbox
fixed server valuefromUse a verified address on your domain

A useful subject is New website enquiry from Ada Lovelace, not a subject supplied entirely by the visitor. This reduces phishing-like subjects and makes mailbox filters more consistent. If you need visitor-selected categories, use a controlled select field and map known values to known labels.

The following Node.js example is a complete middleware route. It accepts the JSON body defined above, checks a shared secret, validates the required values, makes a deterministic idempotency key from the Fluent Forms submission ID, and submits an email request to Volanea. Set VOLANEA_API_KEY, FLUENT_WEBHOOK_SECRET, and the recipient/sender environment variables in your deployment environment.

import express from "express";
import crypto from "node:crypto";

const app = express();
app.use(express.json({ limit: "100kb" }));

const required = (value, name) => {
  if (typeof value !== "string" || value.trim() === "") {
    throw new Error(`${name} is required`);
  }
  return value.trim();
};

const escapeHtml = (value) => value
  .replaceAll("&", "&")
  .replaceAll("<", "&lt;")
  .replaceAll(">", "&gt;")
  .replaceAll('"', "&quot;")
  .replaceAll("'", "&#039;");

app.post("/fluent/contact", async (req, res) => {
  try {
    if (req.get("X-Fluent-Webhook-Secret") !== process.env.FLUENT_WEBHOOK_SECRET) {
      return res.status(401).json({ error: "invalid webhook secret" });
    }

    const { event, form_id, submission_id, full_name, email, company = "", subject = "", message } = req.body;

    if (event !== "fluent_forms_submission" || String(form_id) !== "12") {
      return res.status(400).json({ error: "unexpected form event" });
    }

    const name = required(full_name, "full_name");
    const replyTo = required(email, "email");
    const text = required(message, "message");
    const submissionId = required(String(submission_id), "submission_id");

    if (!/^\S+@\S+\.\S+$/.test(replyTo)) {
      return res.status(400).json({ error: "invalid email" });
    }

    const safeName = escapeHtml(name);
    const safeCompany = escapeHtml(String(company));
    const safeSubject = escapeHtml(String(subject));
    const safeMessage = escapeHtml(text).replaceAll("\n", "<br>");
    const idempotencyKey = crypto
      .createHash("sha256")
      .update(`fluent-form-${form_id}-submission-${submissionId}`)
      .digest("hex");

    const emailPayload = {
      from: { email: process.env.VOLANEA_FROM_EMAIL, name: "Example website" },
      to: [{ email: process.env.CONTACT_RECIPIENT_EMAIL, name: "Website enquiries" }],
      reply_to: { email: replyTo, name },
      subject: `New website enquiry from ${name}`,
      html: `<h1>New enquiry</h1><p><strong>Name:</strong> ${safeName}</p><p><strong>Email:</strong> ${escapeHtml(replyTo)}</p><p><strong>Company:</strong> ${safeCompany || "—"}</p><p><strong>Topic:</strong> ${safeSubject || "—"}</p><p><strong>Message:</strong><br>${safeMessage}</p>`,
      text: `New enquiry\n\nName: ${name}\nEmail: ${replyTo}\nCompany: ${company || "—"}\nTopic: ${subject || "—"}\n\nMessage:\n${text}`
    };

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

    if (!volaneaResponse.ok) {
      const detail = await volaneaResponse.text();
      console.error("Volanea send failed", volaneaResponse.status, detail);
      return res.status(502).json({ error: "email provider rejected send" });
    }

    return res.status(202).json({ accepted: true });
  } catch (error) {
    console.error("Fluent Forms webhook error", error.message);
    return res.status(400).json({ error: error.message });
  }
});

app.listen(process.env.PORT || 3000);

Before deploying, compare the request URL, authorization scheme, message-object field names, and idempotency-header support in the current Volanea documentation with your account’s API version. The code shows the integration boundary and mapping pattern; production implementations must use the exact API contract available in their account.

Send an acknowledgement without creating an open relay

Many teams also want an automatic confirmation sent to the person who filled in the form. That is reasonable, but it needs different safeguards from the internal alert.

The recipient can be the submitted email field only after syntax validation. Keep the content generic: confirm that the request was received, state the expected response time, and link to your privacy policy or support channel if appropriate. Do not include sensitive internal details from the original submission in an automatic response.

A confirmation message can be created in the same middleware route after the internal alert succeeds. Use a fixed subject such as We received your message, a fixed from identity, and a recipient mapped from the validated form email. If an attacker submits another person’s address, that person may receive one confirmation; rate limits, CAPTCHA or anti-spam controls, and form abuse monitoring still matter.

Avoid turning visitor input into recipient lists. A public contact form should never accept a comma-separated to field, CC/BCC fields, arbitrary sender domains, HTML templates, or an unbounded number of recipients. Those options are appropriate for an authenticated application workflow, not for an anonymous website form.

Test the complete Fluent Forms email integration

Testing only the form’s success screen is insufficient. It proves that WordPress accepted the submission, not that the Webhook feed sent valid JSON, the middleware authorized it, or Volanea accepted the email.

Run this sequence in a staging environment first:

  1. Submit the form with every required field populated and an email address you can inspect.
  2. Confirm Fluent Forms recorded the submission and that its Webhook feed was enabled for that form.
  3. Inspect middleware logs for the submission ID, HTTP status, and a provider request or message identifier. Do not log the API key or full message body.
  4. Verify that Volanea accepted the send request and that the sender domain is authorized.
  5. Check the receiving inbox, including spam and quarantine folders.
  6. Submit again with optional fields blank, an apostrophe in the name, multiline text, emoji, and quotation marks. These cases reveal broken JSON construction and unsafe HTML rendering.
  7. Intentionally use an invalid webhook secret and confirm the endpoint returns 401 without sending email.

Test the reply path too. Reply to the internal notification and verify it goes to the visitor through reply_to, while the visible sender remains your verified domain. This protects deliverability and gives your team a natural reply workflow.

For form-level validation, do not confuse an email address that looks syntactically valid with an address that can receive mail. When the form’s business purpose depends on contactability, add an appropriate validation strategy and consider checking addresses with a free address verification tool before adding them to follow-up workflows.

When this breaks

The failure modes in this integration occur at the Fluent Forms-to-webhook hop as often as they occur at the email API. Design for them before a campaign or busy launch turns a transient error into missing notifications or duplicate messages.

A retry creates duplicate emails

A webhook sender may retry when it does not receive a timely successful HTTP response. That can happen even when your endpoint already sent the email but timed out before returning its response. If every request causes a new provider call, a single Fluent Forms submission can generate duplicate internal alerts or confirmations.

Use the Fluent Forms submission ID as the basis for an idempotency key, as in the example. For stronger protection, persist the submission ID and send status in a database with a unique constraint. On a repeated request, return a success response without sending again. Do not use only the visitor email address as the key: the same person can legitimately submit two separate enquiries.

The webhook times out

A webhook should receive a fast response. If middleware waits for slow downstream work, template rendering, database queries, or a provider request before acknowledging receipt, the sending side may treat it as failed and retry.

For higher-volume workflows, validate and persist the submission event quickly, return a 2xx response, and send email asynchronously through a queue. The queue worker can retry provider failures with controlled backoff while the webhook route remains fast. Record the provider response and terminal failure reason so support staff can distinguish “form submitted” from “email delivered.”

Fields are blank or missing

A field can be absent because it is optional, conditionally hidden, renamed after the feed was built, or unavailable in the active Fluent Forms edition or configuration. The Webhook capability itself is a Pro integration, so a site moved to an edition without it cannot rely on the direct outbound request flow.

Treat every optional field as optional in middleware. Use safe defaults for company and subject, but reject a contact workflow that lacks the minimum fields needed to send safely, such as the submission ID, name, email, or message. After changing field names, update the Webhook feed mapping and retest a real submission rather than assuming the form label and internal input name are the same.

The payload is invalid JSON

Manual JSON request bodies are susceptible to unescaped quotes, backslashes, and line breaks from user-entered text. If you see parsing errors, first inspect a sanitized capture of the raw request. Then switch to Fluent Forms’ structured request-body facilities if available in your installed version, or send form-encoded data and normalize it at the middleware layer.

Do not solve this by removing validation. An endpoint that silently accepts malformed data can produce empty emails, incorrect replies, or unexpected values in templates.

Volanea rejects the request

A 401 or 403 generally points to an invalid, revoked, insufficiently permitted, or incorrectly placed API key. A validation error generally points to a mismatch between your JSON body and the provider’s current API schema, an unverified sender, or malformed recipient data. A domain-related issue may also prevent delivery even when the API returns an accepted response.

Log the provider status code and a redacted error response. Never return raw provider details, keys, or recipient information to the public browser. The visitor only needs to know whether the form was accepted; your operations logs need the diagnostic context.

Deliverability and data-handling implications

An integration that technically sends mail is not automatically a dependable email program. Contact-form mail comes from public input and should be treated as untrusted data from the moment it reaches WordPress through to the final rendered message.

Escape all user-provided values before rendering HTML. Keep a plain-text part for recipients who prefer it and for resilient mailbox rendering. Use a clear, stable sender identity and a reply-to address that points to the person who submitted the form. Set up domain authentication for the sending domain and monitor bounces or complaints if confirmations are sent at meaningful volume.

Separate operational notifications from marketing. A message confirming a visitor’s contact request is transactional. It is not permission to add that person to an unrelated promotional list. If the form includes a marketing opt-in, make it an explicit unchecked consent field and route that consent to a separate, auditable subscription workflow.

Retention matters as well. A contact message can contain personal data, account details, or sensitive requests. Limit who can view Fluent Forms entries, restrict middleware logs, set a retention period, and avoid copying full submissions into multiple third-party systems unless that is necessary for the stated purpose.

Alternatives and when to use them

The direct Webhook-to-middleware approach is the best fit when a developer can deploy a small endpoint and needs control over security, formatting, and duplicates. It is not the only possible architecture.

A no-code automation platform can receive a Fluent Forms submission and call an email API, but it introduces another account, another queue, and another place where secrets and personal data are stored. It can be useful for prototypes or simple internal alerts. For production transactional mail, check whether the automation platform can set headers, preserve a stable submission ID for deduplication, handle non-2xx responses predictably, and keep API keys out of user-visible steps.

You can also use Fluent Forms’ own notification capabilities for basic WordPress mail. That is simpler when you only need a low-volume administrative notice. A dedicated sending API is more appropriate when you need a verified sending domain, API-based observability, consistent templates, controlled sender identities, or the ability to make email part of a wider application workflow.

The deciding question is not “can this form send an email?” Almost every WordPress form can. The deciding question is whether the workflow remains secure, traceable, and non-duplicative when traffic increases, a provider is slow, a field changes, or a staff member needs to investigate a missing message.

FAQ

Does Volanea have a native Fluent Forms plugin?

No. This integration uses Fluent Forms’ Webhook capability to send a form-submission payload to an endpoint, which then calls Volanea’s REST API. There is no marketplace installation step to rely on.

What triggers the email in Fluent Forms?

A form submission triggers it. After the visitor submits the configured form, its Webhook feed sends the configured outbound HTTP request.

Where should I store the Volanea API key?

Store it in middleware environment variables or a secrets manager whenever possible. If you make a direct server-side webhook request, keep it only in the protected Fluent Forms feed configuration—not in browser JavaScript, a hidden form field, or a public configuration file.

How do I stop duplicate emails after webhook retries?

Use the Fluent Forms submission ID to create an idempotency key, persist that key or submission status, and treat a repeated event as already processed. Return successful responses promptly after safely accepting the work.

Can I send a confirmation email to the person who submitted the form?

Yes, after validating their submitted email address. Use a fixed verified sender, map their address only to the recipient and reply context as appropriate, keep the confirmation generic, and do not use a contact request as implied marketing consent.