Send email from HubSpot with Volanea when a CRM event needs a message that is more transactional, programmatic, or operational than a standard HubSpot marketing email. The practical route is a HubSpot contact-based workflow that runs a custom code action, maps contact properties into a Volanea API request, and keeps the Volanea secret out of browser-accessible code.

Volanea does not provide a native HubSpot app, HubSpot Marketplace listing, or one-click plugin. This is therefore an API integration, not an installation flow. HubSpot does have native outbound webhook actions and serverless custom code actions for workflows, but the custom code route is the stronger fit here because it can assemble a complete Volanea request, use a securely stored secret, validate required properties, and send a deterministic idempotency key.

The example in this guide uses a contact-based workflow whose enrollment trigger is When an event occurs → Form submission. A contact submits a selected HubSpot form, the workflow enrolls that contact, and the custom code action sends a Volanea email to the contact’s email property. HubSpot documents form submission as an event-based workflow enrollment trigger, and its workflow tooling supports custom code actions for Data Hub Professional and Enterprise accounts. (knowledge.hubspot.com)

What this integration does—and does not do

This setup connects a HubSpot workflow to Volanea’s POST /v1/send endpoint. It is appropriate when HubSpot is the source of a business event and Volanea is the service responsible for sending the email.

A common example is a high-intent request form. A visitor submits a consultation form. HubSpot creates or updates the contact and records the form submission. The workflow then sends an immediate acknowledgement, a next-step message, or an internal notification through Volanea.

That workflow can also begin from other HubSpot conditions. For example:

  • A contact property changes, such as onboarding_status becoming ready_for_invite.
  • A deal reaches a defined stage, with the workflow using associated-contact values where appropriate.
  • A ticket is created or its status changes.
  • A contact joins a segment or meets filter criteria.
  • A custom event occurs in HubSpot.

The guide uses form submission because it makes the trigger concrete and easy to test. Do not interpret it as a requirement. The important architectural rule is that the workflow trigger represents one deliberate email-worthy event.

This is not a replacement for HubSpot’s own marketing-email tooling when you need consent management, campaign reporting, or a broad newsletter send managed directly in HubSpot. It is an integration for transactional and system-driven messages where you want the send to originate from Volanea’s email infrastructure and API.

Why use HubSpot custom code instead of only a webhook action

HubSpot’s workflow editor includes a Send a webhook action under Data ops. It supports POST requests to HTTPS endpoints and can authenticate the request using a request signature or an API key. That can work for simple outbound integrations. (knowledge.hubspot.com)

For this specific connection, a custom code action is usually safer and more maintainable. Volanea expects an authenticated JSON request with a verified sender, recipient, subject, and HTML content. The code action gives you a controlled place to:

  1. Read contact data as explicitly selected workflow inputs.
  2. Stop before sending if the recipient address or required business data is missing.
  3. Escape values placed in HTML.
  4. Set Authorization, Content-Type, and Idempotency-Key headers exactly.
  5. Treat a Volanea error response as a workflow failure rather than silently continuing.
  6. Avoid exposing your Volanea secret in a client-side form, HubSpot page script, or public webhook URL.

HubSpot runs custom code actions in a managed serverless environment and supports JavaScript in Node.js; its documented supported Node libraries include Axios. (developers.hubspot.com)

There is also an operational reason to prefer code. A plain webhook action is a transport mechanism. It does not inherently know whether a contact has an email address, whether a form response contains unexpected characters, or whether a retry should be treated as the same logical email. Those decisions are part of delivery logic, not merely HTTP configuration.

Prerequisites before you build the workflow

Set up the email side first. A workflow that successfully invokes the API but uses an unverified sender is still not a ready-to-send production integration.

You need:

  • A Volanea project and a secret API key, beginning with sk_ or sk_test_.
  • A sending domain configured and verified in Volanea.
  • A sender address on that verified domain, such as notifications@example.com.
  • A HubSpot account with access to workflows.
  • Data Hub Professional or Enterprise to use HubSpot custom code actions.
  • Permission to create or edit workflows, plus permission to publish the workflow.
  • A HubSpot form that creates or updates a contact and captures the properties the email needs.

Volanea’s send endpoint is POST https://api.volanea.com/v1/send. It accepts secret-key authentication, supports sending to one address or up to 50 recipients, and supports the Idempotency-Key header for safe retries. (volanea.com)

