If you need to send email from Ninja Forms with Volanea, the reliable path is to use Ninja Forms’ server-side submission hook or its Webhooks add-on—not a native Volanea integration. This guide shows a production-minded implementation that maps submitted fields into a Volanea REST email request while keeping your API key out of browser-visible code.

The integration model: Ninja Forms submission to Volanea

Ninja Forms is a WordPress form builder. Its basic Email action can notify site owners or respondents through WordPress’s mail configuration, but it does not provide a native Volanea app, marketplace listing, or one-click Volanea connection.

That distinction matters. A browser-based form should never call an email API directly because doing so would expose the sending credential to anyone who can inspect the page, browser network requests, or bundled JavaScript. The form submission must reach WordPress first, then WordPress—or a trusted automation service—can make the authenticated API request to Volanea.

There are two practical architectures:

  1. WordPress hook route: Use Ninja Forms’ ninja_forms_after_submission action to run PHP after a submission is processed. Your PHP code reads the submitted values and calls Volanea over HTTPS.
  2. Webhook route: Use the Ninja Forms Webhooks add-on to post submission data to a server-side endpoint you control. That endpoint validates the request, maps the data, and sends through Volanea.

For most WordPress sites, the hook route is simpler, has fewer moving parts, and avoids sending personally identifiable form data through an additional service. The webhook route is useful when the email logic belongs in an existing integration service, when several systems need the same submission event, or when the WordPress host cannot safely run custom code.

What actually triggers the send in Ninja Forms

The event is a form submission. Ninja Forms processes the submitted form, runs its configured actions, and exposes an ninja_forms_after_submission WordPress action for server-side code.

The code in this guide attaches to that action:

add_action( 'ninja_forms_after_submission', 'acme_send_volanea_email', 10, 1 );

The callback receives $form_data, an array that includes form metadata and a fields array. Each item in fields contains data such as the field key, label, value, and field ID. The field key is the stable identifier you should use for mapping. A label such as “Email address” can change when an editor updates form copy; a key such as email should be treated as the integration contract.

This is not a client-side trigger. The callback runs in WordPress after Ninja Forms receives the submission. That means it can read a secret stored on the server and can use WordPress HTTP functions to contact Volanea without disclosing authentication details to the visitor.

Before publishing code, open the relevant Ninja Forms form and confirm the field keys. In a typical contact or lead form, you might use these keys:

  • name for the visitor’s name
  • email for the visitor’s email address
  • message for their message
  • product for a selected product or plan
  • consent for marketing consent, if applicable

Do not assume the visible labels are the keys. Check each field’s advanced settings and update the PHP mapping if your keys differ.

Why the server-side hook is usually the best route

A custom WordPress hook is not a native Volanea plugin. It is a small, explicit integration that you own. That is an advantage when deliverability and data handling matter: the request flow is visible, testable, and not dependent on a browser session.

The hook route also gives you control over decisions that form-builder email actions often hide:

  • Whether a particular form should send an email at all.
  • Which recipient should receive the message.
  • Whether the submitter’s address belongs in reply_to rather than from.
  • How to escape user-supplied text before placing it in HTML.
  • How to prevent an automatic retry from creating a duplicate email.
  • Which failed sends should be logged, retried, or escalated.

In particular, use a verified address on a domain you control as the sender. Do not put a visitor’s submitted address in the From header. DMARC alignment and common anti-spoofing policies make that a poor delivery pattern. Put the visitor’s email address in reply_to, while the From address remains something such as forms@example.com.

Store the Volanea API key safely

Put the Volanea API key in server-side configuration, not in a Ninja Forms text field, hidden field, JavaScript variable, page builder setting, or public repository. A hidden HTML field is hidden only from the ordinary page layout; it is still delivered to the browser and can be edited by a visitor.

For a WordPress installation, a straightforward approach is to define the key in wp-config.php, ideally from a host-managed environment variable:

// wp-config.php
// Prefer setting VOLANEA_API_KEY in the hosting control panel or secret manager.
define( 'VOLANEA_API_KEY', getenv( 'VOLANEA_API_KEY' ) ?: 'replace-with-a-server-side-secret' );

On a managed host, use its secret or environment-variable interface instead of committing a value to Git. If your deployment system supports separate staging and production environment variables, use different Volanea API keys for each environment. That prevents a test form from sending as your production domain and makes key rotation less disruptive.

Only WordPress administrators and server operators should be able to alter the integration. An administrator can generally install plugins or edit settings, so WordPress role permissions still matter. A secret stored in the WordPress database may be acceptable for some sites, but a server environment variable or a secret manager is a stronger default because it reduces accidental exposure in database exports and site migrations.

