Delighted is no longer available as a standalone product, but teams maintaining a legacy Delighted webhook endpoint can still send email from Delighted through Volanea. The safe architecture is not a marketplace installation: Delighted posts a survey-response event to your server, and your server decides whether to call Volanea’s email API.

Important context: Delighted was sunset on June 30, 2026, and Qualtrics now directs former Delighted users to its Customer Feedback offering. This guide is therefore for existing integrations, exported workflows, and teams operating a legacy endpoint during a migration—not for creating a new native Delighted app or plugin.

What this integration does

This integration turns a Delighted survey response into an operational email. A common example is alerting a customer-success manager when a customer leaves a low NPS score and comment. Another is sending a personal thank-you note after a promoter response, provided the message is appropriate for the survey program and the recipient has not opted out of the relevant communication.

There is no native Volanea listing in Delighted and no “install Volanea” flow in a Delighted marketplace. Delighted’s outbound mechanism is a webhook: when a survey response is created, it sends an HTTP POST request to a URL you control. That URL must be a server-side endpoint, serverless function, or automation middleware—not browser JavaScript.

The resulting flow is straightforward:

  1. A person completes a Delighted survey.
  2. Delighted creates a survey response and sends a survey_response.created webhook event to your HTTPS endpoint.
  3. Your endpoint verifies and records the event, then applies business rules such as “only email for scores of 0 through 6.”
  4. Your endpoint calls POST /v1/send on Volanea with a server-side API key.
  5. Volanea accepts the email for processing and returns a send result. Your application logs the result against the Delighted event ID.

This extra hop is intentional. It keeps the Volanea secret key out of Delighted configuration, lets you handle duplicates safely, and gives you a durable place to validate event data before an email leaves your domain.

The Delighted trigger: a survey response is created

The concrete trigger for this workflow is Delighted’s survey_response.created webhook event. It occurs when a respondent submits a score. A comment may be included when the respondent leaves one, but a comment is not guaranteed; your routing must work for score-only responses.

Do not model this trigger as a contact being created, a form submission, or a lifecycle-stage change. Delighted’s relevant object is the survey response. A person record can exist before a survey is sent, and a response update can occur later if feedback is edited. For first-response notifications, subscribe to survey_response.created rather than treating every response update as a fresh request to send email.

Legacy Delighted webhook payloads use an envelope with an event type, a unique event ID, and an event_data object containing the response. The response data commonly includes the score, comment, person information, timestamps, and custom properties. Build against the fields you actually receive in a test delivery, because optional fields can be absent depending on the survey channel, respondent data, and account setup.

A representative event shape is:

{
  "event_type": "survey_response.created",
  "event_id": "evt_01HV8Y8PZ7R2Q4J6K9M3",
  "event_data": {
    "id": "res_01HV8Y8M4E6A1B2C3D4E",
    "score": 3,
    "comment": "Setup took longer than expected.",
    "created_at": 1713962640,
    "person": {
      "id": "person_01HV8Y7X",
      "email": "ava@example.com",
      "name": "Ava Patel"
    },
    "properties": {
      "account_id": "acct_4821",
      "plan": "Growth",
      "customer_success_owner": "sam@example.com"
    }
  }
}

Treat that JSON as an inbound event, not as a complete recipient record. Before sending, validate every field your email needs. In particular, do not assume person.email, person.name, comment, or custom properties always exist. A web survey can be anonymous, a name can be blank, and custom properties only exist if your team supplied them when creating or updating the person.

Choose the right architecture for sending email from Delighted

The best implementation is a small middleware service. It can be an Express route, a Next.js route handler, a Cloudflare Worker, an AWS Lambda, a Supabase Edge Function, or an existing backend endpoint. The only hard requirements are that it is reachable over HTTPS, can retain the raw request body if signature verification requires it, and has access to a server-side secrets store.

Direct webhook-to-server route

Use a direct server endpoint when you need control over data handling, retry logic, recipient selection, or audit history. It is also the preferred route when feedback comments may contain personally identifiable information or sensitive account context.

Your endpoint should do four fast things when Delighted calls it:

  • Read the raw body and validate the webhook according to the credentials and verification method configured for the legacy Delighted account.
  • Reject an event type other than survey_response.created.
  • Store the event ID in a database with a unique constraint before scheduling the email work.
  • Return a successful HTTP response promptly after the event has been accepted for processing.