Before making the integration live, create a dedicated transactional sender identity rather than using an individual employee’s address. notifications@, hello@, support@, or a similarly durable inbox is easier to maintain when team members change.

If the email needs a reply path, decide that deliberately as well. A customer-facing confirmation may need a monitored reply address. An event notification might not. The sender address influences recipient trust, reply handling, and the operational ownership of the message.

For a broader review of endpoint fields, keys, and send behavior, keep the email API reference and setup guides available while implementing the workflow.

Build the HubSpot workflow trigger

Create a contact-based workflow from scratch. In HubSpot, navigate to Automation → Workflows, create a workflow, and select the contact object type. HubSpot’s workflow editor uses enrollment triggers to determine when a record enters the workflow. (knowledge.hubspot.com)

For this implementation, configure the enrollment trigger as follows:

  1. Choose When an event occurs.
  2. Select Form submission.
  3. Select the specific form, for example, Request a consultation.
  4. Add an additional criterion if needed, such as email is known or a product-interest property matching the route that should receive this message.
  5. Decide whether re-enrollment is appropriate.

The concrete event that starts the send is therefore: a contact submits the selected HubSpot form. Once that event occurs after the workflow has been turned on, HubSpot enrolls the contact and runs the next workflow actions. Event-based workflow triggers only enroll records for events occurring after the workflow is active, so publish the workflow before relying on live submissions. (knowledge.hubspot.com)

Decide re-enrollment before you write the email

Re-enrollment is a business rule, not a checkbox to enable by default. A person who sends one support form twice may reasonably receive two acknowledgement emails. A person who updates a contact property twice should not necessarily receive two onboarding messages.

HubSpot normally enrolls an object the first time it meets a workflow’s triggers. Re-enrollment can allow the object to enter again when it meets selected triggers again. (knowledge.hubspot.com)

For a form-confirmation workflow, permitting repeat submissions can be sensible. For an account-activation email, use a more specific state transition or an explicit activation_email_sent_at property so that accidental updates cannot create an unwanted repeat send.

Add a guard branch for missing data

Before the custom code action, add an if/then branch that verifies the contact has an email value. You can also check whether the contact has opted into the relevant process, whether the requested product is present, or whether a required personalization field is known.

Do not rely on a generic greeting as a substitute for basic validation. A missing first name is usually harmless. A missing email address is not. A missing product, order number, or appointment time may produce a message that is confusing enough to become a support issue.

Store the Volanea API key as a HubSpot secret

Add a Custom code workflow action after the branch. In the action configuration, create a secret named VOLANEA_API_KEY and paste the Volanea secret key as its value. HubSpot custom code actions provide a secrets mechanism specifically for sensitive values used during execution. The code receives the secret through the server-side execution context rather than from a public web page. (developers.hubspot.com)

Do not put the Volanea key in any of these places:

  • A HubSpot form hidden field.
  • A personalization token.
  • Front-end JavaScript on a HubSpot-hosted page.
  • A publicly readable file or CMS module.
  • A webhook URL query parameter.
  • Email content, workflow notes, or screenshots shared outside the team.

A Volanea API key is a bearer credential. Anyone who obtains it can potentially submit sends under its permissions. Keeping it in a HubSpot custom-code secret limits exposure to the workflow execution environment and to people authorized to edit that workflow configuration.

Use a test key and a test recipient while building. Move to the live key only after you have validated the mapping, sender domain, and idempotency behavior. If a secret is ever copied into an unsafe location, rotate it rather than assuming deletion from a document or message fully removes exposure.

Map HubSpot contact properties into the Volanea send payload

In the custom code action, add the following input properties from the enrolled contact:

  • email
  • firstname
  • lastname
  • hs_object_id
  • Any custom property that supplies context, such as product_interest

HubSpot passes values selected as code-action inputs in the action’s event.inputFields object. In other words, the relevant shape made available to the action is like this:

{
  "inputFields": {
    "email": "ada@example.com",
    "firstname": "Ada",
    "lastname": "Lovelace",
    "hs_object_id": "123456",
    "product_interest": "Analytics"
  },
  "secrets": {
    "VOLANEA_API_KEY": "sk_..."
  }
}

The exact values change per enrolled contact; the field names are determined by the inputs you configure in the workflow action. This is preferable to assuming every CRM property is automatically available to the code.

The outbound Volanea payload is distinct from that HubSpot input object. Map the contact’s email to Volanea’s recipient, build the message subject and HTML from the business event, and use a verified sender in from.

