If you need to send email from Beefree, the reliable approach is to treat Beefree as the email creation layer and Volanea as the delivery layer. Beefree SDK generates the design JSON and production-ready HTML in your application; your server then validates the request, creates the Volanea message, and sends it without exposing an email API key in the browser.
There is an important implementation detail to get right at the beginning: Beefree SDK is an embeddable email builder, not a standalone outbound-email automation platform. It does not provide a native Volanea app, marketplace installation, or a standard-plan outbound webhook that directly posts a campaign to your email provider. Instead, Beefree calls callback functions configured by the host application, such as onSave(jsonFile, htmlFile) and onSend(htmlFile).
That architecture is useful rather than limiting. It gives your application control over who can send, which audience is eligible, what sender identity is used, whether an approval is required, and how duplicate sends are prevented. It also means the correct integration is a short server-side route between Beefree SDK and Volanea—not a browser-side API call and not a fictional “install integration” flow.
What this Beefree-to-Volanea integration does
The completed flow has four distinct responsibilities:
- Beefree SDK lets a user design an email and produces the Beefree design JSON plus rendered HTML.
- Your application frontend receives Beefree’s callback and posts the email draft to your own authenticated backend endpoint.
- Your application backend checks authorization, validates audience and sender details, records an idempotency key, and calls Volanea.
- Volanea accepts the message through
POST /v1/send, applies its sending pipeline, and handles delivery infrastructure.
This separation matters. A visual email editor should not have unrestricted access to a delivery credential. A delivery API should not infer that every person who can edit an email is allowed to mail every contact. Your backend is the policy boundary between those systems.
At a high level, the request path looks like this:
Beefree editor
→ Beefree onSend(htmlFile) callback in your app
→ POST /api/email/send-from-beefree on your server
→ POST https://api.volanea.com/v1/send
→ Volanea sending pipeline
The concrete Beefree event used in this guide is the onSend(htmlFile) callback. Beefree SDK also exposes onSave(jsonFile, htmlFile) when a user saves. In a production product, it is usually best to use onSave to persist a draft and onSend only after your own application has collected or selected the recipient, subject, and sender details.
Understand what Beefree actually sends
Beefree SDK’s callbacks are not outbound HTTP webhooks. The SDK runs inside your application, and it invokes JavaScript functions that you provide in the beeConfig configuration object.
For the standard save callback, the real callback signature is:
onSave: function (jsonFile, htmlFile, ampHtml, templateVersion, language) {
// Your application receives the generated design and HTML here.
}
For the send callback, the relevant value is the generated HTML:
onSend: function (htmlFile) {
// Your application receives the rendered email HTML here.
}
That distinction avoids a common mistake: there is no Beefree-generated webhook JSON such as event: campaign.created that you configure to call Volanea directly. The payload is local callback data delivered to the JavaScript application that embedded Beefree.
The callback payload shape
The practical payload from Beefree is made up of callback arguments, not a pre-packaged outbound event envelope. For a save, your code receives values shaped like this:
{
jsonFile: "{...Beefree design JSON as a string...}",
htmlFile: "<!doctype html><html>...rendered email HTML...</html>",
ampHtml: "<!-- optional AMP email HTML, if produced -->",
templateVersion: "...template version value...",
language: "en-US"
}
The jsonFile is valuable for reopening and editing the design later. The htmlFile is the value you normally deliver through Volanea. Do not attempt to parse Beefree design JSON into an email at send time when Beefree has already generated the email HTML for you.
Your frontend should wrap the pieces that Beefree provides together with data that belongs to your product: recipient address, subject, sender identity, reply-to address, a stable draft or campaign ID, and optionally recipient metadata. That becomes the request to your backend.
For example:
{
"draftId": "drf_01JQ2B7NY4TQ0X5G7M1J4N2K7P",
"to": "alex@example.net",
"subject": "Your February product update",
"from": "Updates <updates@news.example.com>",
"replyTo": "support@example.com",
"html": "<!doctype html><html>...</html>",
"design": "{...Beefree JSON...}"
}
The recipient, subject, and sender do not come from Beefree’s core onSend(htmlFile) callback. Your host application supplies them. Keeping those details in your own product model is intentional: it prevents an editor configuration from becoming an uncontrolled delivery authorization mechanism.
Architecture: Beefree is the builder, your backend is the bridge
The simplest safe design uses two application endpoints:
POST /api/email/draftssaves the Beefree JSON and rendered HTML as a draft.POST /api/email/send-from-beefreeturns an approved draft or a currenthtmlFileinto a Volanea API request.
You can combine them for a very small product, but separating draft persistence from sending is usually safer. It makes it possible to support review steps, campaign scheduling, audit trails, test sends, approval roles, and a reliable retry queue.
Why not call Volanea from the browser?
Never put a Volanea API key in beeConfig, a React environment variable exposed to the browser, an iframe query string, local storage, or a client-side API call. Anything shipped to the browser can be inspected, copied, and abused.
An exposed sending credential can be used to send arbitrary mail under your verified domain, consume your sending allowance, harm domain reputation, or expose operational data. The same rule applies to Beefree SDK credentials: Beefree’s own documentation recommends a server-to-server authentication flow and says not to expose the client secret in frontend code.
The safe placement for VOLANEA_API_KEY is a server-only secret store or backend environment variable. For example:
# Server environment only. Do not prefix this for browser exposure.
VOLANEA_API_KEY=vol_live_replace_with_your_secret
VOLANEA_FROM_EMAIL=updates@news.example.com
If you deploy on a managed platform, store this as an encrypted environment secret in that platform’s server-side configuration. Give it only to the runtime or worker that sends mail. Do not return it from any API endpoint, include it in logs, or paste it into a Beefree custom add-on configuration.
Configure Beefree’s send callback
Below is a browser-side example showing how a host application can receive Beefree’s generated HTML. It deliberately sends the HTML to an application endpoint rather than directly to Volanea.
This example assumes your application already obtains the Beefree SDK token through its server-side authentication flow and has loaded the editor. It also assumes the recipient and subject are selected elsewhere in your product UI.
const beeConfig = {
container: "beefree-sdk-container",
onSave: async function (jsonFile, htmlFile, ampHtml, templateVersion, language) {
const response = await fetch("/api/email/drafts", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
credentials: "include",
body: JSON.stringify({
draftId: window.currentDraftId,
design: jsonFile,
html: htmlFile,
ampHtml: ampHtml || null,
templateVersion: templateVersion || null,
language: language || "en-US"
})
});
if (!response.ok) {
throw new Error("Could not save the Beefree email draft");
}
},
onSend: async function (htmlFile) {
const response = await fetch("/api/email/send-from-beefree", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
credentials: "include",
body: JSON.stringify({
draftId: window.currentDraftId,
to: window.selectedRecipientEmail,
subject: window.emailSubject,
from: "Updates <updates@news.example.com>",
replyTo: "support@example.com",
html: htmlFile
})
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.error || "Could not queue the email");
}
console.log("Volanea accepted email request", result);
}
};
The important field mapping is explicit:
| Beefree or application field | Volanea message field | Purpose |
|---|---|---|
htmlFile from onSend | html | Rendered email body created in Beefree |
| Product recipient selector | to | Individual destination address |
| Product subject input | subject | Message subject line |
| Server-approved sender | from | Verified sending identity |
| Product support address | replyTo | Address for recipient replies |
| Stable draft/send operation ID | Idempotency-Key header | Prevents duplicate sends during retries |
Notice that the from value is not trusted simply because the browser supplied it. The browser may suggest a sender profile, but the backend should check it against sender identities your organization has approved and verified.
Send the rendered Beefree HTML through Volanea
The server below uses Node.js with an Express-style route. The example shows the actual integration boundary: it receives data collected by the host application and calls Volanea’s POST /v1/send endpoint over HTTPS.
Before using it, make sure the from domain is verified in Volanea. A message request can be accepted by your server but rejected by the email API if its sender domain is not authorized for the account.
import crypto from "node:crypto";
import express from "express";
const app = express();
app.use(express.json({ limit: "2mb" }));
app.post("/api/email/send-from-beefree", async (req, res) => {
const {
draftId,
to,
subject,
from,
replyTo,
html
} = req.body;
// 1. Authenticate the signed-in application user before this point.
// 2. Authorize whether that user may send from this sender/profile.
// 3. Validate the values before calling Volanea.
if (!draftId || !to || !subject || !html) {
return res.status(400).json({
error: "draftId, to, subject, and html are required"
});
}
if (!/^\S+@\S+\.\S+$/.test(to)) {
return res.status(400).json({ error: "Recipient email is invalid" });
}
// Do not trust a browser-provided sender without checking it.
const allowedFrom = "Updates <updates@news.example.com>";
if (from !== allowedFrom) {
return res.status(403).json({ error: "Sender is not permitted" });
}
// This must be stable for retries of the same logical send.
// Store it with the draft/send record in a real database.
const idempotencyKey = crypto
.createHash("sha256")
.update(`beefree-send:${draftId}:${to}`)
.digest("hex");
// Map the Beefree-generated HTML and app metadata into Volanea's send body.
const volaneaPayload = {
from: allowedFrom,
to,
subject,
html,
...(replyTo ? { replyTo } : {})
};
const volaneaResponse = await fetch("https://api.volanea.com/v1/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.VOLANEA_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": idempotencyKey
},
body: JSON.stringify(volaneaPayload)
});
const responseBody = await volaneaResponse.json();
if (!volaneaResponse.ok) {
console.error("Volanea send failed", {
status: volaneaResponse.status,
responseBody,
draftId
});
return res.status(volaneaResponse.status).json({
error: "Volanea did not accept the email request",
details: responseBody
});
}
// Persist the response and send state in your database here.
return res.status(202).json({
accepted: true,
draftId,
volanea: responseBody
});
});
This is the key Volanea request created by the route:
POST /v1/send HTTP/1.1
Host: api.volanea.com
Authorization: Bearer VOLANEA_API_KEY
Content-Type: application/json
Idempotency-Key: stable-key-for-one-logical-send
{
"from": "Updates <updates@news.example.com>",
"to": "alex@example.net",
"subject": "Your February product update",
"html": "<!doctype html><html>...</html>",
"replyTo": "support@example.com"
}
For broader API details, sender setup, and additional sending examples, refer to the Volanea email API reference. The integration above uses a single-recipient request, which is the safest place to start while you validate your product’s permissions, unsubscribe behavior, and delivery workflow.
Treat HTML, recipients, and sender identity as separate concerns
A Beefree design is content. It is not complete sending authorization.
That distinction becomes especially important when multiple users can edit emails, when teams share templates, or when your product supports multiple brands. The email content may be created by one user, approved by another, and sent only by a service account associated with a specific tenant or sender domain.
Validate the HTML before sending
Beefree generates HTML intended for email clients, but your delivery route should still apply practical safeguards:
- Enforce a reasonable request body size before accepting HTML.
- Save the exact HTML version associated with the send record for auditability.
- Reject unexpected sender identities and reply-to domains.
- Ensure recipient addresses are valid enough for your product’s use case.
- Test the message in common inboxes before a major campaign.
- Preserve an accessible plain-text alternative when your sending workflow requires one.
Avoid “cleaning up” the generated email HTML with aggressive generic sanitizers. Email markup often relies on tables, inline styles, conditional structures, and attributes that a browser-focused sanitizer may remove. If you must enforce an HTML policy, test it against representative Beefree emails and real target inboxes.
Do not let the browser choose unrestricted recipients
If your application supports one-to-one transactional messages, allowing a user to type a recipient may be reasonable after authorization and validation. For campaign-style mail, your server should resolve the recipient list from a saved segment or audience ID that belongs to the authenticated tenant.
Do not accept an arbitrary array of thousands of browser-provided addresses and immediately turn it into sends. That design makes it difficult to enforce contact permissions, suppression rules, per-tenant rate limits, audit logs, and recipient privacy.
A safer campaign request looks more like this:
{
"draftId": "drf_01JQ2B7NY4TQ0X5G7M1J4N2K7P",
"audienceId": "audience_active_trial_users",
"subject": "Three ways to finish your setup",
"senderProfileId": "sender_product_updates"
}
The backend then loads the stored Beefree HTML and resolves eligible recipients from the database. If you need to send individualized copies at scale, use a queued worker and a carefully controlled batch strategy rather than holding an HTTP request open while every recipient is processed.
Authentication and secrets: where the Volanea key belongs
The Volanea API key lives on the server side of the Beefree integration. In practical terms, that means it belongs in one of these places:
- A server runtime environment variable, such as
VOLANEA_API_KEY. - A managed secret store connected to your backend or worker.
- A private deployment secret injected only into the sending service.
It does not belong in a Beefree configuration object, a frontend .env variable that is bundled for the browser, a custom add-on iframe, a JavaScript source file, a mobile app, or a client-side automation configuration.
This is not merely a general security preference. Beefree’s editor is a client-side experience. Every configuration value needed by the browser can be viewed by a user with developer tools. If an email API key is present there, it should be considered compromised.
Use separate secrets for environments
Use different Volanea API keys for development, staging, and production where your operational setup allows it. This prevents a local prototype from sending real mail and makes it easier to revoke access without interrupting production delivery.
Also keep sender domains separated by environment. A staging preview should not accidentally mail customers from the same sending identity used for production notifications.
Rotate credentials deliberately
Have a rotation procedure before you need one:
- Create a new key in Volanea.
- Add it to the server-side secret store.
- Deploy or reload the sender service.
- Verify a controlled test send.
- Revoke the old key after the new path is confirmed.
Log only key identifiers or masked fragments if you need debugging context. Never log the full authorization header or raw secret value.
When this breaks
A Beefree-to-Volanea connection has more than one hop: a user action in the editor, a browser callback, your application endpoint, a database or queue, and the Volanea API. Reliable delivery depends on identifying which hop failed and making retries safe.
A timeout can cause duplicate email
The most dangerous failure is an ambiguous timeout. Your backend may call Volanea, Volanea may accept the message, but the network connection may close before your backend receives the response. If your code blindly repeats the POST, the recipient may receive the email twice.
Use a stable Idempotency-Key for one logical send and reuse exactly that key on retries. Do not generate a fresh random key every time a user clicks Send or every time your job runner retries.
In the example above, the key is derived from draftId and to. In a real system, it is better to create and persist a dedicated send-operation ID before the first API attempt. That lets a queue worker resume safely after a process restart and lets support staff trace a specific send.
Beefree callback retries are your application’s responsibility
Because Beefree invokes callbacks in the host application rather than delivering an outbound webhook with a documented retry contract, the main retry behavior comes from your own frontend and backend. A user may click Send twice, a browser may retry a request, or your frontend code may accidentally invoke onSend more than once.
Protect against that at several layers:
- Disable or visually lock the send action while the request is in progress.
- Create one durable send-operation record before calling Volanea.
- Enforce a unique database constraint for the logical send identity.
- Reuse the same idempotency key for retries.
- Return the already-recorded result when the same operation is submitted again.
Do not assume a disabled button alone solves duplicate sends. Browser refreshes, multiple tabs, worker retries, and client connection failures can all recreate the request.
Missing fields are often an application-model problem
Beefree’s callbacks provide the design and rendered HTML, but they do not inherently know your recipient, sender policy, campaign audience, or subject-line conventions. If to, subject, or an approved sender is missing, that is normally a missing product-level field—not a reason to try to infer it from Beefree HTML.
Fail closed. Return a clear validation error such as “Choose a recipient before sending” or “This workspace does not have a verified sender profile.” Do not silently substitute a default recipient or sender, especially in multi-tenant applications.
Some Beefree capabilities are also plan-dependent. For example, features such as advanced collaboration or multi-language template workflows can have plan restrictions. Build the email delivery path around the broadly available callback output you actually use—HTML and saved design data—rather than making delivery depend on an optional editor feature your account may not include.
Volanea accepts a request, but inbox delivery is later
A successful API response means Volanea accepted the message request for processing. It should not be interpreted as proof that the recipient has seen the message in an inbox.
For operationally important mail, retain the Volanea response with your internal send record and use delivery events, suppression information, and recipient status in your normal monitoring workflow. This gives your support team a way to distinguish “the browser did not submit,” “our backend rejected the request,” “the API refused the message,” and “the message was processed but later bounced or was suppressed.”
HTML looks right in Beefree but wrong in an inbox
A builder preview is useful, but desktop Outlook, Gmail, Apple Mail, mobile clients, and dark-mode rendering do not behave identically. Email HTML has constraints that ordinary web pages do not.
Before sending at scale:
- Send an internal test through the same Volanea path used in production.
- Check links, images, alt text, and unsubscribe or preference links where applicable.
- Review mobile layout and dark-mode behavior.
- Confirm the sender and reply-to addresses are correct.
- Verify that the email’s visible subject aligns with its content and audience expectation.
The delivery integration should preserve the exact generated HTML used for the test and production send. That makes visual regressions easier to reproduce.
Build a production-ready send workflow
A direct request from onSend to your backend is a good starting point, but mature products should model email sending as a stateful workflow instead of a single browser action.
A useful send record might contain:
{
"id": "send_01JQ2C7R5EJ66P03H5K9N1V7YQ",
"draftId": "drf_01JQ2B7NY4TQ0X5G7M1J4N2K7P",
"tenantId": "team_123",
"requestedByUserId": "usr_456",
"recipient": "alex@example.net",
"from": "updates@news.example.com",
"subject": "Your February product update",
"idempotencyKey": "...",
"state": "queued",
"createdAt": "2026-09-30T12:00:00.000Z"
}
The browser creates the request. The server validates it and records queued. A worker performs the Volanea request and records the outcome. This gives you a durable boundary between an interactive editing experience and a delivery operation that may need retrying.
Recommended states
A simple state machine is enough for many applications:
draft— Beefree JSON and HTML are saved but not approved for delivery.queued— The user or system requested a send and the server accepted the work.sending— A worker has claimed the operation.accepted— Volanea accepted the API request.failed— A permanent validation, authorization, or provider error needs action.cancelled— The send was stopped before it was handed to the provider.
For campaign use cases, keep recipient-level states too. A campaign can be accepted while individual recipients are skipped, suppressed, or fail later. One top-level “sent” flag is rarely enough for support, analytics, or compliance.
Alternatives when you need automation rather than embedded editing
This guide is specifically for Beefree SDK embedded in your own product. If what you need is a no-code business automation that starts from a CRM record, form response, subscription change, or pipeline stage, Beefree may not be the event source for that workflow.
In that situation, keep Beefree focused on creating the HTML template and use the system that owns the business event to trigger your middleware. For example, a form platform, CRM, database automation, or workflow tool can call a backend endpoint or a service such as Zapier or Make. That middleware can then retrieve an approved Beefree-generated template from your application and call Volanea.
The crucial rule remains unchanged: put the Volanea API key in a server-side secret field within the middleware or backend, never in a client-visible Beefree configuration.
For a simple one-off address check before your backend queues mail, you can also use the email address verification tool. Verification is not a substitute for consent, suppression handling, or proper list management, but it can help catch obvious address-entry errors in operational workflows.
Conclusion
To send email from Beefree with Volanea, do not look for a marketplace plugin or attempt a browser-to-provider connection. Beefree SDK gives your application the important outputs—design JSON and rendered email HTML—through callbacks such as onSave and onSend.
Use onSave to persist the editable source of truth. Use onSend(htmlFile) as the editor-side trigger that hands rendered HTML to your authenticated backend. On the server, validate recipients and sender permissions, keep the Volanea API key in a private secret store, generate one stable idempotency key per logical send, and call POST /v1/send with the mapped HTML, recipient, subject, and sender data.
That design is secure, debuggable, and resilient when a browser retries, a network times out, or a user clicks twice. More importantly, it gives your product—not the editor iframe—control over who is allowed to send what, to whom, and from which verified domain.
FAQ
Does Beefree have a native Volanea integration?
No. Beefree SDK does not provide a native Volanea app, marketplace plugin, or direct outbound Volanea connection. The supported integration model is to handle Beefree callbacks in your host application and call Volanea from your backend.
What trigger sends the email from Beefree?
Use Beefree SDK’s onSend(htmlFile) callback as the editor-side send trigger. For a safer workflow, use onSave(jsonFile, htmlFile) to store drafts first, then allow sending only after your application has gathered recipient, subject, and sender details.
Can I put the Volanea API key in Beefree configuration?
No. Beefree configuration is used in the client-side application, where users can inspect it. Store the Volanea API key only in server-side environment variables or a managed secret store, then call Volanea from your backend.
What does Beefree provide to the integration?
Beefree provides callback arguments, including the generated email HTML (htmlFile) and, on save, the editable Beefree design JSON (jsonFile). Your application provides the recipient, subject, sender identity, authorization checks, and delivery policy.
How do I avoid sending duplicate emails after a timeout?
Create one durable send-operation ID for each logical email, reuse the same Volanea Idempotency-Key on every retry, and record send state on your backend. Do not generate a new key for a second click or a retry of the same intended message.