The actual Volanea send can happen in the same request for low traffic, but a queue is safer in production. Persist the event first, enqueue a job, and acknowledge the webhook. The worker can then make the Volanea request independently of the inbound webhook timeout.

Middleware route with Zapier or Make

If you do not operate a backend, use an automation service as the middleware layer. Delighted’s survey webhook can be received by a webhook trigger in an automation platform, then transformed and posted to a server endpoint you control. Do not place the Volanea secret in a client-visible webpage, form script, or public webhook URL.

A no-code route still needs careful design. Use an incoming-webhook trigger for the Delighted event, add a filter for the score range you care about, and call a protected internal endpoint that owns the Volanea secret. This keeps email credentials separate from the automation’s input data and lets your server apply idempotency.

For a very small internal workflow, the automation platform can make the Volanea request itself only if its credential store is private to authorized administrators and not exposed in a browser. Review its retry behavior first: automation platforms can replay failed steps, which means duplicate sends are possible without a stable idempotency key.

Set up the webhook endpoint before configuring Delighted

Start with the receiving endpoint. Give it a narrow, dedicated path such as /webhooks/delighted/survey-response. Avoid reusing a general public form endpoint; it makes it harder to apply request validation, rate limiting, monitoring, and event-specific logging.

Your endpoint should accept POST requests with JSON. It should also preserve the exact request bytes until verification is complete. Re-serializing parsed JSON can change whitespace or key order, which matters for signature schemes that sign the raw request body.

Configure these secrets in your server environment or secrets manager:

VOLANEA_API_KEY=sk_live_...
VOLANEA_FROM=feedback@example.com
DELIGHTED_WEBHOOK_SECRET=...
INTERNAL_ALERT_RECIPIENT=customer-success@example.com

The VOLANEA_FROM address must use a domain that has already been verified in Volanea. The API will not treat domain authentication as a cosmetic warning: sending from an unverified domain can cause the request to be rejected. Complete domain setup and test with an internal recipient before enabling a live response-driven workflow. The email API reference and setup guides cover the send endpoint, domain setup, and delivery-event handling.

Do not put VOLANEA_API_KEY in a Delighted custom property, webhook URL query parameter, front-end environment variable, browser bundle, Zap payload, or email template. A Volanea secret key authorizes sending. Anyone who obtains it could send mail as your configured domain, consume your sending capacity, and damage sender reputation.

Configure Delighted to call your endpoint

In the legacy Delighted account, configure a webhook destination for survey-response notifications and use your endpoint’s HTTPS URL. The event you want is survey_response.created.

Use a test delivery if the account provides one. Capture the raw payload in a protected development log, redact email addresses and comments before sharing it, and compare the received object with the mapping in your code. This is important because properties differ between survey configurations. A transactional survey sent to identified email recipients has more useful person data than an anonymous link survey.

Before turning the workflow on, decide which responses should result in an email. A practical first rule is detractor escalation:

  • Score 0–6: send an internal alert to the account owner or support queue.
  • Score 7–8: create a review task, but do not necessarily send immediate email.
  • Score 9–10: optionally notify a customer-advocacy workflow, subject to your outreach policy.
  • Missing score: log and hold for review rather than guessing.

This classification is a business rule, not a guarantee that every Delighted program uses NPS. For CSAT or CES surveys, scores and thresholds mean different things. Put the threshold in configuration so you can change it without redeploying code.

Map the Delighted payload to a Volanea email

The code below is a working Node.js/Express pattern. It maps a Delighted survey_response.created event to an internal alert email. It deliberately sends to an internal team address rather than automatically emailing the survey respondent. That default is safer: a feedback response is not automatically permission to begin a new external email conversation.

The handler uses the Delighted event_id as the Volanea Idempotency-Key. That is the critical mapping for duplicate protection. If Delighted retries the same webhook delivery, your application can repeat the Volanea request without creating another logical notification.

import express from "express";

const app = express();

// Keep raw bytes available for webhook verification if your legacy
// Delighted configuration provides a signing secret/header.
app.use("/webhooks/delighted", express.raw({ type: "application/json" }));