Here is a complete JavaScript custom code action. It uses Axios, validates the required address, escapes the two values used in HTML, sends to Volanea, and returns the Volanea response fields as workflow outputs.

const axios = require('axios');

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

exports.main = async (event, callback) => {
  const {
    email,
    firstname,
    hs_object_id: contactId,
    product_interest: productInterest
  } = event.inputFields;

  if (!email) {
    throw new Error('Cannot send Volanea email: HubSpot contact email is empty.');
  }

  const safeFirstName = escapeHtml(firstname || 'there');
  const safeProductInterest = escapeHtml(productInterest || 'your request');

  // Stable for this contact + workflow event purpose. Do not use a random value
  // if HubSpot retries the same execution after a timeout.
  const idempotencyKey = `hubspot-form-confirmation:${contactId}`;

  const volaneaPayload = {
    from: 'Acme Team <notifications@example.com>',
    to: [email],
    subject: `We received your ${productInterest || 'request'}`,
    html: `
      <p>Hi ${safeFirstName},</p>
      <p>Thanks for your interest in ${safeProductInterest}. We received your form submission and will follow up shortly.</p>
      <p>— The Acme Team</p>
    `
  };

  try {
    const response = await axios.post(
      'https://api.volanea.com/v1/send',
      volaneaPayload,
      {
        headers: {
          Authorization: `Bearer ${event.secrets.VOLANEA_API_KEY}`,
          'Content-Type': 'application/json',
          'Idempotency-Key': idempotencyKey
        },
        timeout: 8000
      }
    );

    callback({
      outputFields: {
        volanea_status: response.data.status || 'accepted',
        volanea_message_id: response.data.id || response.data.messageId || ''
      }
    });
  } catch (error) {
    const status = error.response?.status;
    const details = error.response?.data
      ? JSON.stringify(error.response.data)
      : error.message;

    throw new Error(
      `Volanea send failed${status ? ` with HTTP ${status}` : ''}: ${details}`
    );
  }
};

The request maps email from HubSpot to to, uses a fixed verified sender for from, and generates subject and html from HubSpot fields. Volanea documents authenticated JSON sends to POST /v1/send, including support for the Authorization header and an Idempotency-Key header. (volanea.com)

Use a better idempotency key for repeatable events

The example key is intentionally simple for a one-time form confirmation: hubspot-form-confirmation:<contactId>. It prevents a retry from creating a second copy for the same contact and email purpose.

But it also means that a later, genuinely new form submission from the same contact would reuse the same logical key. If you intend each separate form submission to create a new email, add a stable per-submission identifier to the key. The right identifier depends on what HubSpot makes available for your trigger and data model.

For example, if a workflow property stores a request ID, use:

hubspot-request-confirmation:<request_id>

If the workflow is triggered by a deal-stage transition, use a stable deal ID plus the target stage and transition event identifier. The principle is simple: the same business event must always produce the same key; different legitimate events must produce different keys.

Volanea’s idempotency support exists specifically to make retryable side effects, including transactional email, safer. (volanea.com)

Make the message production-ready

The API call is only the transport. The message still needs the same care as any other transactional email.

Keep transactional content tied to the trigger

An acknowledgement email should confirm the action the recipient just took. It should not become an unannounced marketing newsletter. Good confirmation content usually includes:

  • A clear statement that the form or request was received.
  • The expected next step and timing, if you can truthfully provide one.
  • A copy of important submitted values when that helps the recipient verify the request.
  • A support route if the request was made in error.
  • A sender identity that matches the brand and domain the recipient expects.

A message sent after a request-for-demo form could say that the request was received and explain when a team member will follow up. It should not imply that a meeting has been booked unless an actual scheduling event occurred.

Do not insert raw CRM values into HTML

The sample code escapes the first name and product interest because CRM fields can contain punctuation, markup-like characters, or data entered by external visitors. This is not only a security concern. Unescaped values can break email layout, invalidate links, or turn an ordinary customer name into malformed HTML.

Use plain-text output or HTML escaping for every dynamic field. Avoid putting unvalidated values into HTML attributes, CSS, URLs, or JavaScript. If a field needs to become part of a link, validate it against an allowed URL pattern rather than merely escaping it.

Consider templates for messages that evolve often

For a single small email, generating HTML in the custom code action is easy to understand. For a growing set of branded messages, reusable Volanea templates are often a better operational boundary. They let a team update presentation separately from the HubSpot workflow code while still sending through the same API.