For endpoint, authentication, and message-object details, keep the implementation aligned with the current email API reference and setup guides. API keys should have the smallest practical scope, and a suspected exposed key should be revoked and replaced rather than merely hidden.

Working PHP: map a Ninja Forms submission into an email request

Place the following code in a small site-specific plugin or an mu-plugin. Avoid putting business-critical integration code in a theme’s functions.php: a theme change can silently remove the send behavior.

This example sends an internal notification after submissions from one form. Replace 42 with your Ninja Forms form ID, replace the sender and recipient addresses, and match the array keys in $values to your real Ninja Forms field keys.

<?php
/**
 * Plugin Name: Ninja Forms to Volanea
 * Description: Sends selected Ninja Forms submissions through Volanea.
 */

add_action( 'ninja_forms_after_submission', 'acme_send_volanea_email', 10, 1 );

function acme_send_volanea_email( $form_data ) {
    // Run only for the intended Ninja Forms form.
    if ( empty( $form_data['form_id'] ) || (int) $form_data['form_id'] !== 42 ) {
        return;
    }

    // Convert Ninja Forms' fields array into key => value pairs.
    $values = array();
    foreach ( (array) $form_data['fields'] as $field ) {
        if ( isset( $field['key'] ) ) {
            $values[ $field['key'] ] = isset( $field['value'] ) ? $field['value'] : '';
        }
    }

    $name    = sanitize_text_field( $values['name'] ?? '' );
    $email   = sanitize_email( $values['email'] ?? '' );
    $message = sanitize_textarea_field( $values['message'] ?? '' );
    $product = sanitize_text_field( $values['product'] ?? '' );

    // Do not send malformed reply-to values to the email provider.
    if ( ! is_email( $email ) ) {
        error_log( 'Volanea form email skipped: missing or invalid email field.' );
        return;
    }

    // Use a stable submission-related idempotency value where available.
    $submission_id = ! empty( $form_data['submission_id'] )
        ? (string) $form_data['submission_id']
        : wp_generate_uuid4();

    $text = "New Ninja Forms enquiry\n\n"
        . "Name: {$name}\n"
        . "Email: {$email}\n"
        . "Product: {$product}\n\n"
        . "Message:\n{$message}";

    $html = '<h2>New Ninja Forms enquiry</h2>'
        . '<p><strong>Name:</strong> ' . esc_html( $name ) . '</p>'
        . '<p><strong>Email:</strong> ' . esc_html( $email ) . '</p>'
        . '<p><strong>Product:</strong> ' . esc_html( $product ) . '</p>'
        . '<p><strong>Message:</strong><br>' . nl2br( esc_html( $message ) ) . '</p>';

    $payload = array(
        'from' => array(
            'email' => 'forms@example.com',
            'name'  => 'Example Website Forms',
        ),
        'to' => array(
            array(
                'email' => 'sales@example.com',
                'name'  => 'Sales Team',
            ),
        ),
        'reply_to' => array(
            'email' => $email,
            'name'  => $name,
        ),
        'subject' => 'New enquiry from ' . ( $name ?: 'website visitor' ),
        'html'    => $html,
        'text'    => $text,
    );

    $response = wp_remote_post(
        'https://api.volanea.com/v1/emails',
        array(
            'timeout' => 15,
            'headers' => array(
                'Authorization' => 'Bearer ' . VOLANEA_API_KEY,
                'Content-Type'  => 'application/json',
                'Idempotency-Key' => 'ninja-forms-' . $submission_id,
            ),
            'body' => wp_json_encode( $payload ),
        )
    );

    if ( is_wp_error( $response ) ) {
        error_log( 'Volanea request failed: ' . $response->get_error_message() );
        return;
    }

    $status = (int) wp_remote_retrieve_response_code( $response );
    if ( $status < 200 || $status >= 300 ) {
        error_log( 'Volanea rejected message. HTTP ' . $status . ': ' . wp_remote_retrieve_body( $response ) );
    }
}

The significant mapping happens in the foreach loop. Ninja Forms provides an array of fields; the loop turns that into a predictable associative array. The later lines map name, email, message, and product into the message payload. That makes it easy to add a field, remove one, or route messages based on a selection without rewriting the entire integration.

The sample request uses a JSON email object, bearer authentication, and an idempotency header. Confirm the exact Volanea endpoint and any account-specific sending requirements before deployment, particularly if your API version uses different message property names or idempotency handling.

Understand the submission payload before mapping it

At the Ninja Forms hook, $form_data is a PHP array rather than a raw webhook JSON document. Conceptually, the relevant part looks like this:

array(
  'form_id' => 42,
  'fields'  => array(
    array( 'key' => 'name',    'label' => 'Your name', 'value' => 'Avery Lee' ),
    array( 'key' => 'email',   'label' => 'Email',     'value' => 'avery@example.net' ),
    array( 'key' => 'message', 'label' => 'Message',   'value' => 'Please contact me.' ),
    array( 'key' => 'product', 'label' => 'Product',   'value' => 'Enterprise' ),
  ),
)