app.post("/webhooks/delighted/survey-response", async (req, res) => {
  const rawBody = req.body;

  // Verify the raw request here when your Delighted webhook setup supplies
  // a signature and signing secret. Reject before parsing if verification fails.
  // const signature = req.get("X-Delighted-Webhook-Signature");
  // if (!verifyDelightedSignature(rawBody, signature, process.env.DELIGHTED_WEBHOOK_SECRET)) {
  //   return res.status(401).json({ error: "invalid webhook signature" });
  // }

  let event;
  try {
    event = JSON.parse(rawBody.toString("utf8"));
  } catch {
    return res.status(400).json({ error: "invalid JSON" });
  }

  if (event.event_type !== "survey_response.created") {
    return res.status(204).end();
  }

  const response = event.event_data ?? {};
  const score = Number(response.score);
  const comment = typeof response.comment === "string" ? response.comment : "";
  const person = response.person ?? {};
  const properties = response.properties ?? {};

  if (!event.event_id || !Number.isFinite(score)) {
    return res.status(422).json({ error: "missing event_id or score" });
  }

  // Example policy: alert an internal team only for detractor scores.
  if (score > 6) {
    return res.status(204).end();
  }

  const customerName = person.name || "Unknown respondent";
  const customerEmail = person.email || "No email supplied";
  const accountId = properties.account_id || "Not supplied";
  const safeComment = escapeHtml(comment || "No comment supplied");

  const emailPayload = {
    from: process.env.VOLANEA_FROM,
    to: process.env.INTERNAL_ALERT_RECIPIENT,
    subject: `Delighted follow-up needed: score ${score}`,
    html: `
      <h1>Customer feedback needs review</h1>
      <p><strong>Score:</strong> ${score}</p>
      <p><strong>Respondent:</strong> ${escapeHtml(customerName)}</p>
      <p><strong>Email:</strong> ${escapeHtml(customerEmail)}</p>
      <p><strong>Account ID:</strong> ${escapeHtml(String(accountId))}</p>
      <p><strong>Comment:</strong> ${safeComment}</p>
      <p><strong>Delighted event:</strong> ${escapeHtml(event.event_id)}</p>
    `,
    text: [
      "Customer feedback needs review",
      `Score: ${score}`,
      `Respondent: ${customerName}`,
      `Email: ${customerEmail}`,
      `Account ID: ${accountId}`,
      `Comment: ${comment || "No comment supplied"}`,
      `Delighted event: ${event.event_id}`
    ].join("\n")
  };

  const sendResponse = await fetch("https://api.volanea.com/v1/send", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.VOLANEA_API_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": `delighted:${event.event_id}`
    },
    body: JSON.stringify(emailPayload)
  });

  const result = await sendResponse.json();

  if (!sendResponse.ok) {
    console.error("Volanea send failed", {
      delightedEventId: event.event_id,
      status: sendResponse.status,
      result
    });
    return res.status(500).json({ error: "email send failed" });
  }

  return res.status(200).json({ accepted: true });
});

function escapeHtml(value) {
  return String(value)
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#039;");
}

app.listen(3000);

The key field mapping is explicit:

Delighted fieldVolanea useWhy it matters
event.event_idIdempotency-KeyMakes retries safe for one logical feedback event.
event.event_data.scoreSubject and message bodyGives the receiving team triage context.
event.event_data.commentHTML and text bodyPreserves the respondent’s written feedback.
event.event_data.person.nameMessage bodyIdentifies the respondent when supplied.
event.event_data.person.emailMessage body, not necessarily toLets the team find the person without automatically contacting them.
event.event_data.properties.account_idMessage bodyLinks feedback to an account or CRM record.

Use text as well as html. An HTML-only internal alert may still be readable, but a plain-text alternative gives recipients and security tools a dependable fallback.

Keep the Volanea API key off the Delighted side

The direct answer to “where does the Volanea key live on the Delighted side?” is: nowhere. Delighted should hold only the destination webhook URL. The Volanea secret belongs in the secret store of the server or middleware that receives the webhook.

That separation is more than a security preference. A webhook sender cannot safely protect a third-party sending credential that is embedded in a URL or exposed in client-side configuration. URLs are often copied into logs, browser histories, proxy records, screenshots, alert messages, and support tickets. Query-string secrets are especially risky because they are routinely logged.

Use a runtime environment variable, cloud secrets manager, or encrypted deployment secret. Restrict access to the production secret to the service identity that sends mail. Keep test and production keys separate, rotate the key after an accidental exposure, and remove old keys when a migration is complete.

If you use Zapier or Make as an intermediary, do not assume a visual workflow makes secrets harmless. Limit editor access, use the platform’s credential storage when available, avoid inserting the key into a templated URL, and still prefer a private backend endpoint for the final Volanea API call. That endpoint can authenticate the automation with a separate scoped shared secret or signed request rather than disclosing the Volanea key.

