Sending email from Duda with Volanea does not require a native marketplace app, but it does require one important architectural decision: keep the email API call on a server you control. Duda can notify an external endpoint when a visitor submits a form; that endpoint can validate the submission, map its fields, and send the resulting message through Volanea.
This guide uses Duda’s form webhook capability rather than pretending there is a one-click Volanea installation. The pattern is deliberately simple: a Duda form submission triggers an HTTPS POST to middleware, and the middleware makes the authenticated Volanea REST request. It works well for contact-form alerts, lead-routing notifications, request confirmations, and other messages that need to be sent immediately after a visitor takes action.
The integration architecture
The integration has three distinct responsibilities. Keeping them separate makes the setup more secure and substantially easier to troubleshoot.
- Duda collects the visitor’s form submission. The concrete trigger is a visitor submitting a Duda form. In the form’s response settings, configure a webhook destination that points to your middleware URL.
- Your middleware receives and validates the webhook. It reads the form data, identifies the recipient and message content, applies deduplication rules, and rejects malformed requests.
- Volanea sends the email. The middleware calls the Volanea email API with an API key held in a server-side environment variable.
Duda is the event source, not the email sender in this design. That distinction matters. A webhook URL is not a place to expose credentials, and a browser-delivered Duda page is not an appropriate place to store an email API key.
A common first use case is a team notification. A website visitor completes a “Request a quote” form; Duda posts the response to your endpoint; the endpoint sends a detailed notification to sales@yourdomain.com. A second use case is a confirmation email sent to the visitor, provided the form includes an email-address field and the visitor has a reasonable expectation of receiving that confirmation.
What Duda triggers: a form submission webhook
Duda forms can send submitted response data to a configured webhook endpoint. The event that starts the send is therefore a Duda form submission, not a generic page view, button click, or Duda marketplace installation.
In the Duda editor, select the form that should start the workflow and open its form-response or submission settings. Add a webhook destination and supply the publicly reachable HTTPS URL for your middleware, such as:
https://email.example.com/webhooks/duda/contact-form
Use one endpoint per message type when practical. For example, use /webhooks/duda/quote-request for a sales notification and /webhooks/duda/support-request for a support ticket alert. Separate URLs provide a useful first layer of intent: a quote form should not accidentally use the support-email template simply because two forms share a field named Email.
Treat form labels as part of the integration contract
Duda form payloads are built from the fields in the form. That means the labels and field names you create in Duda affect what your middleware must map. Before writing code, standardize the fields in the form:
NameEmailCompanyPhoneMessageConsentwhen you need recorded marketing consent
For a transactional acknowledgement, Email is usually required. For an internal team alert, it may be optional, but retaining it in the message gives the recipient a way to respond to the lead.
Avoid changing a production form field label casually. If your middleware maps Email and an editor changes it to Work email, an unguarded integration can send an email with a blank recipient. Build field aliases into the middleware and alert on missing required values.
Preserve the raw Duda submission
A Duda form webhook contains metadata about the form and site plus the submitted field values. Because the exact set of fields is defined by the form, a representative payload is shaped like this:
{
"site_name": "Acme Studio",
"form_name": "Request a quote",
"submission_date": "2026-10-03T14:22:31.000Z",
"form_fields": [
{"label": "Name", "value": "Avery Chen"},
{"label": "Email", "value": "avery@example.net"},
{"label": "Company", "value": "Northstar Labs"},
{"label": "Message", "value": "We need a proposal for a redesign."}
]
}
Do not assume every Duda form has exactly those fields or that every visitor supplies every optional value. Capture one real test submission in your request logs before going live and compare it with the form currently published on the site. The raw body is also the evidence you need when a later editor changes a form.
The code below accepts this form-field list and intentionally turns it into a lower-case label map. That makes the field mapping explicit rather than burying assumptions in an email template.
Why middleware is required
Duda’s webhook configuration is for a destination URL. It is not a safe place to put a long-lived Volanea credential, and the Duda page itself runs in a visitor’s browser. If an API key is shipped to browser JavaScript, any visitor can inspect it in developer tools, copy it, and send email at your expense and under your sending identity.
Use a small server-side service instead. It can be a serverless function, a container endpoint, or an API route in an existing application. The only requirements are that it can accept HTTPS POST requests and keep environment variables private.
Store these values in the middleware deployment’s secret or environment-variable manager:
VOLANEA_API_KEY=replace-with-a-server-side-key
VOLANEA_FROM_EMAIL=notifications@your-verified-domain.example
DODA_WEBHOOK_SECRET=long-random-value-used-in-your-webhook-url
The third name intentionally represents your own inbound secret rather than a Duda API credential. If the Duda webhook configuration does not provide a request-signature mechanism for your account and setup, place a high-entropy secret in the webhook path or query string and validate it at the middleware. For example:
https://email.example.com/webhooks/duda/contact-form?token=long-random-secret
A URL secret is not as strong as a signed request because it can appear in logs. It is still better than accepting unauthenticated POST requests from the public internet. Redact query strings in logs where possible, rotate the secret if it leaks, rate-limit the route, and never put the Volanea key in that URL.
The field mapping and Volanea API request
The following Node.js example shows the complete transformation: Duda’s form_fields array becomes a simple map, the visitor’s Email becomes the recipient of an acknowledgement, and the same data becomes HTML for an internal notification.
The Volanea request uses the sending endpoint and authentication model documented in the email API reference and setup guides. Set VOLANEA_API_URL to the current send endpoint shown in your Volanea account documentation rather than hard-coding an unverified URL into a frontend project.
import express from "express";
import crypto from "node:crypto";
const app = express();
app.use(express.json({ limit: "256kb" }));
const required = (name) => {
const value = process.env[name];
if (!value) throw new Error(`Missing environment variable: ${name}`);
return value;
};
const escapeHtml = (value = "") =>
String(value)
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll('"', """)
.replaceAll("'", "'");
function dudaFieldsToMap(formFields = []) {
return Object.fromEntries(
formFields
.filter((field) => field && field.label)
.map((field) => [String(field.label).trim().toLowerCase(), field.value ?? ""])
);
}
app.post("/webhooks/duda/contact-form", async (req, res) => {
// Put this token in the Duda webhook URL as ?token=... .
if (!crypto.timingSafeEqual(
Buffer.from(req.query.token || ""),
Buffer.from(required("DUDA_WEBHOOK_SECRET"))
)) {
return res.status(401).json({ error: "Unauthorized webhook" });
}
// Duda webhook payload fields
const { site_name, form_name, submission_date, form_fields = [] } = req.body;
const fields = dudaFieldsToMap(form_fields);
// Explicit Duda-to-email mappings. Support aliases for edited labels.
const leadName = fields.name || fields["full name"] || "there";
const leadEmail = fields.email || fields["email address"] || "";
const company = fields.company || "Not provided";
const phone = fields.phone || fields["phone number"] || "Not provided";
const message = fields.message || fields.enquiry || "Not provided";
if (!leadEmail || !/^\S+@\S+\.\S+$/.test(leadEmail)) {
return res.status(422).json({ error: "The Duda form did not include a valid Email field" });
}
const notificationHtml = `
<h1>New Duda form submission</h1>
<p><strong>Site:</strong> ${escapeHtml(site_name)}</p>
<p><strong>Form:</strong> ${escapeHtml(form_name)}</p>
<p><strong>Submitted:</strong> ${escapeHtml(submission_date)}</p>
<p><strong>Name:</strong> ${escapeHtml(leadName)}</p>
<p><strong>Email:</strong> ${escapeHtml(leadEmail)}</p>
<p><strong>Company:</strong> ${escapeHtml(company)}</p>
<p><strong>Phone:</strong> ${escapeHtml(phone)}</p>
<p><strong>Message:</strong><br>${escapeHtml(message)}</p>`;
// The body below is the Volanea email request. Keep the API key server-side.
const volaneaResponse = await fetch(required("VOLANEA_API_URL"), {
method: "POST",
headers: {
"Authorization": `Bearer ${required("VOLANEA_API_KEY")}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
from: required("VOLANEA_FROM_EMAIL"),
to: ["sales@yourdomain.example"],
reply_to: leadEmail,
subject: `New quote request from ${leadName}`,
html: notificationHtml,
text: `New Duda submission from ${leadName} (${leadEmail}). Company: ${company}. Phone: ${phone}. Message: ${message}`
})
});
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 the send" });
}
return res.status(202).json({ accepted: true });
});
app.listen(process.env.PORT || 3000);
Two details deserve emphasis. First, the reply_to value is the visitor’s email address, while from remains an address at a domain you control and have authenticated for Volanea. This preserves DMARC alignment and lets the sales team reply directly to the lead.
Second, do not build HTML by inserting raw submitted values. A visitor can enter angle brackets, markup, or content that alters the appearance of a notification. The example escapes each value before putting it into HTML. Keep the plain-text alternative too; it is helpful for recipients with HTML disabled and for troubleshooting.
Configure sending identity before testing
A technically successful API call is not the same as successful inbox delivery. Before pointing Duda at production middleware, configure a sender address at a domain you own and complete the required authentication records supplied by Volanea.
Use a domain-based From address such as notifications@yourdomain.example, not the visitor’s address. The visitor’s address belongs in reply_to. Sending “from” arbitrary form entrants can cause DMARC failures, undermine trust, and create an easy path for abuse.
Your practical preflight list should include:
- A verified sending domain and the required DNS authentication records.
- A From address that belongs to that authenticated domain.
- A clear internal recipient for lead notifications.
- A Reply-To mapping to the visitor’s submitted email.
- A valid test recipient that you control.
- Logging that stores the submission identifier or a derived deduplication key, not a full API key or sensitive content.
If you send an acknowledgement to the visitor, make the message match the form action. “We received your request” is transactional. Promotional follow-up is marketing email and should be gated by an appropriate consent field and your organization’s compliance process.
Test the complete path in the right order
Do not debug Duda, your middleware, and email delivery simultaneously. Test each boundary separately so that a failure points to a single owner.
1. Test the Volanea request from the server
Deploy the middleware with the required environment variables and invoke it with a saved sample payload. Verify that the message arrives, that its From address is correct, and that Reply-To is the lead address. If this fails, the issue is API configuration, sender verification, or message construction—not Duda.
2. Test Duda with a controlled submission
Publish or preview the page as appropriate for the form setup, submit a unique test value such as Duda test 2026-10-03 1422, and inspect middleware logs. Confirm all four milestones:
- Duda made an HTTP request to the endpoint.
- The endpoint parsed the expected
form_nameand field values. - The endpoint received a successful response from Volanea.
- The intended recipient received one email with the expected contents.
3. Test negative cases
Submit a form with no email address if the field is optional. Submit a malformed address. Temporarily use an invalid webhook secret. These tests confirm that invalid input produces a useful log entry without sending misleading messages.
Also test an entry containing <b>test</b> in the Message field. The notification should display the literal characters rather than rendering arbitrary HTML. This is a simple but meaningful check that your template escapes untrusted form content.
When this breaks: Duda-to-email failure modes
Every webhook integration is a distributed system: Duda, the internet, your middleware, and Volanea must all work at the same time. Build for the known failure modes rather than assuming a form submission has exactly one effect.
Duda retries can create duplicate sends
A webhook sender may retry when it does not receive a successful response quickly enough or receives a server error. A retry is correct behavior from the sender’s perspective, but it can produce two emails if your endpoint sent the first email and then timed out before returning success.
Add idempotency to the middleware. Derive a key from stable submission attributes, such as the site name, form name, submission timestamp, and normalized email, then store it in Redis, a database, or another short-lived shared store before sending. If the same key reappears within a reasonable window, return a success response without sending again.
Do not use only the lead’s email as the idempotency key. One person may legitimately submit two separate quote requests. A key based on the content hash plus timestamp is usually safer. If Duda includes a submission-specific identifier in the payload you receive, prefer that identifier and retain it in your logs.
Webhook timeouts cause ambiguity
Your endpoint should respond promptly. Slow template rendering, database queries, or a long wait on a downstream API increases the chance that Duda regards the webhook as failed and retries it.
For modest form volumes, validate the request, record an idempotency key, submit the email request, and return a 2xx response quickly. For higher volume or workloads that need enrichment, enqueue a job after validation and return success once the job is durably accepted. The worker can then call Volanea outside the webhook request window.
The trade-off is intentional: synchronous sending gives immediate confirmation but couples Duda’s webhook lifecycle to the email API; queueing improves resilience but requires a durable queue and retry policy. In either model, do not return success before you have either sent the email or durably recorded work that will send it.
Fields may be missing, renamed, or unavailable
Duda sends fields based on the actual form configuration. Optional fields can be empty, editors can rename labels, and form variants can differ by page or plan. A payload that worked for Email yesterday may contain Email address tomorrow after an editorial change.
Handle this in three layers:
- Validate required fields before calling Volanea.
- Support a small, explicit alias list for expected labels.
- Alert when required values are absent or an unexpected form name reaches the endpoint.
Never silently substitute a team address for a missing visitor email when sending a visitor acknowledgement. That turns a data-quality error into a privacy and customer-experience problem. For internal alerts, state “Not provided” clearly rather than implying the lead supplied the value.
A 4xx or 5xx response has different meaning
A 401 or 403 from your middleware usually means the webhook secret was wrong or rotated. A 422 indicates a payload-validation problem such as a missing Email field. A 429 can mean rate limiting. A 5xx indicates a transient service or deployment issue and is the class most likely to cause retries.
Log a correlation ID for every request, the form name, a hashed email value where needed, the deduplication result, and the Volanea response status. Do not log the Volanea API key. Avoid retaining message content in broad-access logs unless your privacy policy and operational need justify it.
Delivery and template design choices
The most useful Duda-triggered email is usually concise and action-oriented. An internal lead alert should show who submitted the form, what they asked for, when it was submitted, and a Reply-To address. A visitor confirmation should say what happens next and when they can expect a response.
For example, an internal subject line can be New quote request from Avery Chen. A visitor acknowledgement can be We received your quote request. Avoid sending the full visitor message back to the visitor unless it is necessary; repeating sensitive details in email may create unnecessary exposure.
Use separate templates for different Duda forms. A contact form, event registration, and support request carry different expectations and recipients. The middleware should route by form_name or, more safely, by the unique endpoint assigned to each form. This keeps logic understandable when nontechnical editors maintain the site.
If address quality is especially important for a confirmation flow, validate the address before sending. A typo in a form email field can create bounces and make support follow-up harder. You can check an address with the free address verification tool during development or incorporate validation into your own lead-handling workflow.
Alternatives when a direct webhook is not your preferred path
A native Duda form webhook plus middleware is the most direct route because it minimizes the number of systems handling the submission. It is not the only possible design.
Duda also supports integrations with automation services such as Zapier. In that model, a Duda form-submission trigger starts a Zap, and the Zap can call your middleware with a Webhooks action. This can be useful for teams that already use Zapier to add leads to a CRM, notify Slack, or create tasks.
However, do not move the Volanea API key into a client-side Duda script just because an automation route feels more complex. If an automation platform is used, keep the key in that platform’s encrypted connection or, preferably, keep the email call in your own server-side endpoint. The same security principle applies regardless of how the event travels.
Choose the direct webhook route when you need low latency, control over mapping, and strong idempotency. Choose an automation layer when operations teams need to visually manage multiple downstream actions and accept the additional dependency. In both cases, test the actual payload at the point your code receives it.
Operational checklist before launch
Before enabling the webhook on a production Duda form, review this checklist with the person who owns the site and the person who owns email delivery:
- The Duda form has the correct webhook URL and no test endpoint.
- The middleware URL uses HTTPS and validates an inbound secret or signature where available.
- The Volanea key exists only in server-side secrets, never in Duda page code, public configuration, or a Git repository.
- The From address uses an authenticated domain; visitor addresses are used only as Reply-To.
- Required field mappings have tests, including renamed-label aliases where necessary.
- Duplicate prevention is implemented before the first production send.
- The endpoint has monitoring for non-2xx responses and Volanea send failures.
- The recipient list and email copy have been approved for the form’s purpose.
- The privacy notice and consent language reflect any visitor confirmation or marketing follow-up.
The result is intentionally unglamorous infrastructure: a form submission becomes a validated event, and a validated event becomes an authenticated email request. That is exactly what makes it dependable.
FAQ
Can I install Volanea from the Duda marketplace?
No. This setup does not rely on a native Volanea Duda app or marketplace plugin. It uses Duda’s form webhook to notify a secure middleware endpoint, which then calls the Volanea API.
Where should I store the Volanea API key?
Store it only in server-side environment variables or a managed secret store used by your middleware. Do not put it in Duda custom code, page JavaScript, browser storage, a form field, or a webhook URL.
Can a Duda form send an acknowledgement to the person who submitted it?
Yes, if the form captures a valid email address and your middleware maps it to the Volanea recipient field. Keep your authenticated domain in the From field and use the visitor’s address as Reply-To only for internal notifications.
How do I stop duplicate emails after a webhook retry?
Implement idempotency in middleware. Store a submission ID when available, or a short-lived hash derived from stable form-submission data, before sending. Return a successful response for repeated deliveries of the same submission without sending again.
What happens if the form does not include the expected Email field?
Validate the payload and return a controlled error rather than sending to an empty or fallback recipient. Support known label aliases, log the form name and missing field, then correct the Duda form or mapping before resuming sends.