Send email from JivoChat without copying contact details into another tool manually: receive JivoChat’s completed-chat webhook, validate it in a server-side relay, and send a mapped transactional message through Volanea. This approach does not require—and does not pretend there is—a native Volanea app in JivoChat’s marketplace.

The important design choice is to treat JivoChat as the event source and Volanea as the delivery service. A completed conversation produces an event; your integration decides whether that event deserves an email, builds the message from safe fields, and asks Volanea to deliver it. That separation gives you a usable audit trail, protects your sending credentials, and makes retry behavior manageable.

What this integration does—and does not do

JivoChat can notify an external URL about chat events through webhooks. For a follow-up email after a support or sales conversation, the useful trigger is JivoChat’s chat_finished event: a chat has ended, so the customer is no longer actively waiting in the widget and a follow-up can be appropriate.

Volanea is not installed inside JivoChat for this setup. Instead, JivoChat sends an HTTP POST to a URL you operate. That endpoint is often called a webhook receiver, relay, or middleware service. It translates the JivoChat event into Volanea’s email-send request.

That distinction matters for security. A JivoChat webhook configuration is an event destination, not a safe place to expose a broad email-sending credential to every browser visitor. Your relay is the only component that needs the Volanea API key.

A basic flow looks like this:

  1. A visitor finishes a JivoChat conversation.
  2. JivoChat posts a chat_finished webhook event to your HTTPS endpoint.
  3. Your endpoint checks that the request is expected and has not already been processed.
  4. The endpoint extracts an email address and conversation context.
  5. The endpoint calls Volanea’s REST email endpoint.
  6. Volanea queues the message and returns a send result; your endpoint records it.

This is best suited to confirmation emails, agent follow-ups, case summaries, product links, appointment next steps, and internal notifications. It is not a reason to email every person who opens a chat. An event being technically available does not establish permission to market to that person.

The JivoChat trigger: chat_finished

The concrete JivoChat trigger for this guide is the chat_finished webhook event. Configure JivoChat’s webhook capability to deliver that event to a public HTTPS URL controlled by your application, such as https://app.example.com/webhooks/jivochat.

A finished chat is a more useful boundary than an individual message. A message-level integration can produce many sends during one conversation, can fire while an agent is still handling the issue, and needs significantly more state management. chat_finished gives the relay a single natural decision point: should the customer receive a follow-up now?

What arrives at your endpoint

JivoChat’s webhook data is JSON with an event name and event data. The exact optional fields depend on the channel and on what the visitor supplied. A website chat where the visitor provided an email can look like this:

{
  "event_name": "chat_finished",
  "event_data": {
    "chat_id": "987654321",
    "client": {
      "id": "123456789",
      "name": "Avery Chen",
      "email": "avery@example.com",
      "phone": "+14155550123"
    },
    "agent": {
      "id": "42",
      "name": "Morgan"
    },
    "channel": {
      "id": "12",
      "title": "Website chat"
    }
  }
}

Treat this as an event envelope, not as a guarantee that all fields exist. event_data.client.email can be absent when the chat channel did not collect an email address, when a visitor declined to provide it, or when the conversation originated in a channel where an email is not available. Similarly, names, agent details, and channel information should be handled as optional values.

Do not infer an email address from a display name, phone number, social profile, or chat ID. If client.email is missing, skip the customer follow-up or route the event to a human workflow. Sending to a guessed address creates privacy, deliverability, and customer-service problems.

Decide the email policy before writing code

The relay should contain explicit policy rather than a blanket “send on every finished chat” rule. A sensible first policy is:

  • Send only when event_name is chat_finished.
  • Send only to a syntactically valid email provided by the customer.
  • Send a transactional follow-up only when the conversation’s purpose supports it.
  • Exclude messages or data that should not be echoed back to the recipient.
  • Log a decision such as sent, skipped_no_email, skipped_duplicate, or skipped_policy.

