Send email from Wisepops without exposing an email API key by connecting its form-collection webhooks to a small server-side relay. Wisepops does not provide a native Volanea marketplace app or plugin, but its webhook feature can POST newly collected form data to an endpoint you control, where that data can safely become a Volanea REST API request.
This is a useful pattern for transactional follow-ups that must happen immediately after a visitor submits a Wisepops sign-up form: a welcome message, coupon delivery, quiz result, lead-owner alert, double-opt-in prompt, or requested resource link. The important detail is architectural: Wisepops collects the response, your server validates and maps it, and Volanea sends the email.
The flow is deliberately not browser-to-email-provider. A Volanea secret API key is a server credential, so it must never be included in a Wisepops campaign’s front-end configuration, JavaScript, custom HTML, or a public page source.
What this integration does
Wisepops webhooks are triggered when form data is collected in a campaign. Its webhook settings let you select an event type—Email, Phone, or Survey—that corresponds to the kind of block in the campaign. For an email follow-up, configure an Email hook for a campaign that contains a sign-up block. When a visitor completes that block, Wisepops sends an HTTP POST payload to the URL you configured.
The complete path looks like this:
- A visitor submits a Wisepops sign-up form or survey.
- Wisepops collects the response and POSTs it to your HTTPS webhook endpoint.
- Your endpoint checks the route secret, validates the email address, and reads the submitted fields.
- Your endpoint calls Volanea’s
POST /v1/sendendpoint using a server-side secret key. - Volanea queues the transactional message and returns the queued message record.
- Your endpoint returns a successful response to Wisepops only after it has handled the event appropriately.
Wisepops describes webhook delivery as near-real-time and automatically retries failed requests. That makes it better suited to immediate lead handling than repeatedly polling the contacts API for new records. But automatic retries also mean your receiving service must be safe when it receives the same logical submission more than once.
The real Wisepops trigger: collected form data
The trigger is not a generic “campaign published” or “popup displayed” event. It is data collected by a form block in a Wisepops campaign.
In practical terms, choose the hook event that matches the campaign block:
- Email for a sign-up block that collects an email address.
- Phone for a phone block.
- Survey for a survey block.
For the common welcome-email use case, the event begins when a visitor submits the campaign’s sign-up block and Wisepops records the response. The webhook is then posted to your target URL in seconds.
That distinction matters. A visitor seeing a popup has not necessarily opted in, provided an address, or requested a response. Sending email on display or click would be both technically unreliable and potentially non-consensual. Sending after the email form is collected gives your service an actual recipient value and a specific interaction to log.
Decide what the first email should be
A webhook-triggered Wisepops email should have one clear reason to exist. Good examples include:
- “Here is your 15% welcome code.”
- “Here is the guide you requested.”
- “Thanks for taking the quiz—your result is inside.”
- “Confirm your subscription to receive future updates.”
- “A new high-intent lead submitted the enterprise inquiry form.”
Avoid using this direct webhook path to launch an entire marketing nurture sequence synchronously. The first response can be transactional or consent-related, while downstream marketing enrollment should respect the consent language, audience rules, and suppression state you maintain for campaigns.
Why you need a webhook relay instead of a direct Volanea URL
Wisepops can send an outbound HTTP POST to your hook URL. Volanea’s send API requires an authenticated Authorization: Bearer sk_... header. The safe place to join those two systems is a server-side endpoint you operate.
Do not point the Wisepops hook at https://api.volanea.com/v1/send and attempt to put an API key in a browser-visible campaign, a query string, or an unprotected custom script. A Volanea sk_... key has broad project access and is explicitly server-side only.
Your relay has four jobs:
- Receive the Wisepops payload over HTTPS.
- Authenticate the route so random internet traffic cannot trigger sends.
- Normalize and validate the collected fields before they become email content.
- Send safely through Volanea with a stable
Idempotency-Key.
This may sound like extra plumbing, but it gives you control over duplicate prevention, audit logs, content generation, consent handling, testing, and future changes to either product’s payload schema.
Where the Volanea API key lives
The Volanea secret key lives nowhere in Wisepops. It belongs in the secret manager or encrypted environment configuration for the webhook relay—for example, an environment variable configured in your hosting platform:
VOLANEA_API_KEY=sk_...
WISEPOPS_WEBHOOK_TOKEN=a-long-random-route-token
In Wisepops, store only the webhook destination URL, such as:
https://email.example.com/hooks/wisepops/a-long-random-route-token
The route token is not the Volanea API key. It is a separate shared secret used to make the receiving URL difficult to discover and to reject requests sent to an incorrect path. Treat it as sensitive because anyone who knows the full URL may be able to submit requests to that endpoint.
A key placed in client-visible configuration can be copied by a visitor, browser extension, page cache, analytics tool, or anyone with access to the campaign HTML. Once leaked, it can be used outside the intended Wisepops workflow. Keep the Volanea key in server-side secret storage, rotate it when access changes, and never print it in application logs.
Configure the Wisepops webhook
Wisepops documents webhook management in the Settings > Email API area. Create a hook there and select the form event that matches the campaign block. For a welcome email triggered by a sign-up form, select Email.
Use an HTTPS endpoint that you control. It should accept JSON POST requests and return quickly. A typical production webhook URL includes a high-entropy path component rather than using a predictable route such as /webhook.
A practical setup checklist is:
- Create and deploy the relay endpoint before creating the hook.
- Add
VOLANEA_API_KEYas a deployment secret, not in source control. - Add a separate
WISEPOPS_WEBHOOK_TOKENsecret. - Configure the hook URL in Wisepops as
https://your-domain/hooks/wisepops/<token>. - Select the Email event for a sign-up block, or Survey where the survey itself includes the recipient field you will use.
- Use Wisepops’s Test hook control to send a test payload and inspect the response.
- Start with an inbox you control before activating the campaign for real traffic.
Wisepops hooks are associated with a specific website. If you manage multiple sites in Wisepops, use separate URLs or an explicit site identifier per environment. That prevents a staging campaign from sending production email or a lead from one brand being processed under another brand’s sender identity.
Wisepops payload shape and field mapping
Wisepops contact data uses a top-level collection timestamp, the campaign identifier, visitor context, and a fields object containing the values collected by the form. An email sign-up payload follows this structure:
{
"collected_at": "2019-10-10T10:10:58.389Z",
"wisepop_id": 12345,
"ip": "127.0.0.1",
"country_code": "US",
"fields": {
"email": "example@example.com",
"Gender": "male",
"City": "New York"
}
}
The important mapping is not the optional demographic data. It is:
| Wisepops field | Meaning | Volanea use |
|---|---|---|
fields.email | Address submitted in the sign-up block | to |
fields.first_name or another configured form field | Recipient name, if collected | variables.firstName |
wisepop_id | Wisepops campaign identifier | Internal metadata or idempotency input |
collected_at | Collection timestamp | Idempotency input and audit logging |
country_code | Visitor country context, when present | Optional personalization or routing logic |
Custom form-field names are configurable, so do not assume every campaign will have first_name, City, Gender, or even exactly the same capitalization. In the relay, use the actual field name configured in the Wisepops campaign and make optional fields genuinely optional.
For example, a popup that only asks for email should work even if fields.first_name is absent. A survey may send a different set of response keys than a sign-up campaign. Depending on your Wisepops plan and campaign configuration, fields that exist in one form may not be available in another payload, so your handler should define fallbacks rather than failing the entire webhook because a personalization value is missing.
Working Node.js relay: Wisepops to Volanea
The following Express example receives the Wisepops payload, verifies a secret embedded in the webhook path, maps fields.email into Volanea’s to field, and creates a stable idempotency key from the Wisepops campaign ID, collection time, and recipient address.
The Volanea request uses POST https://api.volanea.com/v1/send, a bearer secret key, JSON content, and the Idempotency-Key header. The message body uses documented to, subject, html, and variables fields.
import "dotenv/config";
import express from "express";
import crypto from "node:crypto";
const app = express();
app.use(express.json({ limit: "256kb" }));
const { VOLANEA_API_KEY, WISEPOPS_WEBHOOK_TOKEN } = process.env;
if (!VOLANEA_API_KEY || !WISEPOPS_WEBHOOK_TOKEN) {
throw new Error("Missing VOLANEA_API_KEY or WISEPOPS_WEBHOOK_TOKEN");
}
function isEmail(value) {
return typeof value === "string" &&
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
}
app.post("/hooks/wisepops/:token", async (req, res) => {
if (!crypto.timingSafeEqual(
Buffer.from(req.params.token),
Buffer.from(WISEPOPS_WEBHOOK_TOKEN)
)) {
return res.status(404).json({ error: "not_found" });
}
// Real Wisepops email-form payload fields:
// body.collected_at, body.wisepop_id, body.ip, body.country_code,
// and body.fields.email plus any custom form fields.
const body = req.body ?? {};
const fields = body.fields ?? {};
const email = typeof fields.email === "string"
? fields.email.trim().toLowerCase()
: "";
if (!isEmail(email)) {
// Return 2xx for a deliberately ignored malformed submission so it is
// recorded but not retried forever. Alert internally if this is unexpected.
return res.status(202).json({ ignored: "missing_or_invalid_email" });
}
const firstName = typeof fields.first_name === "string"
? fields.first_name.trim()
: "there";
const campaignId = String(body.wisepop_id ?? "unknown-campaign");
const collectedAt = String(body.collected_at ?? "unknown-time");
// A stable value is essential because Wisepops retries failed hook deliveries.
const idempotencyKey = crypto
.createHash("sha256")
.update(`wisepops:${campaignId}:${collectedAt}:${email}`)
.digest("hex");
const volaneaResponse = await fetch("https://api.volanea.com/v1/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${VOLANEA_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": idempotencyKey
},
body: JSON.stringify({
to: email,
subject: "Thanks for signing up",
html: "<p>Hi {{firstName}},</p><p>Thanks for signing up. Your welcome offer is <strong>WELCOME15</strong>.</p>",
variables: {
firstName,
wisepopsCampaignId: campaignId,
countryCode: body.country_code ?? ""
}
})
});
const responseBody = await volaneaResponse.json().catch(() => null);
if (!volaneaResponse.ok) {
console.error("Volanea send failed", {
status: volaneaResponse.status,
code: responseBody?.error?.code,
campaignId,
collectedAt
});
// A non-2xx response tells Wisepops the delivery was not processed.
// Its webhook retry behavior can attempt the event again.
return res.status(502).json({ error: "email_send_failed" });
}
console.info("Wisepops email queued", {
campaignId,
collectedAt,
message: responseBody?.messages?.[0]
});
return res.status(200).json({ ok: true });
});
app.listen(process.env.PORT || 3000, () => {
console.log("Wisepops webhook relay is listening");
});
Before deploying this exact sample, make one implementation adjustment: ensure both strings passed to timingSafeEqual have equal length. Since your configured route token should always be the same length as the expected environment value, use a preliminary length check before calling it:
if (
req.params.token.length !== WISEPOPS_WEBHOOK_TOKEN.length ||
!crypto.timingSafeEqual(
Buffer.from(req.params.token),
Buffer.from(WISEPOPS_WEBHOOK_TOKEN)
)
) {
return res.status(404).json({ error: "not_found" });
}
For production, also persist each logical webhook event in a database before or alongside the send attempt. Volanea’s idempotency protection makes repeated calls with the same key safe, but a durable event table improves observability: you can see whether the first request timed out, whether Wisepops retried, and which Volanea message was ultimately queued.
For endpoint syntax, authentication, idempotency behavior, and send-response details, use the Volanea API reference and setup guides.
Build a reliable idempotency strategy
A webhook delivery is an at-least-once integration, not a guarantee that your endpoint will see an event exactly once. If your service processes the send but loses the response connection before Wisepops receives a 200, Wisepops may retry. Without idempotency, that retry can create a duplicate welcome email.
Volanea supports an Idempotency-Key header for this reason. When the same key is repeated, Volanea replays the stored response instead of creating another logical send.
What should be in the key?
Use values that identify one form collection event rather than a generic value such as the email address alone. The sample uses:
wisepops:<wisepop_id>:<collected_at>:<normalized-email>
That means:
- One visitor can submit a later campaign and receive a different message.
- Two campaigns can send different follow-ups to the same address.
- A retry of the same collection event maps to the same logical email send.
Do not use a random UUID created for each request. A random value defeats idempotency because every retry looks new. Do not use only fields.email, either, because it would suppress legitimate future messages to the same subscriber.
If you need stronger deduplication than the fields available in the payload allow, write an inbound-event record in a database with a unique constraint over your chosen event fingerprint. Store the payload hash, campaign ID, normalized recipient, collection time, processing status, Volanea message ID, and error code. That record becomes your source of truth for replays and support investigations.
Test the flow before activating a campaign
Wisepops provides a Test hook action in its webhook interface. Use it before turning the campaign live. The test is valuable because it exercises the exact outbound connection from Wisepops, not merely a local curl request from your laptop.
Run this test sequence:
- Deploy the relay with a Volanea test key (
sk_test_...) first. - Add the hook in Wisepops under Settings > Email API.
- Select the appropriate event type, usually Email.
- Use Test hook and confirm your relay returns a
200response. - Check relay logs for the campaign ID, collection time, and a non-secret Volanea response summary.
- Confirm the Volanea response is in test mode and renders as expected.
- Switch to a secret key only after the payload mapping and message content are correct.
- Submit the live form with an inbox you own.
A successful response from POST /v1/send means Volanea durably queued the message for processing. It is not equivalent to an inbox placement guarantee or an open event. For operational visibility, inspect the message’s later state through Volanea email records or delivery webhooks.
Validate the sender before debugging code
Your sending domain needs to be configured and verified in Volanea before a live email can be accepted for delivery. An API key authorizes the API call; it does not authorize arbitrary sender domains.
This is a common setup trap: the webhook works, the relay receives the payload, and the Volanea request is correctly authenticated, but the send fails because the chosen sender identity is not ready. Verify the sending domain first, then test the relay. If you are evaluating volume and setup requirements, review transactional email pricing and sending plans before moving the campaign live.
When this breaks
The hard part of this integration is not the happy-path POST request. It is the boundary between a third-party webhook sender, your infrastructure, and an email API with real-world side effects.
Wisepops retries create duplicate-send risk
Wisepops automatically retries failed webhook requests. A retry can happen when your endpoint returns an error, times out, crashes after sending, or becomes temporarily unreachable.
The correct response is not to disable retries. Retries protect you from temporary failures. The correct response is to make processing idempotent:
- Generate the same Volanea
Idempotency-Keyfor the same Wisepops collection event. - Persist event state if the flow is business-critical.
- Do not generate a new random request ID for each retry.
- Return
200only when the event has been safely accepted, queued, or intentionally ignored.
If Volanea accepts the email but your process dies before replying to Wisepops, the next attempt will call Volanea with the same key. That is the precise scenario idempotency is designed to solve.
Webhook timeouts make synchronous work fragile
A webhook handler should do minimal synchronous work: validate, store or enqueue, initiate the send, and respond. Avoid generating large PDFs, querying several unrelated systems, waiting for CRM enrichment, or performing slow marketing segmentation in the request path.
If the relay takes too long, Wisepops can treat the request as failed and retry it. Even with idempotency, long-running requests consume capacity and make monitoring noisier. The more durable design is to acknowledge the inbound event after saving it to a queue or database, then have a worker call Volanea.
For low-volume welcome emails, the direct relay shown above is often sufficient. For high-volume campaigns or workflows with multiple external dependencies, convert the handler into an ingestion endpoint and process events asynchronously.
Payload fields are missing or named differently
Wisepops places collected form values under fields, but the contents depend on the block and campaign configuration. A campaign may only collect email; another may use a custom field name such as First name, first_name, or Name.
Do not write code that assumes every custom field exists. Validate the required recipient field, then use graceful fallbacks for everything else:
const firstName = fields.first_name || fields["First name"] || "there";
If a field is unavailable for the relevant Wisepops plan, event type, or form configuration, do not try to manufacture it from visitor data. Use generic copy, update the campaign to collect the field with clear consent, or route that campaign to a different template.
Also treat field names as integration contracts. If a marketer changes a Wisepops form field from first_name to First Name, your personalization mapping can silently stop working. Add a payload-schema test and alert when expected optional fields disappear at an unusual rate.
The endpoint receives non-Wisepops traffic
A webhook URL is reachable from the internet. The route token reduces accidental or opportunistic misuse, but it is not a replacement for good application controls.
At minimum:
- Use HTTPS only.
- Use a long, randomly generated path token.
- Compare the token safely.
- Rate-limit the route.
- Limit JSON body size.
- Validate recipient addresses and field types.
- Log request metadata without logging unnecessary personal data.
- Rotate the route token if it is exposed or an administrator leaves.
Do not trust arbitrary fields as HTML. The sample only inserts a controlled firstName variable into a fixed template, but even then you should HTML-escape values if your rendering layer does not do that automatically. Never put untrusted survey answers directly into HTML without escaping them.
A 200 response is not an inbox result
A successful Volanea response means the send request was accepted and queued. It does not prove the recipient received the email in the inbox. A recipient can still be suppressed, unsubscribed, rejected by a receiving server, deferred, filtered, or later bounced.
Treat the send API response as one operational event and delivery feedback as another. If the campaign matters commercially, connect Volanea delivery and bounce events to your operational logs. That lets your team distinguish “Wisepops did not call us,” “the relay rejected the payload,” “Volanea rejected the request,” “Volanea queued the email,” and “the destination mailbox rejected it.”
Alternatives when a direct relay is not right
The webhook relay is the strongest option when you can deploy a small endpoint and want full control of security, content, deduplication, and logs. It is not the only architecture.
Use an automation platform as middleware
If your team cannot host code, an automation platform can sit between Wisepops and your email-sending logic. The general model is still the same: Wisepops webhook to middleware, middleware validates and maps fields, middleware calls an authenticated server-side email action.
Be careful with this route. Confirm that the middleware can preserve an idempotency key across retries, store the Volanea secret in its credential vault, inspect the original request, and return fast enough for the hook sender. A no-code workflow is not automatically duplicate-safe merely because it looks visual.
For sensitive or high-volume lead flows, a relay you control is often easier to audit. For low-volume experiments, middleware can be a reasonable bridge as long as it keeps secrets out of the browser and has an explicit deduplication plan.
Poll the contacts API only when real-time is unnecessary
Wisepops also provides an API for retrieving collected contacts. Polling can work for a scheduled batch export, but it is less suitable for immediate confirmation or content delivery. You must manage a cursor or collection timestamp, handle API-call limits, and define what happens when a poll fails between intervals.
Use the webhook for “a person submitted this form; react now.” Use scheduled retrieval for periodic synchronization where a few minutes of delay is acceptable.
Operational checklist for production
Before relying on this workflow for customers, verify every item below:
- Your Wisepops campaign has a sign-up or survey block with the fields your mapping expects.
- The webhook event type matches the block: Email, Phone, or Survey.
- The Wisepops hook targets an HTTPS endpoint you control.
- The Volanea API key exists only in server-side secret storage.
- The route token is separate from the Volanea API key.
- Your sender domain is verified in Volanea.
- The relay rejects malformed or missing recipient addresses.
- The relay escapes or safely renders custom field values.
- The
Idempotency-Keyis deterministic for one collection event. - Your database or queue records processing state for important flows.
- Your logs omit full API keys and avoid retaining unnecessary personal data.
- You have tested Wisepops’s Test hook and a real campaign submission.
- You monitor both relay failures and later email delivery events.
A small amount of deliberate engineering here prevents the most expensive failures: leaked send credentials, duplicate coupon emails, silent personalization regressions, and a support team that cannot tell whether a lead was collected, queued, delivered, or bounced.
Conclusion
To send email from Wisepops with Volanea, use Wisepops’s native outbound webhook capability rather than looking for a non-existent native Volanea plugin. The concrete trigger is form data collected through a campaign’s Email, Phone, or Survey block; for an email follow-up, that is typically an Email event from a sign-up block.
Route that POST request to a small server-side endpoint, map fields.email into Volanea’s to field, and call POST /v1/send with a bearer secret stored only in your deployment environment. Add a deterministic idempotency key because Wisepops retries failed deliveries, and design optional form fields so missing values do not break the entire send.
That gives you a direct, supportable path from onsite conversion to a reliable email response—without exposing email credentials to visitors or pretending a marketplace integration exists.
FAQ
Does Wisepops have a native Volanea integration?
No. This setup uses Wisepops outbound webhooks plus a server-side relay that calls the Volanea REST API. There is no native Wisepops marketplace installation flow to describe.
What event triggers the email?
Wisepops sends the hook when data is collected by the selected campaign form event. For a standard email signup, configure an Email hook for the campaign’s sign-up block.
Can I put my Volanea API key in Wisepops?
No. Keep the Volanea sk_... secret key in server-side environment variables or a secret manager for your relay. Wisepops should store only the webhook destination URL and, if used, a separate opaque route token.
How do I stop duplicate emails after a webhook retry?
Send a stable Idempotency-Key with the Volanea request. Build it from values that identify the one Wisepops collection event, such as wisepop_id, collected_at, and normalized fields.email.
What happens if the customer’s email is missing from the payload?
Validate fields.email before calling Volanea. If it is absent or invalid, do not attempt a send. Record the event for investigation and return a deliberate response that prevents endless retries for data your workflow cannot process.