Send email from Elementor without exposing an email API key by treating a successful form submission as a server-side event. Elementor Pro provides both a Form widget and post-submission actions, while Volanea provides the REST sending endpoint; the safe integration point is your WordPress server between them.
This is not a native Elementor app or marketplace plugin. You do not install Volanea inside Elementor, paste a Volanea secret into a public page, or make the visitor’s browser call the email API. Instead, an Elementor Pro Form widget submission triggers server-side WordPress processing. That processing validates the submitted fields, builds a trusted email, and sends it to Volanea with a secret API key stored outside the page configuration.
What actually triggers the email in Elementor
The concrete trigger is an Elementor Pro Form widget submission. A visitor completes the form and presses its submit button. Elementor validates and processes that form submission on the WordPress server, where form actions and Form API hooks can run.
For a simple confirmation email, configure a form with stable field IDs such as:
nameemailmessageconsent(optional, but useful for marketing consent)
The important distinction is between the field’s human-readable label and its ID. A label may change from “Work email” to “Email address” during a redesign. The field ID is the integration contract. Build your field mapping around IDs, not labels.
Elementor Pro’s Form widget includes Actions After Submit in the widget’s Content tab. Its built-in options include a Webhook action, which can POST a submission to an external URL. Elementor also exposes the server-side elementor_pro/forms/new_record hook for developers who need direct control of what happens after a valid record is created.
For sending a transactional email through Volanea, the server-side hook is usually the better fit. It eliminates an unnecessary public relay endpoint, keeps the Volanea key in WordPress configuration, and lets you create a controlled payload with validation and duplicate protection.
Choose the right integration pattern
There are two real ways to connect Elementor form activity to Volanea. Both start with the same trigger: an Elementor Pro Form widget submission.
Option 1: Server-side WordPress hook — recommended
Use Elementor’s elementor_pro/forms/new_record action in a small custom plugin or an mu-plugin. WordPress receives the submission, reads the record fields, and calls Volanea from the server.
Use this when you control the WordPress installation and can add a small amount of PHP. It is the most direct approach because:
- The Volanea API key never enters Elementor’s visual form configuration.
- You can whitelist one form by its configured form name.
- You can validate and normalize recipient data before a send request exists.
- You can generate an idempotency key, log outcomes, and choose how failures affect the form response.
- You avoid relying on a generic webhook payload format for business-critical email.
Option 2: Elementor Webhook action to a protected relay
Add Webhook under Actions After Submit, then set the Webhook URL to an endpoint you control. The relay receives the Elementor request, checks that it is expected, maps the fields, and calls Volanea.
This pattern is useful when your email sending logic lives outside WordPress: for example, in a Cloudflare Worker, an application backend, or a queue worker. It is also the practical route when you need an audit database, cross-site routing, or asynchronous processing.
Do not set the Webhook URL to Volanea’s /v1/send endpoint directly. Elementor’s built-in Webhook action is designed to send form data to a URL; it is not a secure generic REST client where you should place a long-lived provider secret. A direct browser-side implementation would be worse: it would expose a credential that can send mail on your behalf.
The Elementor submission payload: what your code receives
Inside the elementor_pro/forms/new_record hook, Elementor gives WordPress a form record. The raw fields are available through $record->get( 'fields' ). Each field is keyed by its field ID and carries field metadata plus the submitted value.
For a form with IDs name, email, and message, the relevant shape looks like this:
[
'name' => [
'id' => 'name',
'type' => 'text',
'title' => 'Name',
'value' => 'Ada Lovelace',
'raw_value' => 'Ada Lovelace',
],
'email' => [
'id' => 'email',
'type' => 'email',
'title' => 'Email',
'value' => 'ada@example.com',
'raw_value' => 'ada@example.com',
],
'message' => [
'id' => 'message',
'type' => 'textarea',
'title' => 'How can we help?',
'value' => 'I would like a product demonstration.',
'raw_value' => 'I would like a product demonstration.',
],
]
Treat this as untrusted visitor input. The fact that a value originated in Elementor does not make it safe for an email subject, HTML body, CRM record, or internal notification. Escape content when rendering HTML, sanitize text for headers, validate email addresses with WordPress’s email validator, and never let a form field set the sender address, API key, recipient list, or arbitrary request headers.
The built-in Elementor Webhook action also forwards form data after submission, but a generic webhook receiver must be prepared for form-style field data and any metadata Elementor includes for that form. This is why a direct WordPress hook is clearer for the core email action: you receive the record in its native structure, select exact fields by ID, and create the Volanea JSON yourself.
Configure the Elementor form before adding code
Create or edit the Elementor Pro Form widget and make the integration explicit.
Set a stable form name
Give the form a distinct name, such as contact_confirmation. The PHP example below uses that name to make sure that another Elementor form on the same website cannot accidentally trigger the same email workflow.
A form name is not a security boundary by itself. It is an operational guardrail. Use it to prevent a newsletter form, quote request form, or checkout inquiry from being handled by the wrong code path.
Use stable field IDs
In the Form Fields panel, set these IDs:
| Purpose | Suggested field ID | Field type |
|---|---|---|
| Recipient name | name | Text |
| Recipient email | email | |
| Request details | message | Textarea |
| Consent proof | consent | Acceptance or checkbox |
Make the email field required and use Elementor’s Email field type. That improves front-end and server-side validation, but you should still validate it again in your sending code.
Decide whether this is a confirmation, notification, or both
A contact form often needs two separate messages:
- A confirmation to the person who submitted the form.
- An internal notification to the sales, support, or operations team.
Do not combine those recipients in one message. The customer confirmation should go only to the submitted email address. The internal notification should go to a fixed, server-controlled mailbox such as sales@example.com. This prevents a visitor from using a form input to turn your site into an open mail relay.
You can add Elementor’s Email or Email 2 action for a basic fallback or operational copy, but do not use that as evidence that the Volanea send succeeded. The dedicated Volanea request should have its own logs and error handling.
Store the Volanea API key safely
The Volanea API key belongs in server-side configuration, not in Elementor fields, page settings, custom JavaScript, a URL query string, or any client-visible config object.
For a typical WordPress site, add the key to wp-config.php:
define( 'VOLANEA_API_KEY', 'sk_live_replace_with_your_secret_key' );
define( 'VOLANEA_FROM_EMAIL', 'hello@example.com' );
define( 'VOLANEA_FROM_NAME', 'Example Co' );
In a managed deployment, environment variables are even better when your host supports them:
define( 'VOLANEA_API_KEY', getenv( 'VOLANEA_API_KEY' ) );
define( 'VOLANEA_FROM_EMAIL', getenv( 'VOLANEA_FROM_EMAIL' ) );
define( 'VOLANEA_FROM_NAME', getenv( 'VOLANEA_FROM_NAME' ) );
The sender address must belong to a domain you have verified in Volanea. Verify the sending domain before activating the form flow. A verified sender identity is not merely a deliverability preference; it is what lets the API accept mail from your domain rather than treating the request as an unauthorized sender.
Never place the key in an Elementor HTML widget or JavaScript snippet. Anyone can inspect page source, browser developer tools, a cached asset, or a network request. A Volanea secret key is a bearer credential: possession is enough to use it. If it leaks, revoke it, create a replacement, update server configuration, and review your sending logs.
For API fields, authentication, domain setup, templates, and delivery events, keep the email API reference and setup guides close while you implement and test.
Working WordPress code: Elementor field mapping to Volanea
The following example is a complete small plugin. It listens for Elementor’s new_record event, checks the form name, maps the field IDs, validates the recipient, creates both text and HTML versions, and POSTs a Volanea send request.
Create this file as wp-content/mu-plugins/elementor-volanea-email.php. If the mu-plugins directory does not exist, create it. Must-use plugins load automatically and are useful for site-critical integrations because a normal plugin cannot be accidentally disabled from the standard Plugins screen.
<?php
/**
* Plugin Name: Elementor to Volanea Transactional Email
* Description: Sends an Elementor Pro form confirmation through Volanea.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
add_action( 'elementor_pro/forms/new_record', function( $record, $ajax_handler ) {
// Only handle the Elementor form explicitly intended for this workflow.
$form_name = $record->get_form_settings( 'form_name' );
if ( 'contact_confirmation' !== $form_name ) {
return;
}
// Elementor's raw field record is keyed by each field's stable ID.
$fields = $record->get( 'fields' );
$name = isset( $fields['name']['value'] ) ? sanitize_text_field( $fields['name']['value'] ) : '';
$email = isset( $fields['email']['value'] ) ? sanitize_email( $fields['email']['value'] ) : '';
$message = isset( $fields['message']['value'] ) ? sanitize_textarea_field( $fields['message']['value'] ) : '';
if ( ! is_email( $email ) ) {
$ajax_handler->add_error( 'email', 'Please enter a valid email address.' );
return;
}
if ( empty( VOLANEA_API_KEY ) || empty( VOLANEA_FROM_EMAIL ) ) {
error_log( 'Elementor/Volanea: missing server-side configuration.' );
$ajax_handler->add_error_message( 'We could not send your confirmation. Please try again later.' );
return;
}
// A repeat of the exact same form submission maps to the same logical email.
// Do not use a random UUID here: retries need to reuse the same key.
$idempotency_key = 'elementor-contact-' . hash(
'sha256',
$form_name . '|' . strtolower( $email ) . '|' . $name . '|' . $message
);
$subject = 'We received your request';
$text = "Hi {$name},\n\n"
. "Thanks for contacting Example Co. We received your message and will reply soon.\n\n"
. "Your message:\n{$message}\n";
$html = '<!doctype html><html><body>'
. '<p>Hi ' . esc_html( $name ) . ',</p>'
. '<p>Thanks for contacting Example Co. We received your message and will reply soon.</p>'
. '<p><strong>Your message</strong><br>'
. nl2br( esc_html( $message ) )
. '</p></body></html>';
// Volanea REST request: one recipient, verified sender, subject, text, and HTML.
$payload = [
'fromEmail' => VOLANEA_FROM_EMAIL,
'fromName' => defined( 'VOLANEA_FROM_NAME' ) ? VOLANEA_FROM_NAME : '',
'to' => $email,
'subject' => $subject,
'text' => $text,
'html' => $html,
];
$response = wp_remote_post(
'https://api.volanea.com/v1/send',
[
'timeout' => 10,
'headers' => [
'Authorization' => 'Bearer ' . VOLANEA_API_KEY,
'Content-Type' => 'application/json',
'Idempotency-Key' => $idempotency_key,
],
'body' => wp_json_encode( $payload ),
]
);
if ( is_wp_error( $response ) ) {
error_log( 'Elementor/Volanea transport error: ' . $response->get_error_message() );
$ajax_handler->add_error_message( 'Your form was received, but we could not send the confirmation email.' );
return;
}
$status_code = wp_remote_retrieve_response_code( $response );
$response_body = wp_remote_retrieve_body( $response );
if ( $status_code < 200 || $status_code >= 300 ) {
error_log(
'Elementor/Volanea API error ' . $status_code . ': ' . $response_body
);
$ajax_handler->add_error_message( 'Your form was received, but we could not send the confirmation email.' );
return;
}
// Log only non-sensitive operational information in production.
error_log( 'Elementor/Volanea accepted send for form: ' . $form_name );
}, 10, 2 );
This code sends a confirmation email to the form submitter. The mapping is explicit:
- Elementor
fields['name']['value']becomes the greeting name. - Elementor
fields['email']['value']becomes Volanea’storecipient. - Elementor
fields['message']['value']becomes escaped content in bothtextandhtml. - Server configuration supplies
fromEmailandfromName. - A deterministic
Idempotency-Keyrepresents the logical email send.
Volanea’s single-message REST endpoint is POST https://api.volanea.com/v1/send. It accepts a secret key through Bearer authentication and supports the Idempotency-Key header, allowing a retry of the same logical operation without deliberately creating another send. The endpoint can send to one address or multiple recipients, but a confirmation workflow should normally use exactly one recipient per submitted form.
Why field mapping should stay narrow
It is tempting to turn every form field into an email variable automatically. Avoid that default. A narrow mapping is safer, easier to test, and less likely to break when someone edits a form in Elementor.
For example, this is a good mapping:
Elementor field ID Volanea email use
---------------------- -----------------------------------
name Greeting and internal notification
email Recipient for the confirmation only
message Escaped email body content
consent Stored audit value; not an email header
This is a dangerous mapping:
Elementor field ID Unsafe use
---------------------- -----------------------------------
email Add to To, Cc, Bcc, Reply-To, and From
subject Use directly as an email subject
recipient Let visitor choose an internal destination
html Insert directly as HTML without escaping
api_key Accept a provider credential from the form
Let users provide information, not instructions. Sender identity, recipients for internal alerts, template choice, tagging policy, and reply handling should be defined by trusted server-side code.
If you want a reply to go to the person who submitted the form, validate the submitted email and use Volanea’s supported Reply-To field according to the current API reference. Do not make the submitted address the From address. Sending “from” a visitor’s personal domain will usually conflict with domain authentication and creates spoofing risk.
Use a stored template when content becomes more complex
Inline HTML is useful for a small confirmation message, but it becomes hard to govern once you have branded layouts, multiple languages, legal text, or several workflows. Volanea supports reusable templates, so you can move stable email presentation out of WordPress code and send a template identifier plus the relevant data.
That gives content and engineering teams clearer responsibilities:
- WordPress validates the Elementor submission and decides whether an event merits an email.
- The Volanea template controls approved sender content and layout.
- Field mapping supplies only approved variables, such as name, request type, or reference number.
- Delivery outcomes can be monitored separately from the form submission itself.
Do not convert a marketing opt-in form into a transactional confirmation workflow merely because it has an email field. Transactional mail confirms or services a requested action. Marketing mail requires the appropriate consent and unsubscribe handling for your audience and jurisdiction.
When this breaks: Elementor-to-email failure modes
The Elementor-to-Volanea hop has several distinct failure points. Design for them before a customer tells you that they submitted a form twice and received two confirmations.
Elementor retries, visitor resubmits, or a timeout creates duplicate sends
A duplicate can happen whenever the upstream form submission is replayed: a visitor double-clicks Submit, refreshes after a slow response, a host retries work, or an integration layer repeats a request after uncertainty. You should not rely on a vague assumption that a timeout means no email was accepted. A network timeout can occur after Volanea has already received and queued the request.
The answer is idempotency. Reuse the same Idempotency-Key when retrying the same logical submission. The sample uses a stable hash of the form name and submitted values, which protects an immediate identical replay. For a high-volume or business-critical form, improve that design:
- Create a server-side submission ID and store it before sending.
- Use that database ID as the idempotency key.
- Save the Volanea response and message identifier with the submission.
- Retry only failed or unknown operations with the same key.
- Use a queue for slow provider calls instead of keeping the visitor waiting.
A hash of submitted values has a trade-off: a person who intentionally submits the exact same form twice may receive only one confirmation during the idempotency period. For a contact form, that is often desirable. For a booking or payment-related form, use a unique business record ID instead.
Webhook timeouts make the visitor experience unreliable
If you use Elementor’s built-in Webhook action and your receiver performs rendering, database writes, spam checks, provider calls, and CRM synchronization in one synchronous request, it may exceed the web server’s or client’s timeout budget.
Return quickly from the receiver after authenticating and durably recording the event. Then use a queue worker to call Volanea. This has two benefits: the form can show a prompt success state, and temporary API failures can be retried safely using the original idempotency key.
For a small WordPress installation, the direct hook example is acceptable when sends are fast. For lead forms that drive revenue, move the provider request to a queue as traffic and workflow complexity grow.
Expected payload fields are missing
Elementor sends only fields that exist in the particular form. A field may be renamed, deleted, conditionally absent, empty, or configured with a different ID on another page. Elementor’s Form widget itself is an Elementor Pro feature, so a site without the appropriate Pro functionality cannot rely on this flow at all.
Defend against missing input deliberately:
- Use
isset()before reading anyfields[ID]['value']path. - Treat optional values as optional in template rendering.
- Add a user-visible validation error for required data such as email.
- Match only the intended
form_name. - Test every form variant, including multi-step and conditional forms.
Do not use the label as a key. A label is presentation; the ID is implementation.
The API accepts the request but the email is not delivered
A successful API response means Volanea accepted the send request for processing. It is not the same as an inbox placement guarantee. A recipient can later be suppressed, unsubscribed, rejected, bounced, or filtered by their mailbox provider.
For critical messages, capture the accepted-send identifier returned by Volanea and subscribe to delivery, bounce, and complaint events. Then distinguish three states in your own records: form submitted, email accepted, and email delivered. Conflating those states makes support investigations much harder.
A sender domain is not verified
If VOLANEA_FROM_EMAIL uses an unverified domain, the API should reject the message rather than quietly impersonate a sender. Verify the domain in Volanea, publish the required DNS records, and test from the exact sender address you configure in code.
Keep production and staging separate. A staging site should use its own safe sender identity and test recipients, not the production From address plus live customer data.
Testing checklist before publishing the form
A reliable Elementor integration needs more than one successful test submission. Test the operational edges.
- Submit the form with a real internal test address and confirm the expected From name, From address, subject, HTML, and plain-text fallback.
- Submit an invalid email and confirm the form shows a useful validation error rather than attempting an API request.
- Submit with the optional message field empty and confirm your rendering still works.
- Submit twice with the same data and confirm your idempotency behavior is intentional.
- Temporarily use an invalid API key in a non-production environment and confirm logs capture the failure without exposing the key to visitors.
- Test with special characters such as
&,<, quotes, line breaks, and non-ASCII names to verify HTML escaping and text rendering. - Confirm the configured From domain is verified and authentication records are active.
- Check the Volanea send log and, for important workflows, correlate accepted sends with later delivery events.
The transactional email pricing page is useful once you know expected form volume, because an inquiry confirmation flow may look small until it is also handling booking notices, account messages, receipts, and support updates.
A practical architecture for growing Elementor sites
For a single contact form, the WordPress hook approach above is enough. For multiple forms and higher stakes, separate the responsibilities into layers:
Visitor
-> Elementor Pro Form submission
-> WordPress validation and form-name routing
-> durable submission record or queue
-> Volanea POST /v1/send
-> Volanea delivery events
-> your logs, CRM, or support workflow
This architecture makes failures visible instead of silently disappearing inside a visual form builder. It also lets you change form layout without rewriting the email transport layer, as long as stable field IDs and the event contract stay intact.
A useful next step is a routing table in code: contact_confirmation maps to one sender, template, and recipient rule; demo_request maps to another; support_request sends an internal alert and a customer acknowledgment. Keep the rules explicit. A generic “send every Elementor field to every address” function becomes an abuse and maintenance problem quickly.
Conclusion
To send email from Elementor with Volanea, use an Elementor Pro Form widget submission as the trigger and make the Volanea REST call from trusted server-side code. Elementor’s native Webhook action exists, but it should point to a protected relay you control—not directly to an email API with a secret key.
The safe default is a small WordPress integration using elementor_pro/forms/new_record. Map stable field IDs, validate every input, keep the Volanea key in wp-config.php or environment variables, use a verified sender domain, and attach a deterministic idempotency key. That gives you an email flow that is secure enough for production and understandable enough to troubleshoot when a form, network request, or delivery outcome does not behave as expected.
FAQ
Can I send email from Elementor without Elementor Pro?
Not with Elementor’s Pro Form widget workflow described here. The Form widget and its Actions After Submit capabilities are Elementor Pro features. If your site uses another WordPress form plugin, connect that plugin’s server-side submission hook or webhook to the same Volanea sending pattern.
Can I paste my Volanea API key into Elementor’s Webhook settings?
No. Keep the API key on the server. Elementor’s Webhook action should send to a relay endpoint you control, or use the server-side Elementor Form API hook shown above. Never expose a secret key in browser-visible JavaScript, HTML, or page configuration.
What is the Elementor event that starts the send?
The trigger is a successful Elementor Pro Form widget submission. In server-side WordPress code, use Elementor’s elementor_pro/forms/new_record action to run logic after Elementor creates the submitted form record.
How do I stop duplicate confirmation emails?
Send a stable Idempotency-Key with the Volanea request and reuse that exact key if the same logical submission is retried. For stronger protection, store a submission ID in your own database before calling the provider and use that ID as the idempotency key.
Does a successful Volanea API response mean the email reached the inbox?
No. It means the request was accepted for processing. Track delivery, bounce, complaint, suppression, and unsubscribe events separately when delivery status matters to your workflow.