For acquisition or promotional follow-ups, collect consent separately and retain the consent evidence in your CRM or customer database. A service reply about the conversation may be appropriate under a different legal basis than a campaign email; do not collapse those categories simply because the same webhook powers both.

Architecture: why a server-side relay is required

A direct browser-to-Volanea request is the wrong architecture. A browser bundle, widget configuration, front-end environment variable, or publicly inspectable script cannot safely hold an API key that can send mail from your domain. Anyone who discovers that key can use your account to send abusive mail, damage domain reputation, and consume sending allowance.

A small relay avoids that exposure. It can be an Express application, a serverless function, a container endpoint, or a route in your existing backend. Its responsibilities are narrow:

  • accept the JivoChat webhook over HTTPS;
  • authenticate or otherwise verify the incoming request according to your JivoChat webhook configuration;
  • parse and validate the event shape;
  • deduplicate repeated deliveries;
  • apply consent and business rules;
  • call Volanea using a server-only secret;
  • return a fast HTTP response and retain useful logs.

Keep the Volanea key in a server-side secret store or an environment variable available only to the relay runtime. Examples include a hosting provider’s encrypted secrets feature, a cloud secret manager, or your deployment platform’s protected environment settings. Name it something unambiguous, such as VOLANEA_API_KEY.

JivoChat should store only the destination URL and any inbound verification secret needed by your own endpoint. It should not store the Volanea API key. Even if a configuration interface is access-controlled, that key does not belong in an event-source configuration because the source does not need permission to send mail.

For API request formats, authentication headers, sender verification, and current endpoint details, consult the email API reference and setup guides before deployment. Sender-domain authentication should be complete before you enable automated follow-ups.

Working webhook relay and field mapping

The following Node.js example shows the mapping from a chat_finished payload to a Volanea send request. It deliberately sends a restrained, transactional follow-up and does not include a raw transcript. Store processed chat IDs in a durable database in production; the in-memory Set below only demonstrates the deduplication boundary.

import express from "express";

const app = express();
app.use(express.json({ type: "application/json" }));

const processed = new Set(); // Replace with a DB table or Redis in production.

function validEmail(value) {
  return typeof value === "string" &&
    /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
}