The outgoing JSON created by the example is correspondingly explicit:

{
  "from": {"email": "forms@example.com", "name": "Example Website Forms"},
  "to": [{"email": "sales@example.com", "name": "Sales Team"}],
  "reply_to": {"email": "avery@example.net", "name": "Avery Lee"},
  "subject": "New enquiry from Avery Lee",
  "html": "<h2>New Ninja Forms enquiry</h2>...",
  "text": "New Ninja Forms enquiry\n\nName: Avery Lee\nEmail: avery@example.net..."
}

This separation is intentional. Raw form fields are not automatically a safe email payload. Sanitize plain text, validate email addresses, and escape data when inserting it into HTML. If a field can contain an array—for example, a multi-select control—normalize it before rendering, such as by joining approved values with commas.

Use the Webhooks add-on when an external workflow owns the logic

Ninja Forms also offers a Webhooks add-on for posting form data to a remote URL. This is a valid alternative, but it does not turn Ninja Forms into a Volanea-native integration. It creates an extra hop:

Visitor → Ninja Forms submission → Ninja Forms webhook → your middleware → Volanea API

Configure the webhook to send a JSON POST to an HTTPS endpoint you operate. In the webhook field mapping, include only the values that middleware needs, such as the submission identifier, form ID, name, email, message, and an event type. A useful normalized request body is:

{
  "event": "ninja_forms.submission",
  "form_id": 42,
  "submission_id": "12345",
  "name": "Avery Lee",
  "email": "avery@example.net",
  "message": "Please contact me.",
  "product": "Enterprise"
}

Your middleware should authenticate the incoming webhook using a shared secret or a signature scheme that you control. Then it should perform the same validation, escaping, recipient selection, and Volanea API call shown in the PHP example. Keep the Volanea credential in the middleware’s environment variables, not in the Ninja Forms webhook fields.

The Webhooks add-on may be appropriate when a team already uses a queue worker, serverless function, or integration API. It is also helpful if one submission must create a CRM lead, open a support ticket, and send a notification. However, each new service adds latency, outage modes, privacy considerations, and a place where retries can produce duplicate side effects.

If you use Zapier or Make

Ninja Forms offers automation integrations, including Zapier-oriented workflows, but an automation platform should still be treated as middleware rather than as a place to expose a secret in the browser. The pattern is the same: a Ninja Forms submission starts the automation, a server-side automation action builds a Volanea request, and the Volanea key is stored in that automation account’s encrypted connection or secret facility.

This route is useful when non-developers need to maintain routing rules. For example, a product selector can send “Demo” enquiries to sales and “Existing customer” enquiries to support. Keep the email rendering and validation disciplined even in a low-code flow. Map a submitted email to Reply-To, not From; use a verified From address; and include both text and HTML versions where your sending configuration supports them.

Check whether the plan in use includes the required Ninja Forms automation or webhook capability before designing around it. A field that exists in WordPress does not automatically become available as an automation token, and premium add-ons or plan entitlements can affect which outbound actions are available.

Deliverability choices that affect this integration

An API call that returns success is not the same thing as an email appearing in an inbox. The form integration controls message construction, while your Volanea account and sending domain control authentication, reputation, and downstream delivery behavior.

Use these defaults for form-originated transactional messages:

  • Send from a domain and address verified for your Volanea account.
  • Configure the domain’s required SPF and DKIM DNS records before production use.
  • Use a recognizable sender name, such as “Example Support” or “Example Website Forms.”
  • Keep the visitor in Reply-To, not From.
  • Include a text alternative for operational notifications and customer confirmations.
  • Do not add marketing content to an operational acknowledgement unless the recipient has given the appropriate consent.
  • Suppress or handle known-invalid addresses before sending customer-facing confirmations; Volanea’s email address verification tool can help with that decision.

If the form sends an automatic receipt to the person who submitted it, make the content narrowly useful: confirm receipt, set expectations, and identify the next action. Do not make an enquiry receipt look like a bulk campaign. A sudden stream of form-confirmation messages to malformed, typoed, or abusive addresses can harm operational deliverability even though each message is technically transactional.

When this breaks

This integration has a specific failure boundary: Ninja Forms completes a submission, then WordPress or middleware sends an HTTP request to Volanea. Diagnose failures by determining which side of that boundary succeeded.

Retries can create duplicate sends

A timeout does not prove that Volanea did not accept the message. WordPress, middleware, or a webhook sender can retry after a network timeout, while the original request may already have reached the email API. Without idempotency, the result can be two notifications for one form submission.