Decide who receives the message

A response-triggered workflow needs an explicit recipient policy. The response’s person.email is useful data, but it should not automatically become the Volanea to address.

For detractor follow-up, internal notification is usually the least surprising first action. Send to a shared customer-success address, a support queue, or an account owner resolved from a trusted CRM. Your team can review context and choose the appropriate channel, timing, and owner.

For an external response, add safeguards:

  1. Check that the person has not opted out of the communication type you intend to send.
  2. Confirm the email address exists and is valid before using it as a recipient.
  3. Avoid sending a generic automated message that repeats sensitive feedback in the subject line.
  4. Use a stable customer or case identifier to prevent multiple teams replying independently.
  5. Make the message’s purpose clear and include an appropriate reply path.

If you need an additional syntax and deliverability check before a customer-facing follow-up, run the address through the free email verification tool. Verification reduces obvious address errors, but it does not replace consent checks, suppression handling, or careful outreach policy.

When this breaks: Delighted retries, timeouts, and missing fields

Webhook integrations fail at the boundaries. Design for those boundaries before feedback volume makes them painful.

Delighted retries can create duplicate sends

A webhook sender can retry when it does not receive a timely successful response or when the receiving endpoint returns an error. The same Delighted event may therefore arrive more than once. It may even arrive concurrently if a prior request was slow enough to time out.

Do not deduplicate by customer email, score, or comment. Two real survey responses can have the same values. Deduplicate by the unique Delighted event_id.

Use two layers of protection:

  • Store each event_id in your database with a unique index before dispatching work.
  • Pass a deterministic Idempotency-Key, such as delighted:<event_id>, to Volanea’s send endpoint.

The database prevents your own workers from processing the same event twice. The Volanea idempotency key protects the outbound API call if your application retries after an uncertain network failure. Those are different failure modes, so use both.

A webhook timeout does not mean the email was not sent

The most dangerous situation is an uncertain result. Your service may call Volanea successfully, then lose the connection before it can return a response to Delighted. Delighted sees a timeout and retries. Without idempotency, the retry can create a second email.

The fix is not to make the webhook handler wait longer. Persist the event, enqueue the work, and return a 2xx response quickly. The queue worker should use the stable idempotency key and write the Volanea response to your event record. If the worker crashes after the outbound request, retry the same job with the same key.

Payload fields can be absent

Do not write response.person.email.toLowerCase() or response.comment.trim() without checking the field. Anonymous surveys, incomplete respondent profiles, and different survey channels can omit values you expected.

Treat fields in three categories:

  • Required to process: event ID and numeric score for this example.
  • Useful but optional: comment, name, person email, account ID, and plan.
  • Never trusted without validation: custom properties and any data used to select a recipient or construct links.

If an account owner property is missing, route the alert to a controlled fallback queue. If the person email is missing, do not fabricate it from another value. If the score is malformed, quarantine the event and alert an operator rather than silently classifying it.

Signature verification and URL security can fail

If your legacy Delighted configuration supplies a signature header and signing secret, verify the signature against the unmodified raw body before parsing or acting on the payload. If it does not, treat the endpoint as an internet-facing ingestion point: use a hard-to-guess path, apply rate limits, validate the event shape, and consider network controls where your hosting environment supports them.

Never use the absence of a signature as a reason to accept arbitrary requests and send email. At minimum, require expected event types, validate value types, reject oversized bodies, and ensure recipient routing comes from trusted configuration or a trusted database rather than directly from arbitrary event fields.

The mail request can be accepted but the message can still be skipped

An accepted API call is not the same as inbox delivery. A recipient can be suppressed, unsubscribed, invalid, over quota, or blocked by downstream mailbox systems. For customer-facing emails, record the Volanea message result and subscribe to delivery, bounce, and complaint events so your system has an outcome trail.

Operationally, this matters because a CRM task marked “email sent” can be misleading. Use a clearer state model: webhook_received, qualified, send_accepted, delivered, bounced, or skipped. A person should not receive a second “follow-up” simply because a first send was accepted but later bounced.

Test the complete path before enabling live responses

A production-ready test is more than sending yourself a sample email. Test each boundary in the chain.