That choice should be driven by ownership. If developers own copy and layout changes, code may be enough. If lifecycle marketers or operations teams need to revise content frequently, a template-based approach reduces deployment-style coordination.

Test the full HubSpot-to-Volanea path

Test the live path in layers rather than submitting a production form and hoping the inbox result explains everything.

First, confirm the Volanea sender domain and sender address are ready. Then create a test contact using an inbox you control. Submit the chosen form as that contact, or use the appropriate workflow test process where available.

Use this checklist:

  1. Confirm that the form submission creates or updates the expected contact.
  2. Confirm the contact meets the workflow enrollment trigger.
  3. Confirm the custom code action receives populated email, firstname, and any custom inputs.
  4. Confirm the sender is a verified Volanea sender.
  5. Confirm the Volanea request returns success rather than an authentication or validation error.
  6. Confirm the recipient receives the message and the dynamic values render correctly.
  7. Submit again or simulate a retry according to your test design, then confirm the idempotency key produces the intended result.

HubSpot’s enrollment troubleshooting tools can show why a record did or did not enter a workflow and can display the values present when enrollment occurred. That is particularly useful when a form submission exists but an expected property was empty at the trigger moment. (knowledge.hubspot.com)

Do not test using a real customer’s email address. Test contacts should be controlled accounts, and the subject should make the test unmistakable, such as [Test] HubSpot acknowledgement.

When this breaks

This integration has two hops: HubSpot executes workflow code, then the code calls Volanea. Troubleshoot the hop that actually failed instead of treating every missing email as an inbox-placement problem.

HubSpot retries create duplicate sends

A retry can happen after a timeout or an execution failure where HubSpot cannot safely know whether the previous request reached Volanea. Without idempotency, the second request can result in a second email.

The defense is the Idempotency-Key header. Keep it stable across retries for one logical email. Do not generate Date.now() or a random UUID each time the action runs, because that tells Volanea every retry is a new send.

Also examine your workflow re-enrollment settings. HubSpot distinguishes execution retries from a contact being newly enrolled again. Idempotency can protect the former. It cannot decide whether a newly submitted form, a new deal-stage transition, or a manually re-enrolled contact represents a legitimate new email—that remains your workflow design decision.

The webhook or API call times out

HubSpot notes that slow or timed-out webhook actions can delay workflow action execution. The same distributed-systems concern applies to custom code making outbound HTTP calls: a timeout means the caller may not know whether Volanea received the request. (knowledge.hubspot.com)

Set a finite HTTP timeout, as the example does with 8 seconds. Keep the action narrow: build one payload, send one request, return. Do not make multiple unrelated API calls in the same action if a single email is time-sensitive.

If the timeout occurs after Volanea accepted the request but before HubSpot received the response, retry with the same idempotency key. If it occurs before Volanea receives anything, the retry still works. That uncertainty is exactly why a stable idempotency key matters.

Payload fields are missing or blank

A form submission event may occur before every desired enrichment field has been populated. A field may also exist for some contacts but not others, especially if multiple forms or imports feed the same workflow.

Fix this at the workflow level and in code:

  • Add branches that require essential values before sending.
  • Pass only the properties the code actually needs as custom-code inputs.
  • Use safe fallbacks for nonessential personalization, such as there when first name is blank.
  • Delay the send only when there is a known process that fills the missing data shortly afterward.
  • Record the error in workflow logs or a CRM property if operations staff need follow-up visibility.

Plan availability matters too. HubSpot’s current documentation lists custom code actions for Data Hub Professional and Enterprise. If your account does not include that capability, do not pretend the JavaScript action can be added. Use HubSpot’s native Send a webhook action if its available authentication and payload controls meet your requirements, or route the trigger through middleware such as Make or Zapier, where the Volanea key is stored as a connection secret rather than in public configuration. (developers.hubspot.com)

Volanea returns 401, 403, or a validation error

A 401 commonly indicates a missing, malformed, revoked, or wrong-environment API key. Confirm that the HubSpot secret contains the full key and that the action uses Authorization: Bearer <key>.

A sender-related validation error usually means the from address is not available under a verified Volanea sending domain. Check the exact sender string in the code, not just the domain configuration in general.

A recipient validation error usually points to blank, malformed, or incorrectly mapped HubSpot contact data. Inspect the specific contact at enrollment time and verify the action’s configured input properties.

