Send transactional email from Salesforce without pretending there is a native app: have Salesforce trigger an authenticated HTTP request to Volanea’s REST API. This guide shows the honest integration pattern, including the Salesforce data you assemble, the Volanea send request, secure credential handling, and production safeguards.

The important distinction: Salesforce email settings are not a webhook integration

The phrase “Send Email from Salesforce” can refer to Salesforce’s outbound-email configuration, including sending through Salesforce, Gmail, Microsoft 365, or an email relay. Those settings determine how Salesforce-originated mail is delivered. They do not create a generic outbound webhook that forwards every email event to another provider.

That distinction matters here. Volanea does not currently provide a native “Send Email from Salesforce” package, installed app, or one-click connector. There is also no standard webhook payload emitted by Salesforce’s built-in Send Email Flow action that Volanea can receive. A message sent by that action is sent by Salesforce; it is not transformed into an API request to an external email service.

The practical pattern is different and more useful:

  1. A Salesforce record changes, a screen flow runs, or a scheduled condition becomes true.
  2. A Salesforce Flow or Apex action builds the data needed for the message.
  3. Salesforce makes an HTTPS POST request to Volanea.
  4. Volanea accepts the transactional message, applies suppression and delivery controls, and sends it.
  5. Your Salesforce automation records the result or sends failures to an operational queue.

This approach puts each system in the role it is best suited for. Salesforce owns CRM records, automation conditions, permissions, and business context. Volanea owns the outbound message request, sender identity, delivery pipeline, suppression handling, and email-event infrastructure.

Choose the right Salesforce trigger for the email

Before configuring an HTTP callout, decide what business event actually deserves a transactional message. “A Salesforce record changed” is rarely specific enough. A broad trigger can produce duplicate confirmation emails, send on irrelevant edits, or notify the wrong recipient when a record is updated by an import or integration.

A record-triggered flow is the usual starting point for transactional messages tied to CRM activity. Examples include a Case being created, an Opportunity reaching a signed stage, a Contact being invited to a customer portal, or a custom Invoice__c record being marked paid.

Good transactional-email triggers

Use a narrow entry condition that corresponds to a real customer event:

  • A Case changes from New to Resolved.
  • An invoice record changes from Open to Paid.
  • A customer’s onboarding status changes from Pending to Invited.
  • A renewal request is approved.
  • A support appointment is confirmed or rescheduled.

For a record-triggered flow, prefer conditions that evaluate whether the record was updated to meet criteria rather than merely whether it currently meets them. If an invoice is already marked paid and a staff member later edits its internal notes, you do not want another receipt.

When a screen flow is better

Use a screen flow when a Salesforce user deliberately initiates the message and needs to supply or review values. For example, a support agent may choose a recipient, enter a short explanation, and press a button labeled “Send resolution update.” In that case, the screen flow can collect structured inputs, invoke an Apex action, and show a success or failure message to the agent.

When scheduled automation is better

A scheduled path or scheduled-triggered flow works for time-based notifications: a renewal reminder seven days before expiration, a request for missing documents after two days, or a “we still need information” notice after a Case has been waiting too long. Store enough state on the record to make the scheduled run idempotent, such as Reminder_Sent_At__c or Reminder_Sent__c.

The central rule is simple: trigger on the business event, not on the existence of a record.

What the Salesforce-to-Volanea request actually looks like

Because Salesforce does not emit a predefined “Send Email from Salesforce” webhook payload, you create the JSON request yourself. This is a feature, not a compromise: you control exactly which fields leave Salesforce, how names are formatted, and what content is sent.

For a completed invoice, imagine Salesforce has these record values:

  • Invoice__c.Id: a01xx0000037ABC
  • Invoice__c.Invoice_Number__c: INV-10482
  • Invoice__c.Amount__c: 249.00
  • Related Contact first name: Maya
  • Related Contact email: maya@example.com

The payload submitted to Volanea should be a message request, not a dump of the Salesforce record. Keep it purpose-built:

{
  "from": {
    "email": "billing@example.com",
    "name": "Example Billing"
  },
  "to": [
    {
      "email": "maya@example.com",
      "name": "Maya"
    }
  ],
  "subject": "Payment received for invoice INV-10482",
  "html": "<p>Hi Maya,</p><p>We received your payment of $249.00 for invoice <strong>INV-10482</strong>.</p><p>Thank you,<br>Example Billing</p>",
  "text": "Hi Maya,\n\nWe received your payment of $249.00 for invoice INV-10482.\n\nThank you,\nExample Billing"
}