First, send a captured or synthetic survey_response.created payload to a non-production endpoint. Confirm that a detractor score sends one internal email, while a passive or promoter score follows your intended branch. Then resend the identical event ID and verify that it does not create a second message.

Next, remove optional data one field at a time. Test no comment, no person name, no person email, no account ID, and no custom properties. The result should either be a useful fallback email or a logged, controlled rejection—not an uncaught exception.

Finally, test the adverse paths:

  • Make the Volanea API key invalid and ensure your worker records a failed send.
  • Simulate a Volanea timeout after request dispatch and confirm a retry keeps the same idempotency key.
  • Return a temporary error from the endpoint and verify the webhook retry does not generate duplicates.
  • Use an unverified From domain in a test environment and confirm the configuration error is visible.
  • Send an event with a malicious HTML-like comment and confirm it is escaped in the HTML email.

These tests reveal the difference between a demo integration and an operational one. They also create runbook material for the person who will troubleshoot a real customer escalation later.

Migration implications after Delighted’s sunset

Because Delighted was sunset on June 30, 2026, avoid adding more business-critical dependencies to its event model. The webhook receiver described here is still useful because it separates the source event from the email-sending layer. When you replace Delighted, you can keep the downstream queue, idempotency rules, recipient policy, Volanea API call, monitoring, and delivery handling. You only need to replace the inbound adapter and field mapping.

That separation is the long-term benefit of middleware. Do not let survey-provider payload names spread through customer-success workflows, templates, CRM logic, and database schemas. Normalize the event into your own structure, such as feedback.received, with fields like source_event_id, score, comment, respondent_email, account_id, and received_at.

A normalized record also improves governance. You can document which system owns consent, which system chooses the responder, how long comments are retained, and when an internal alert becomes an external email. Those questions matter more than the HTTP request itself.

A practical production checklist

Before relying on this workflow for real customer feedback, verify the following:

  • Your legacy Delighted account is still capable of delivering to the configured webhook URL.
  • The subscribed trigger is survey_response.created, not a generic person or response-update event.
  • The webhook endpoint accepts HTTPS POST requests and validates the raw request appropriately.
  • The Volanea API key is stored only in server-side secret storage.
  • The From address belongs to a verified Volanea sending domain.
  • A unique database constraint protects the Delighted event ID.
  • Every Volanea request includes an Idempotency-Key derived from that event ID.
  • Optional payload fields have fallbacks or controlled error handling.
  • HTML output escapes survey comments and other untrusted string values.
  • Internal alerts and customer-facing follow-ups have separate routing rules.
  • Delivery, bounce, and complaint outcomes are monitored for customer-facing sends.
  • The workflow has a migration owner and a documented replacement plan for the sunset product.

Conclusion

To send email from Delighted with Volanea, use Delighted’s survey_response.created webhook as the trigger and a server-side middleware endpoint as the bridge. The middleware validates the event, uses the Delighted event ID as an idempotency key, maps safe fields into a Volanea POST /v1/send request, and keeps the Volanea credential out of Delighted and out of the browser.

That design is reliable because it assumes the real behavior of distributed systems: webhooks retry, networks time out, fields are optional, and an accepted email request is not yet proof of delivery. It is also portable. As you complete a move away from Delighted, retain the normalized feedback event and Volanea sending layer, then swap in the successor survey platform at the inbound edge.

FAQ

Does Volanea have a native Delighted integration?

No. Volanea does not ship a native Delighted marketplace app or plugin. Use a Delighted webhook plus a server-side endpoint, or an automation middleware route, to call Volanea’s REST API.

What Delighted event should start the email?

Use survey_response.created for a newly submitted survey response. It is the appropriate trigger for a first-response alert or follow-up workflow. Do not use survey_response.updated unless you intentionally want revised feedback to enter a separate process.

Where should I store the Volanea API key?

Store it in your backend or serverless platform’s secrets manager as an environment secret. It should not live in Delighted properties, a webhook URL, browser code, a public repository, or any client-visible configuration.

How do I prevent duplicate emails when Delighted retries a webhook?

Persist and uniquely constrain Delighted’s event_id, then send the same stable value in Volanea’s Idempotency-Key header. Use both protections because database retries and outbound HTTP retries are separate failure modes.

Can I automatically email the survey respondent?

Technically, you can map event_data.person.email to the Volanea recipient when it is present. Operationally, do so only after validating the address, checking the applicable consent and suppression status, and defining an appropriate customer-facing follow-up policy.