The email is accepted but does not arrive

An accepted API response is not the same as an inbox placement guarantee. Check Volanea message events, the recipient mailbox’s spam or quarantine folders, sender-domain authentication, suppression status, and the actual recipient address used.

Avoid retrying blindly when delivery visibility is incomplete. A second send can create an annoying duplicate while the first message is merely delayed. Start with the Volanea send result and delivery events, then decide whether a resend is appropriate.

Alternatives for teams without custom code access

Not every HubSpot subscription includes custom code actions. The integration path should match your account capabilities and the complexity of your send.

Native HubSpot webhook action

If your workflow includes Send a webhook, you can configure a POST request to an HTTPS endpoint and use its API-key authentication option. HubSpot documents this action for contact-based workflows under Data ops. (knowledge.hubspot.com)

For a direct Volanea request, verify in your own account that the webhook action can set the required authorization header format, JSON body, and dynamic fields. If it cannot express Authorization: Bearer sk_... or cannot maintain a dependable idempotency key, do not force the direct connection. Put a small middleware endpoint in between.

Middleware endpoint

A serverless function, worker, or small API route can receive HubSpot’s webhook and call Volanea. This is a good option when you need signature verification, database-backed deduplication, richer templates, auditing, or several downstream actions.

The middleware should:

  • Verify that the inbound request truly came from HubSpot where applicable.
  • Respond quickly to HubSpot.
  • Persist enough information to identify the logical send.
  • Call Volanea with its secret kept in server-side environment configuration.
  • Use a stable idempotency key.
  • Log the Volanea response and any delivery correlation identifier.

This architecture adds a service to own, but it separates CRM automation from email-transport logic and is often the best route for high-volume or business-critical sends.

Zapier or Make

Zapier and Make can be practical middleware for low-code teams. The HubSpot trigger starts a scenario or Zap, the automation maps fields, and an HTTP request module calls Volanea. Store the Volanea key in the platform’s encrypted connection or credential configuration where supported—not in a field that is inserted into task data or exposed in a shared template.

The trade-off is less direct control over retries, payload normalization, and idempotency. If the email is compliance-sensitive, financially consequential, or expected to scale, use code or a middleware service you can test and observe deeply.

Operational practices after launch

Treat the workflow as production software, even though much of it is configured in an interface.

Assign ownership for three areas: the HubSpot workflow trigger, the email content and sender identity, and the Volanea credentials and deliverability settings. Those responsibilities can sit with different people, but they should not be ambiguous.

Review workflow enrollments periodically. Look for contacts entering unexpectedly, action failures, and re-enrollments that correlate with ordinary CRM edits. HubSpot lets you configure re-enrollment behavior and troubleshoot enrollment records, so use those tools before changing production code in response to a single example. (knowledge.hubspot.com)

Also review your message volume and API use as this workflow expands. A confirmation send that begins as a handful of form submissions per day may later be triggered by imports, integrations, or backfilled data. Understanding your transactional email pricing before a backfill or workflow-wide re-enrollment helps prevent unexpected volume from becoming an operational surprise.

Finally, keep a simple change log. Record the workflow name, enrollment trigger, sender address, Volanea project, secret owner, template or code version, and intended idempotency-key format. That documentation makes it much easier to answer a future question such as: why did this person receive this email twice?

FAQ

Can I install Volanea from the HubSpot Marketplace?

No. Volanea does not ship a native HubSpot Marketplace app or plugin. Connect it through HubSpot workflows using custom code, a native webhook where its controls are sufficient, or middleware such as a serverless endpoint, Make, or Zapier.

What HubSpot event starts the email in this guide?

The concrete trigger is a contact’s Form submission event. A contact-based workflow enrolls the contact when they submit the selected HubSpot form, then its custom code action calls Volanea.

Where should I store the Volanea API key in HubSpot?

Store it as a secret in the HubSpot custom code action, referenced in code as event.secrets.VOLANEA_API_KEY. Never put it in form fields, browser JavaScript, public configuration, or a URL.

How do I stop duplicate sends after a timeout or retry?

Send a stable Idempotency-Key with the Volanea request. The key must identify the logical email event, remain the same for retries of that event, and differ for genuinely new events.

Can I use this for marketing newsletters?

Technically, an API can send email, but this integration is best for transactional or event-driven messages. For newsletters and marketing programs, use the system that gives your team the consent, segmentation, campaign, and reporting controls required for that use case.