Volanea’s single-message endpoint is POST https://api.volanea.com/v1/send. It accepts a message for one recipient or up to 50 recipients, and it supports an Idempotency-Key header for retry-safe sends. Use the single-message endpoint for an event such as a receipt, invitation, account alert, or case update; do not turn a large marketing audience into a loop of transactional API calls.

The request needs a verified sender address that belongs to a domain you control. Do not use the Salesforce user’s email address as the from.email value unless that address is intentionally configured as a verified Volanea sender. A safer model is a stable role address such as billing@, support@, or notifications@ on your authenticated sending domain.

Set up Volanea before connecting Salesforce

Complete the email-infrastructure work before building the Salesforce automation. An API call can be technically valid while email delivery still suffers because the sending domain is unverified or authentication is incomplete.

First, add the domain or subdomain you plan to use for transactional mail in Volanea. A dedicated subdomain such as notify.example.com or mail.example.com can make operational ownership clearer, although the appropriate choice depends on your existing domain and deliverability architecture. Follow the DNS values shown in your Volanea project exactly; do not copy generic SPF or DKIM values from another provider.

Next, verify the sender identity you will use in the request. The display name and email address should be recognizable to recipients and consistent with the purpose of the message. A payment receipt from Example Billing <billing@example.com> is clearer than one from an individual sales representative whose mailbox may not handle replies.

Then create a secret API key in Volanea. Treat it as a service credential, not as a value to paste into a Flow formula, Apex class, Git repository, or browser-side application. Salesforce should store and send the secret through its credential-management tools.

Finally, send a controlled test to an internal mailbox. Check the recipient address, From name, Reply-To behavior if you configure one, subject, HTML rendering, plain-text fallback, and message headers. If your Flow gets the email right but the content includes malformed merge values, fix the mapping before activating the workflow for customers.

For the endpoint, request fields, and current authentication guidance, use the Volanea API reference and setup guides rather than relying on copied snippets that may not reflect your project configuration.

Option 1: Use Salesforce Flow with an HTTP Callout

Salesforce Flow can call an HTTP-based API through an HTTP Callout action. This is a good low-code option when the message is straightforward, the request shape is stable, and the API key can be applied as a static credential header.

The exact Salesforce configuration varies by org permissions and release, but the durable architecture is the same: create credentials first, then create the callout action, then use that action in the flow.

Create a named credential and external credential

In Salesforce Setup, create an external credential and a named credential for Volanea. Salesforce uses these objects to keep authentication out of the flow definition and out of Apex source code.

Use these values as the logical configuration:

  • Endpoint base URL: https://api.volanea.com
  • Request path: /v1/send
  • HTTP method: POST
  • Content type: application/json
  • Authentication secret: the Volanea secret API key

Configure the authorization header according to the Volanea API reference for your key type. The point is not merely concealment: using credentials also lets you rotate keys without editing every flow that calls the service. Grant access to the credential only to the integration principal or users that need to run the flow.

Avoid putting the key in a Flow text variable. Flow definitions can be inspected and moved between environments; a credential should remain a credential.

Create the HTTP Callout action

Open the flow where the callout belongs, add an Action element, and choose the option to create an HTTP callout. Salesforce uses a sample JSON request body to define the action’s input fields. Paste a representative Volanea request that includes the fields your workflow will populate.

For the invoice example, use a sample like this during configuration:

{
  "from": {
    "email": "billing@example.com",
    "name": "Example Billing"
  },
  "to": [
    {
      "email": "recipient@example.com",
      "name": "Recipient Name"
    }
  ],
  "subject": "Payment received for invoice INV-00000",
  "html": "<p>Example message</p>",
  "text": "Example message"
}

Salesforce will use that shape to expose fields for the action. Map the recipient email, recipient name, subject, HTML, and text values from record fields, formula resources, or prior flow elements.

A Flow HTTP Callout is especially appropriate when the sender is fixed. For example, every invoice receipt can come from the same verified billing address. It becomes less suitable when you need dynamic request headers, complex conditional JSON, attachments, arrays with variable lengths, or custom retry behavior. Use Apex for those cases.

Build HTML carefully in Flow

A formula resource can produce simple HTML, but Flow is not a template engine. Keep the markup small, use a known-safe layout, and make a plain-text version as well. Never insert user-entered rich text directly into HTML without considering how it should be escaped and rendered.

For example, a simple HTML formula may concatenate a greeting, a known invoice number, and a currency value. It should not concatenate arbitrary customer notes that could contain markup, copied signatures, or content that makes the email unreadable.