Use a stable submission ID as the idempotency value whenever it is available. Do not generate a fresh random idempotency key for every retry. In the PHP example, the ninja-forms- prefix plus submission ID gives repeated attempts for the same submission the same identity. If your implementation needs stronger control, record successful submission IDs in a custom WordPress table or a transient and decline to send the same notification twice.

Webhook timeouts need a fast acknowledgment

A webhook endpoint that waits for a slow downstream process can time out. If Ninja Forms or a middleware platform sees a timeout, it may retry. Make the endpoint validate and acknowledge quickly, then queue the Volanea send in a worker where possible.

For a direct WordPress hook, the visitor’s form request can be slowed by a 15-second API timeout. That may be acceptable for a low-volume contact form but is not ideal for high-traffic sites. Consider placing messages in a queue and processing them asynchronously if response time or reliability becomes important.

Fields may be missing or differently shaped

A form editor can rename a field key, delete an optional field, add conditional logic, or change a multi-select value into an array. Automation and webhook features can also vary by installed add-on or plan. Code defensively: treat optional fields as optional, validate required values, and log a non-sensitive diagnostic when an expected field is absent.

Do not log full form bodies by default. Messages often contain phone numbers, account details, or sensitive requests. Log the form ID, submission ID, HTTP status, and an error category; restrict access to detailed diagnostics and set a retention period.

Authentication and domain configuration failures

A 401 or 403 response generally points to a missing, revoked, incorrectly scoped, or malformed API key. A validation response often points to an unverified sender address, an invalid recipient, or a malformed payload. DNS authentication changes can take time to propagate, so verify domain status before concluding that application code is at fault.

Test the complete path before going live

Start with a staging form and a staging key if possible. Submit predictable test values and verify every layer: Ninja Forms capture, PHP execution or webhook receipt, HTTP response, Volanea message event, and inbox placement.

A compact test checklist is:

  1. Submit with a valid name, email, and short message.
  2. Submit with an invalid email and confirm the integration does not send an invalid Reply-To value.
  3. Submit without optional fields and confirm the message remains readable.
  4. Submit text containing <script> or HTML characters and confirm the email displays escaped text rather than executable or malformed markup.
  5. Repeat a request with the same submission ID to verify duplicate protection.
  6. Temporarily use an invalid API key to confirm errors are recorded without printing secrets to the page.
  7. Confirm the From domain is authenticated and the Reply-To address is the visitor’s address.

Keep a separate production recipient during early testing. A broad team distribution list can turn a mapping error or retry loop into a noisy incident quickly.

Operational improvements after the first version

Once the basic connection works, make the behavior intentional. Route messages based on the selected department, attach a CRM identifier where allowed, add a correlation ID to logs, and create an alert for repeated API failures. These are better additions than simply adding more email content.

For customer acknowledgements, consider separating internal notification and external confirmation into distinct sends. They have different recipients, different failure impact, and often different retention or consent expectations. An internal sales notification can include routing context; a customer confirmation should be concise and should not expose internal notes or hidden field values.

Review the integration whenever the form changes. Form builders make editing easy, which means an editor can unintentionally alter a key that production code depends on. Treat field keys, form IDs, recipient rules, and templates as configuration that deserves change review.

Conclusion

To send email from Ninja Forms with Volanea, use the Ninja Forms submission lifecycle as the trigger and make the authenticated API call on the server. The ninja_forms_after_submission hook is the most direct route for a WordPress-managed implementation; the Webhooks add-on and automation services are useful when an external workflow is genuinely needed.

The durable parts of the design are not the form labels or the visual builder settings. They are stable field keys, server-side secret storage, validated data, a verified sender domain, idempotency for retries, and logging that helps diagnose failures without exposing submitted data.

FAQ

Does Ninja Forms have a native Volanea plugin?

No. Do not look for a one-click Volanea marketplace installation. Use a server-side WordPress hook, the Ninja Forms Webhooks add-on with trusted middleware, or a supported automation workflow.

What Ninja Forms event should trigger the email?

Use the completed form submission. In custom WordPress code, ninja_forms_after_submission is the server-side action used to process the submission data after Ninja Forms handles it.

Can I put the Volanea API key in a hidden Ninja Forms field?

No. Hidden fields are still sent to the visitor’s browser and can be inspected or changed. Store the key in a server environment variable, wp-config.php, a secret manager, or trusted middleware configuration.

Why should the submitter be Reply-To rather than From?

The From address should be a verified address on your sending domain. Using a visitor’s external address as From can fail authentication checks and appears spoofed; Reply-To preserves the ability for your team to respond directly.

How do I stop duplicate emails after a timeout?

Use the Ninja Forms submission ID as a stable idempotency value, pass it with the API request where supported, and optionally retain sent submission IDs in your own data store before retrying.