app.post("/webhooks/jivochat", async (req, res) => {
  const payload = req.body;

  // Map JivoChat's event envelope.
  if (payload?.event_name !== "chat_finished") {
    return res.status(204).end();
  }

  const chatId = String(payload?.event_data?.chat_id ?? "");
  const client = payload?.event_data?.client ?? {};
  const agent = payload?.event_data?.agent ?? {};
  const channel = payload?.event_data?.channel ?? {};
  const recipient = client.email?.trim().toLowerCase();

  // A chat ID is the idempotency key for this one-email-per-chat policy.
  if (!chatId) {
    return res.status(400).json({ error: "Missing event_data.chat_id" });
  }
  if (processed.has(chatId)) {
    return res.status(200).json({ status: "duplicate_ignored" });
  }
  if (!validEmail(recipient)) {
    processed.add(chatId);
    return res.status(200).json({ status: "skipped_no_valid_email" });
  }

  const firstName = String(client.name || "there").split(/\s+/)[0];
  const agentName = String(agent.name || "our team");
  const channelName = String(channel.title || "JivoChat");

  // Volanea field mapping:
  // client.email      -> to[0].email
  // client.name       -> to[0].name and template greeting
  // chat_id           -> metadata.jivochat_chat_id and idempotency key
  // agent.name        -> HTML/text content
  // channel.title     -> metadata.jivochat_channel
  const email = {
    from: {
      email: "support@example.com",
      name: "Example Support"
    },
    to: [{ email: recipient, name: String(client.name || "") }],
    subject: "Thanks for chatting with Example Support",
    html: `<p>Hi ${escapeHtml(firstName)},</p>
      <p>Thanks for chatting with ${escapeHtml(agentName)} via ${escapeHtml(channelName)}.</p>
      <p>If you need anything else, reply to this email and our team will help.</p>`,
    text: `Hi ${firstName},\n\nThanks for chatting with ${agentName} via ${channelName}.\n\nIf you need anything else, reply to this email and our team will help.`,
    metadata: {
      jivochat_chat_id: chatId,
      jivochat_client_id: String(client.id ?? ""),
      jivochat_channel: channelName
    }
  };

  try {
    const response = await fetch("https://api.volanea.com/v1/emails", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${process.env.VOLANEA_API_KEY}`,
        "Content-Type": "application/json",
        "Idempotency-Key": `jivochat-chat-finished-${chatId}`
      },
      body: JSON.stringify(email)
    });

    if (!response.ok) {
      const detail = await response.text();
      throw new Error(`Volanea returned ${response.status}: ${detail}`);
    }

    processed.add(chatId);
    return res.status(200).json({ status: "sent", chatId });
  } catch (error) {
    console.error({ chatId, error: String(error) }, "Volanea send failed");
    // Return a non-2xx response so the event source can retry when supported.
    return res.status(502).json({ error: "Email provider request failed" });
  }
});

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

app.listen(process.env.PORT || 3000);

The field mapping is intentionally visible rather than hidden in a generic template helper. client.email becomes the recipient; client.name personalizes the greeting; chat_id becomes both metadata and the idempotency basis; and agent/channel fields add context without exposing the full private conversation.

Before using a template, validate each dynamic field and HTML-escape it. Chat-provided values are untrusted input. Without escaping, a visitor’s display name could alter your generated HTML. Plain-text content is still valuable: it improves accessibility, gives mail clients a fallback, and makes the message understandable where HTML is disabled.

Configure JivoChat without exposing credentials

Create an HTTPS endpoint first, deploy it, and verify that it can accept a JSON POST. Then register that endpoint as the destination for JivoChat’s chat_finished webhook using JivoChat’s webhook configuration. Use a non-production endpoint while testing if your environment supports it.

The URL itself should be difficult to guess, but obscurity is not authentication. If JivoChat offers a webhook secret, signature, or verification mechanism for your account, enable it and validate it before parsing or acting on the event. Store the verification secret as JIVOCHAT_WEBHOOK_SECRET in the same protected server environment as your other backend secrets.

If the webhook setup cannot provide request signing, use compensating controls: a high-entropy unguessable route, network controls where available, rate limits, strict schema validation, and deduplication. Do not accept arbitrary event bodies and immediately turn them into mail.

The Volanea API key belongs only in the relay’s protected runtime configuration. Never put it in:

  • JavaScript delivered to the browser;
  • the JivoChat widget code snippet;
  • a public Git repository or example .env file;
  • a client-side mobile app;
  • a webhook URL query string;
  • a CRM note, ticket, or chat transcript.

Rotate the key immediately if it is ever committed, pasted into a ticket, or visible in browser developer tools. Restrict access to the secret at the deployment-platform level, and use separate keys for development and production when your account configuration permits it.

Make the email useful, not merely automated

A good post-chat message confirms a next step. It should answer the question the recipient is likely to have after the window closes: what happens now, who owns the request, and how can they continue the conversation?

For example, a support team might send: “We received your request. Morgan will follow up within one business day. Reply here with screenshots or order details.” A sales team might send a requested guide, a calendar link, or a recap of a stated next step. An internal notification might go to a shared support mailbox when a chat contains a flagged intent.

Avoid automatically emailing the full chat transcript unless you have deliberately assessed privacy, retention, and consent. Transcripts can contain order numbers, contact data, account details, or sensitive information that a customer did not expect to receive in an unencrypted inbox. A short summary and a reply path are often safer.

Use a verified From address on a domain your organization controls. Keep the recipient experience coherent: if the chat is branded as support, send from a support address; if agents promise that replies reach the team, configure a monitored Reply-To or inbox workflow. Authentication records such as SPF, DKIM, and DMARC are foundational to delivery and brand trust, not optional cleanup work after launch.

Idempotency and duplicate-send protection

Webhook delivery is generally at-least-once, not exactly-once. That means a sender may retry an event if it does not receive a timely successful response, if there is a network interruption, or if your service returns an error after completing part of its work. The result can be two or more deliveries of the same chat_finished event.

Your application must make the send idempotent. In this integration, the natural key is the JivoChat chat_id paired with the event type. Save a record such as chat_finished:987654321 before or alongside the provider call, with states like processing, sent, and failed.

A production-grade approach is:

  1. Begin a database transaction and insert the event key with a unique constraint.
  2. If the key already exists as sent, return HTTP 200 without sending again.
  3. If it is new, create an outbox job containing the recipient and message data.
  4. Commit the transaction quickly and return success to JivoChat.
  5. Let a worker send the outbox job to Volanea with the same idempotency key.
  6. Mark the job sent only after Volanea confirms acceptance.

The Idempotency-Key header in the example adds a second layer of protection at the provider request boundary. Your own database remains essential because it governs your business rule: one follow-up per completed chat, irrespective of retry timing or deployment restarts.

When this breaks

The fragile part of this integration is the hop between JivoChat, your endpoint, and Volanea. Plan for failure modes rather than assuming a webhook is a guaranteed single delivery.

JivoChat retries cause duplicate sends

If your endpoint times out or returns a non-success status after Volanea has accepted the email, JivoChat may retry the chat_finished webhook. Without an event key, the recipient receives duplicate follow-ups. This is why chat_id must be persisted as a unique idempotency record and why the Volanea request should carry a stable idempotency key.

Do not solve this by returning 200 before storing anything. That prevents retries but can silently lose emails when your process fails immediately afterward. Use an outbox or queue when email delivery matters, and monitor jobs stuck in processing.

The webhook request times out

A webhook sender expects a prompt response. Slow database queries, synchronous template rendering, DNS delays, or a slow provider request can exceed its timeout. Keep the synchronous receiver small: validate, deduplicate, enqueue, and acknowledge. Perform the email API call in a background worker when your platform supports it.

If you do call Volanea synchronously, set a short outbound timeout, log the failure, and return a retryable response only when it is safe for JivoChat to retry. The safer long-term pattern remains acknowledgment plus an internally retried job.

Some payload fields are absent

Not every JivoChat conversation has client.email, client.name, agent metadata, or the same channel fields. Availability can vary by visitor behavior, connected channel, feature access, and plan. Write optional chaining and fallback copy from the start; never assume a website-chat payload represents every channel.

Most importantly, missing email is not an error to repair with a guess. Record skipped_no_valid_email, then let the team continue through the channel where the conversation occurred. If collecting email is essential to your workflow, configure an appropriate pre-chat or lead-collection process and explain why you are asking.

Volanea rejects the message

A 4xx response often indicates a correctable request issue: an unverified sender, malformed recipient, invalid content field, or missing authentication. A 5xx response and network errors are usually retry candidates. Log the provider status code, response body, chat ID, and a redacted recipient identifier; do not log the API key or full transcript.

Before blaming the API, confirm that your From domain is authenticated and that the recipient is eligible to receive the message. For address quality checks before a non-essential follow-up, a free address verification tool can help identify obvious invalid addresses, but it does not replace consent or bounce handling.

Testing the full path safely

Use a controlled test chat and an inbox you own. Verify each boundary separately before enabling live notifications.

First, send a fixture payload to your relay with curl or a test client. Confirm the validation outcome, the generated text and HTML, and the database event key. Next, test a real JivoChat chat that includes an email address and ends normally. Finally, test a chat without an email, a repeated delivery of the same payload, and a Volanea failure simulation.

Your test checklist should include:

  • a valid chat_finished event with a known email address;
  • an event missing client.email that produces no email;
  • two identical deliveries that result in one send;
  • unusual names containing <, &, quotes, and emoji;
  • a provider timeout or temporary failure;
  • an unverified or incorrect From address in a non-production environment;
  • a reply to the delivered message reaching a monitored destination.

Add structured logging from day one. Useful fields include an internal request ID, webhook event name, chat ID, decision state, provider message ID if returned, latency, and error category. Hash or redact recipient addresses in general logs. That gives support staff enough evidence to answer “did we send it?” without turning logs into an uncontrolled copy of customer data.

Alternatives when a webhook relay is not the right fit

A custom relay is usually the most controllable choice because it owns security, rules, and idempotency. But it is not the only pattern.

A workflow platform can receive a JivoChat event, filter it, and call an HTTP endpoint or an email provider action. This can be useful for a prototype or for teams without backend deployment capacity. The tradeoff is less control over retries, event persistence, sensitive fields, and how credentials are stored. Review the workflow platform’s data retention, error handling, and secret-management model before passing customer chat data through it.

A CRM-first workflow is another option. JivoChat can feed leads or conversations into the CRM; the CRM then decides whether and when to trigger the email. This is useful when the CRM is the system of record for consent, lifecycle stage, account ownership, and suppression status. It can also prevent a chat follow-up from colliding with an existing support case or sales sequence.

If you need real-time chat replies rather than email, keep that work in JivoChat’s chat and agent workflows. Email is asynchronous. The integration described here is for a post-conversation message, not for replacing the live-chat channel.

Operational and deliverability considerations

Transactional automation has a direct effect on sender reputation. A sudden spike in post-chat email volume, a high unknown-user rate, or a confusing message can lead to complaints and poor engagement. Start with a limited use case, measure the results, and expand only after the content and targeting prove useful.

Separate event types conceptually even if they share infrastructure. A “your support case is open” message, a requested document, and a promotional nurture email should have different eligibility rules, templates, and suppression handling. This makes auditing easier and avoids accidentally treating a service event as blanket marketing permission.

Monitor more than API success. A 202-style acceptance response means the provider accepted your request; it does not guarantee inbox placement or a human response. Track sends, deliveries, bounces, complaints where available, replies, and the actual business outcome: resolved tickets, booked meetings, or fewer repeat contacts.

Finally, establish ownership. Support should own copy and response expectations; engineering should own endpoint reliability and secret rotation; marketing or compliance should own consent rules for non-transactional content. The best integration is not merely one that sends—it is one whose messages are expected, useful, authenticated, and supportable.

Conclusion

To send email from JivoChat with Volanea reliably, use JivoChat’s chat_finished webhook as the event source and a secure server-side relay as the control point. Map only the fields you need, especially event_data.client.email and event_data.chat_id; keep the Volanea API key exclusively in server-side secrets; and treat duplicate delivery and missing fields as normal operating conditions.

Start with one concise, clearly transactional follow-up. Add persistent idempotency, durable job handling, sender authentication, and observability before expanding the workflow. That foundation lets your team automate the useful next step after a conversation without compromising credentials, customer expectations, or deliverability.

FAQ

Can I install Volanea directly from the JivoChat marketplace?

No. This setup does not rely on a native Volanea JivoChat marketplace app. It uses JivoChat’s webhook event delivery and a server-side endpoint that calls Volanea’s REST API.

Which JivoChat event should trigger the email?

Use chat_finished for a post-conversation follow-up. It provides a clear end-of-chat boundary and avoids sending an email for every message exchanged during an active conversation.

Where should I keep the Volanea API key?

Keep it in a protected server-side secret or environment variable used only by your relay or background worker. Never place it in widget code, browser JavaScript, a webhook URL, or any client-visible configuration.

What if JivoChat does not provide the visitor’s email address?

Do not send the customer email. Record a skipped outcome and continue through the original chat channel, or collect an email through an appropriate consent-aware process.

How do I stop duplicate emails after webhook retries?

Persist a unique key based on chat_finished and JivoChat’s chat_id, and use it to ensure one message per completed chat. Use the same stable key as the Volanea request idempotency key where supported.