Option 2: Use an invocable Apex action for production flexibility

Apex is usually the stronger long-term option when email logic is important enough to deserve tests, version control, deterministic JSON serialization, dynamic idempotency keys, and explicit error handling. The flow remains easy for admins to understand: it invokes one custom action. The action owns the API request.

The example below is designed for a record-triggered flow that passes a recipient, name, invoice number, amount, and Salesforce record ID. Create a Salesforce named credential with API name Volanea_API that points to https://api.volanea.com. Configure the required Volanea API authorization there rather than embedding a key in Apex.

public with sharing class VolaneaTransactionalEmailAction {
    public class RequestInput {
        @InvocableVariable(required=true)
        public String recipientEmail;

        @InvocableVariable
        public String recipientName;

        @InvocableVariable(required=true)
        public String invoiceNumber;

        @InvocableVariable(required=true)
        public Decimal amount;

        @InvocableVariable(required=true)
        public Id sourceRecordId;
    }

    public class RequestResult {
        @InvocableVariable
        public Boolean accepted;

        @InvocableVariable
        public Integer statusCode;

        @InvocableVariable
        public String responseBody;
    }

    @InvocableMethod(
        label='Send Volanea Payment Receipt'
        description='Sends a payment receipt through Volanea.'
        callout=true
    )
    public static List<RequestResult> sendReceipts(List<RequestInput> inputs) {
        List<RequestResult> results = new List<RequestResult>();
        Http http = new Http();

        for (RequestInput input : inputs) {
            String safeName = String.isBlank(input.recipientName)
                ? 'Customer'
                : input.recipientName;
            String amountText = String.valueOf(input.amount.setScale(2));

            Map<String, Object> payload = new Map<String, Object>{
                'from' => new Map<String, Object>{
                    'email' => 'billing@example.com',
                    'name' => 'Example Billing'
                },
                'to' => new List<Object>{
                    new Map<String, Object>{
                        'email' => input.recipientEmail,
                        'name' => safeName
                    }
                },
                'subject' => 'Payment received for invoice ' + input.invoiceNumber,
                'html' => '<p>Hi ' + safeName + ',</p>' +
                    '<p>We received your payment of $' + amountText +
                    ' for invoice <strong>' + input.invoiceNumber +
                    '</strong>.</p><p>Thank you,<br>Example Billing</p>',
                'text' => 'Hi ' + safeName + ',\n\n' +
                    'We received your payment of $' + amountText +
                    ' for invoice ' + input.invoiceNumber +
                    '.\n\nThank you,\nExample Billing'
            };

            HttpRequest request = new HttpRequest();
            request.setEndpoint('callout:Volanea_API/v1/send');
            request.setMethod('POST');
            request.setHeader('Content-Type', 'application/json');
            request.setHeader('Idempotency-Key',
                'salesforce-invoice-receipt-' + String.valueOf(input.sourceRecordId));
            request.setBody(JSON.serialize(payload));
            request.setTimeout(10000);

            HttpResponse response = http.send(request);

            RequestResult result = new RequestResult();
            result.statusCode = response.getStatusCode();
            result.responseBody = response.getBody();
            result.accepted = response.getStatusCode() >= 200 &&
                response.getStatusCode() < 300;
            results.add(result);
        }

        return results;
    }
}

This example deliberately generates the idempotency key from the Salesforce source-record ID. That works only when the business rule is “one receipt for this record.” If the same invoice can legitimately generate multiple distinct receipts, include an immutable event ID or payment transaction ID instead. An idempotency key must identify one logical send, not merely one recipient.

In production, also add an Apex test using HttpCalloutMock. Test the successful response, a 4xx response caused by invalid input, a 5xx response, and duplicate invocation with the same logical event. Salesforce requires test coverage for deployment, but the more important reason to test is operational confidence when money, account access, or support commitments are involved.

Map Salesforce data into email content without leaking CRM data

The data mapping layer is where a simple integration becomes either reliable or risky. Transactional content should contain what the recipient needs to understand the event and take the next action. It should not replicate an entire Salesforce record.

For a receipt, that might be first name, invoice number, payment amount, payment date, and a link to a customer portal. For a support update, it might be the case number, a short status, the next step, and a reply route. For an account invitation, it might be first name, expiration time, and an action URL.

Use a field allowlist

Create an explicit list of fields that may be sent. This limits accidental exposure when Salesforce admins later add sensitive fields to a record or someone expands a formula without considering email privacy.

A useful allowlist for an invoice receipt could be:

  • Contact first name
  • Invoice number
  • Formatted amount
  • Payment date
  • Customer-facing account name
  • A customer portal URL

Avoid including internal account notes, payment tokens, full support transcripts, raw integration errors, internal owner names, or Salesforce record links that recipients cannot access. If an internal identifier is necessary for support, consider a short public-facing reference rather than exposing record IDs.

Validate recipient addresses before triggering important mail

Use the email address on the Contact or related record only after confirming your data model’s consent and lifecycle rules. A Contact record can have a stale address, a role inbox, or an address that belongs to a former employee.

For high-value onboarding, account-access, or billing workflows, validate addresses at collection time and before large operational changes. You can use Volanea’s email address verification tool as a practical preflight check, but it does not replace your responsibility to respect consent, suppressions, and customer preferences.

Keep merge values safe and legible

Use null handling. A greeting should become “Hi there” when first name is absent, not “Hi null.” Format currency and dates in the recipient’s expected locale. If you send HTML, always include a plain-text counterpart so the message remains usable in clients that block or simplify HTML.

Also be careful with dynamic URLs. Construct them from trusted components, use an HTTPS destination, and avoid placing sensitive session credentials directly in a URL. If an email link grants access, make it short-lived, single-purpose, and auditable.

Prevent duplicate sends with idempotency and record state

Salesforce automation can run more than once. Flows can be retried, records can be updated by multiple automations, integrations can replay changes, and an administrator may reactivate or edit a workflow. If your email event has side effects in the real world, duplicate prevention is part of the integration design.

Volanea supports the Idempotency-Key request header for safe retries. Reuse the same key when retrying the same logical email request. Do not reuse it for an unrelated message simply because it goes to the same person.

A robust design uses two layers of protection:

  1. Salesforce event gating: Trigger only on a relevant state transition and save a field such as Receipt_Sent_At__c, Invite_Sent__c, or Last_Notification_Event_Id__c after the send is accepted.
  2. Volanea idempotency: Send a stable idempotency key derived from the business event so a transport-level retry does not create another email.

For example, use payment-<Payment_Transaction_ID__c>-receipt-v1 for a payment receipt. The v1 suffix gives you an intentional way to create a revised event design later without colliding with historical requests.

Do not mark the Salesforce record as “sent” before you have a successful response from the API. If you set the flag first and the callout fails, the customer may never receive the email and your system will incorrectly claim that they did. Conversely, do not automatically retry every 4xx response. A malformed recipient address or invalid sender needs correction, not repeated traffic.

Handle failures, retries, and operational visibility

A successful HTTP response means Volanea accepted the request; it is not the same thing as a recipient opening or reading the message. Treat each layer separately: request acceptance, provider processing, delivery, bounce or complaint outcome, and business completion.

Classify errors before retrying

Use a simple retry policy:

  • 2xx: Record acceptance and continue the Salesforce workflow.
  • 4xx: Treat as a permanent or configuration-related failure until investigated. Check recipient data, sender configuration, request fields, and authorization.
  • 5xx or network timeout: Treat as potentially temporary. Retry using the same idempotency key, with a controlled backoff strategy.

Do not run a synchronous loop of repeated callouts inside a flow. That can hit Salesforce callout and transaction limits while producing unpredictable delays. Instead, write a retry record to a custom object or publish a platform event that a controlled asynchronous process handles.

Create a delivery audit object

For meaningful workflows, create a custom object such as Email_Send_Log__c or Notification_Attempt__c. Store only the operational details you need:

  • Salesforce source record ID
  • Business event ID
  • Recipient address or a protected representation of it
  • Template or message type
  • Idempotency key
  • Volanea response status
  • Attempt count
  • Accepted timestamp
  • Failure category and safe error summary

Do not store the complete rendered message body by default if it contains personal, contractual, health, payment, or support information. Logging should aid troubleshooting without becoming another uncontrolled copy of sensitive data.

Use a clear ownership model

The Salesforce admin should own trigger rules and CRM-field mapping. The engineering or operations team should own named credentials, key rotation, sender-domain configuration, retry jobs, and incident response. The customer-support team should know where to find the Salesforce record and delivery-attempt history when a customer says a message did not arrive.

That division prevents a common failure mode: one team assumes another team is monitoring delivery, while nobody owns the entire path.

Deliverability implications of sending from Salesforce through an API

Calling an email API from Salesforce does not eliminate the need for good sending practices. It makes the sending system explicit, which is usually helpful, but recipients and mailbox providers still evaluate the message based on sender identity, authentication, content, engagement, complaint rates, and sending behavior.

Use a From domain that your organization controls and has authenticated in Volanea. Keep the sender aligned with the business purpose: billing messages from billing, support updates from support, security notices from security or notifications. A recognizable sender name improves trust and reduces replies to the wrong team.

Keep transactional and promotional traffic conceptually separate. A paid-invoice receipt, password reset, or case update should not be padded with unrelated promotional copy. Aside from customer experience, mixing marketing into essential operational messages can create consent and unsubscribe complications.

Review the actual recipient journey. If your receipt says “reply to this email for help,” make sure replies go somewhere monitored. If the message contains a portal link, test it when signed out and on a mobile device. If the email announces a status change, make sure the Salesforce state and the customer-facing system are already consistent before the message is sent.

Volanea’s send pipeline applies suppression checks before dispatch. That is valuable protection, but it is not a reason to ignore Salesforce data quality. If a critical recipient is suppressed because of a prior hard bounce or complaint, route that condition to a business process—such as asking the account owner to obtain a corrected address—rather than repeatedly attempting to send.

A production checklist for the Salesforce integration

Before activating the flow for real customers, use this checklist:

  1. Trigger precision: The flow runs only for a clearly defined business event or state transition.
  2. Verified sender: The from.email is configured and verified in Volanea, not copied from an arbitrary Salesforce user record.
  3. Credential security: The API key lives in Salesforce credential management, never in Flow variables, Apex strings, browser code, or exported configuration.
  4. Recipient rules: The automation chooses the correct Contact or related email field and handles blank, invalid, or suppressed addresses intentionally.
  5. Content quality: HTML and plain-text versions are present, merge fields have null fallbacks, and the email has been tested in a real inbox.
  6. Duplicate protection: Salesforce gates the business event and the Volanea request has a stable Idempotency-Key.
  7. Failure path: Permanent failures are logged for review; temporary failures have an asynchronous retry path.
  8. Observability: Support and operations can trace a customer-facing email from the Salesforce record to the API attempt.
  9. Privacy review: The payload contains only the CRM fields necessary for the message.
  10. Environment separation: Sandbox or test data uses a test key, safe recipient list, or controlled routing so a deployment cannot send production-like messages to real customers.

The final item deserves special attention. Salesforce sandboxes often contain copied CRM data. A new flow with an active callout can accidentally send messages to real contact addresses if your test strategy is not deliberate. Use a test-specific sender, a gated recipient allowlist, or a mode that redirects all non-production sends to an internal mailbox.

Conclusion

The reliable way to send a transactional email from Salesforce with Volanea is not an app-install flow and not a non-existent Salesforce email webhook. It is an explicit integration: Salesforce Flow or Apex detects a business event, maps approved CRM data into a message request, and posts that request to Volanea’s POST /v1/send endpoint.

Start with a narrow record-triggered flow and a fixed sender. Use a Salesforce named credential for the API secret, build a minimal payload with HTML and plain text, and add an idempotency key tied to the business event. As the workflow becomes more important, move complex construction, retries, and logging into an invocable Apex action.

That architecture is straightforward to test, clear to operate, and honest about where the integration boundary lives: Salesforce initiates the API call; Volanea sends the email.

FAQ

Is there a native Volanea app for Send Email from Salesforce?

No. Volanea does not currently offer a native “Send Email from Salesforce” app or installed integration. Use Salesforce Flow HTTP Callouts or an Apex HTTP callout to invoke Volanea’s REST API.

Does Salesforce Send Email create a webhook payload I can forward to Volanea?

No standard payload is emitted by Salesforce’s built-in Send Email action for this purpose. Build the JSON request yourself from Salesforce record fields, then send it directly to Volanea through Flow or Apex.

Should I use Flow or Apex to send transactional email from Salesforce?

Use Flow for stable, simple requests with fixed headers and straightforward field mapping. Use an invocable Apex action when you need dynamic idempotency keys, complex content, conditional payloads, custom error handling, tests, attachments, or asynchronous retries.

How do I stop Salesforce from sending the same email twice?

Use both a narrow state-transition trigger in Salesforce and Volanea’s Idempotency-Key header. The Salesforce rule prevents unnecessary re-entry; the idempotency key makes retries for the same logical event safe.

Can I use a Salesforce user’s email address as the From address?

Only if that address and domain are intentionally verified for sending in Volanea. In most transactional workflows, use a stable, authenticated role address such as billing@yourdomain.com or support@yourdomain.com.