Send email from CallHippo when a call ends, is missed, or reaches another meaningful status by using CallHippo’s Custom Webhook feature as the trigger and a small server-side relay to call Volanea’s REST API. This is not a native CallHippo app or marketplace installation: CallHippo sends call-event JSON to your endpoint, and your endpoint decides whether to send an email through Volanea.
CallHippo documents custom webhooks for pushing call data, events, and activities to another application in real time. Its Custom Webhook documentation specifically calls the relevant trigger Call Status notification: when enabled, CallHippo syncs call events to the configured webhook URL by HTTP POST in JSON format. (callhippo.ladesk.com)
That makes this integration useful for operational email, not bulk marketing. For example, you can email a manager when a VIP caller is missed, send a recap request to an agent after a completed support call, or notify an internal queue when an inbound call is abandoned. The important architecture decision is to keep Volanea’s secret API key in your own server environment—not inside a browser, public webhook URL, or client-visible CallHippo configuration.
What this integration does—and does not do
There is no native Volanea listing, plug-in, or one-click CallHippo marketplace app to install. Instead, this is a direct webhook-to-server-to-email workflow:
- A call changes state in CallHippo.
- CallHippo posts a JSON notification to a URL you control.
- Your server validates and normalizes that event.
- Your server decides whether this particular call merits an email.
- Your server calls
POST https://api.volanea.com/v1/sendwith a Volanea secret key. - Volanea accepts the message for its transactional delivery pipeline.
CallHippo describes webhooks as real-time notifications for events such as new calls, missed calls, call endings, and voicemail activity. The event details can include caller information, duration, and call status. (help.callhippo.com) Volanea’s POST /v1/send endpoint is intended for sending an individual message to one recipient or up to 50 recipients, and supports an Idempotency-Key header for retry-safe requests. (volanea.com)
The relay is not optional merely because it is convenient. It is the security boundary. CallHippo can deliver an outbound webhook, but a webhook destination is not a safe place to expose the secret that authorizes your email account. Your endpoint also gives you a durable place to apply business rules, validate payloads, redact sensitive call notes, deduplicate repeated deliveries, and record an audit trail.
The concrete CallHippo trigger: Call Status notification
The CallHippo-side trigger for this integration is Call Status notification in the Custom Webhook configuration. CallHippo says that enabling this option sends all call events to the configured webhook URL. It separately describes Call Notify as available on request and associated with predictive dialing, so do not choose Call Notify for a general post-call email workflow unless CallHippo has explicitly enabled that product capability for your account. (callhippo.ladesk.com)
For most teams, the best first rule is not “send on every call event.” A single call can produce multiple status transitions, and a customer does not need several emails because a call rang, connected, and ended. Trigger the email only after your relay sees the terminal or actionable status you care about.
Good trigger rules
Use an explicit allowlist. Examples include:
- A missed inbound call from a known customer number, which sends an internal follow-up alert.
- A completed inbound call over a defined duration threshold, which sends a case-recap request to the assigned team.
- A completed outbound call with a workflow-specific result, where your system has additional context about the contact or opportunity.
- A voicemail-related event, where an internal notification can link the team to CallHippo’s activity record rather than attaching or forwarding sensitive audio automatically.
Avoid using a call status event as permission to send promotional email to the caller. A phone call does not automatically establish consent for unrelated marketing email. Keep this workflow transactional or operational unless your own consent records and policies support a different use.
Configure the CallHippo destination
In CallHippo, create a Custom Webhook and provide a publicly reachable HTTPS endpoint that you operate, such as:
https://hooks.example.com/callhippo/call-status
Enable Call Status notification for that endpoint. CallHippo’s help material describes the feature as a way to send call data, events, and activities to a third-party system or internal application in real time. (help.callhippo.com)
Use a production hostname with TLS. Do not use a browser route, a local localhost address, or a URL that forwards directly to the Volanea API. Your receiver should return a fast success response after it has safely persisted or queued the event; it should not make CallHippo wait for template rendering, external CRM lookups, or a slow email-provider response.
Understand the CallHippo payload before mapping it
CallHippo’s Custom Webhook delivery is an HTTP POST with JSON. The public help material confirms Call Status notification delivers call-event notifications by POST in JSON and identifies caller details, duration, and status as relevant event data. (callhippo.ladesk.com)
Your exact account payload should be captured from a real test call before you put the integration into production. This matters because telephony data is often conditional: a caller name may be unavailable, duration may only be meaningful once a call has ended, and contact email is not generally a field that can be inferred from a phone call. The email recipient in this example is therefore an internal operations address, not the phone caller.
Below is the practical Call Status notification shape the relay expects. The key fields are the stable call identifier, call direction, status, caller or contact identifier, destination number, and timing or duration information. Preserve the full original JSON in logs or a database during testing so you can compare it with your account’s actual delivery.
{
"call_id": "ch_call_01JQ8N7M4K4X9A2P",
"call_type": "Incoming",
"call_status": "Completed",
"from": "+14155550123",
"to": "+14155550999",
"caller_name": "Avery Chen",
"duration": 184,
"start_time": "2026-10-01T15:04:10Z",
"end_time": "2026-10-01T15:07:14Z",
"agent_name": "Jordan Lee"
}
Treat that body as event data, not as trusted instructions. In particular:
- Do not use
caller_nameas unescaped HTML. Names can contain characters that change markup. - Do not assume an email address exists in the event. CallHippo is a voice platform; resolve customer email only through your own CRM or contact database when your use case requires it.
- Do not use a mutable display name as your deduplication key. Use the call identifier plus the event type or status.
- Do not derive the Volanea
fromaddress from CallHippo’stonumber. Your sender must be an email address on a domain configured for your Volanea project.
If your event uses different property names, update the normalization block once and keep the rest of the sending code unchanged. This is safer than spreading raw CallHippo field references through every email template and condition.
Build the secure webhook relay
The following Node.js example receives CallHippo Call Status notification deliveries, normalizes the fields above, sends an internal alert only for missed or completed inbound calls, and then calls Volanea. It also creates a deterministic idempotency key so that retried CallHippo deliveries do not create duplicate messages.
import express from "express";
import crypto from "node:crypto";
const app = express();
app.use(express.json({ limit: "256kb" }));
const {
VOLANEA_API_KEY,
EMAIL_FROM,
OPERATIONS_EMAIL,
CALLHIPPO_WEBHOOK_TOKEN
} = process.env;
function escapeHtml(value = "") {
return String(value)
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll('"', """)
.replaceAll("'", "'");
}
function normalizeCallHippoEvent(body) {
return {
callId: body.call_id,
type: body.call_type,
status: body.call_status,
from: body.from,
to: body.to,
callerName: body.caller_name || "Unknown caller",
durationSeconds: Number(body.duration || 0),
startedAt: body.start_time || null,
endedAt: body.end_time || null,
agentName: body.agent_name || "Unassigned"
};
}
function shouldNotify(call) {
const direction = String(call.type || "").toLowerCase();
const status = String(call.status || "").toLowerCase();
return (
direction === "incoming" &&
(status === "missed" || status === "completed")
);
}
app.post("/callhippo/call-status", async (req, res) => {
// Use an unguessable secret in the destination URL or another
// CallHippo-supported authentication control available to your account.
if (req.query.token !== CALLHIPPO_WEBHOOK_TOKEN) {
return res.status(401).json({ error: "Unauthorized webhook" });
}
const call = normalizeCallHippoEvent(req.body);
if (!call.callId || !call.status || !call.type) {
return res.status(400).json({ error: "Missing required call fields" });
}
// Acknowledge irrelevant events without sending mail.
if (!shouldNotify(call)) {
return res.status(204).end();
}
const idempotencyKey = crypto
.createHash("sha256")
.update(`callhippo:${call.callId}:${call.status}`)
.digest("hex");
const subject = `CallHippo ${call.status}: ${call.callerName}`;
const html = `
<h2>Call follow-up needed</h2>
<p><strong>Status:</strong> ${escapeHtml(call.status)}</p>
<p><strong>Caller:</strong> ${escapeHtml(call.callerName)}</p>
<p><strong>From:</strong> ${escapeHtml(call.from)}</p>
<p><strong>Called number:</strong> ${escapeHtml(call.to)}</p>
<p><strong>Agent:</strong> ${escapeHtml(call.agentName)}</p>
<p><strong>Duration:</strong> ${escapeHtml(call.durationSeconds)} seconds</p>
<p><strong>Call ID:</strong> ${escapeHtml(call.callId)}</p>
`;
const emailPayload = {
from: EMAIL_FROM,
to: [OPERATIONS_EMAIL],
subject,
html,
text: [
"Call follow-up needed",
`Status: ${call.status}`,
`Caller: ${call.callerName}`,
`From: ${call.from}`,
`Called number: ${call.to}`,
`Agent: ${call.agentName}`,
`Duration: ${call.durationSeconds} seconds`,
`Call ID: ${call.callId}`
].join("\n")
};
try {
const response = 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(emailPayload)
});
const result = await response.json();
if (!response.ok) {
console.error("Volanea send failed", response.status, result);
return res.status(502).json({ error: "Email send failed" });
}
console.log("Volanea email accepted", {
callId: call.callId,
status: call.status,
result
});
return res.status(202).json({ accepted: true });
} catch (error) {
console.error("Volanea request error", error);
return res.status(502).json({ error: "Email provider unavailable" });
}
});
app.listen(3000, () => {
console.log("Listening on port 3000");
});
The Volanea request uses the documented base URL, Bearer authorization, POST /v1/send, and Idempotency-Key pattern. Volanea’s documentation identifies secret keys in the sk_… or sk_test_… form and describes the send endpoint as handling the transactional pipeline, including suppression checks and dispatch. (volanea.com) For the full request and response contract, consult the email API reference and setup guides.
Field mapping: CallHippo call data to Volanea email data
The mapping should be deliberate. CallHippo tells you what happened on a call; Volanea needs a valid sender, recipient, subject, and content. These are different domains, so not every value should cross the boundary.
| CallHippo field | Normalized field | Volanea use | Why it matters |
|---|---|---|---|
call_id | callId | Idempotency-Key input and email body | Identifies one logical call event and makes debugging possible. |
call_status | status | Subject, condition logic, email body | Determines whether an email should exist at all. |
call_type | type | Condition logic | Lets you distinguish incoming support calls from outbound sales calls. |
from | from | Email body | Shows the caller or external number. It is not the email sender. |
to | to | Email body | Shows the CallHippo number contacted. It is not the email recipient. |
caller_name | callerName | Escaped subject and body | Helpful context, but optional and untrusted text. |
duration | durationSeconds | Body and condition logic | Helps prioritize a long completed call over a short abandoned call. |
agent_name | agentName | Body | Helps route an internal follow-up. |
| Your environment variable | EMAIL_FROM | Volanea from | Must be a sending identity configured for Volanea. |
| Your CRM or routing rule | OPERATIONS_EMAIL | Volanea to | Determines the actual recipient of the alert. |
The separation between from in the webhook and from in the email API is especially important. In CallHippo, from is telephone context. In Volanea, from is the email sender identity. Never copy a telephone number into the email API’s sender field.
Keep the Volanea API key out of CallHippo and the browser
The Volanea API key belongs in your relay’s secret store or server-side environment variable, for example VOLANEA_API_KEY. It should never be embedded in a public JavaScript bundle, a CallHippo workflow description, a client-side integration, a query string, or an email template.
Volanea’s own implementation guidance for server-side integrations uses an environment variable for the API key and explicitly warns against exposing it to client code. (volanea.com) That is because a secret key authorizes sends under your Volanea project. Anyone who obtains it can potentially send email as your configured account, consume your quota, and damage your domain reputation.
Where each secret belongs
- Volanea API key: Server environment variable, cloud secret manager, or encrypted function secret.
- CallHippo destination token: A separate random secret used to protect your inbound webhook route, ideally stored as an environment variable and compared server-side.
- CallHippo REST API key: Only needed if your middleware calls CallHippo’s REST API for enrichment or reconciliation. It is not required merely to receive a Custom Webhook.
- Email sender address: Environment configuration such as
EMAIL_FROM=Support Alerts <alerts@example.com>after the sending domain is configured in Volanea.
A URL token is a basic shared-secret control, not a replacement for signed webhooks if your CallHippo account provides a verified signing mechanism. Check the current Custom Webhook controls in your CallHippo account before launch. If request signing is available, validate the signature against the raw request body before parsing or acting on it. If it is not available, use a high-entropy unguessable endpoint token, IP or network controls where feasible, rate limits, payload validation, and an internal queue.
Add routing and customer context carefully
The example sends to a fixed internal operations inbox because call notifications reliably contain call context, not necessarily customer email addresses. If you want to send a follow-up to the caller, add a lookup step based on the normalized phone number.
For example, your relay can normalize +14155550123, look up a matching CRM contact, verify that the CRM record has a usable email address and the appropriate communication status, and then use that CRM email as Volanea’s to recipient. Do not guess an address from a name, do not treat caller ID as proof of ownership, and do not turn an unknown incoming caller into a marketing recipient.
A safer conditional flow looks like this:
- Receive the Call Status notification.
- Confirm it is an inbound, completed or missed event you care about.
- Deduplicate by call ID and status.
- Look up the normalized calling number in your CRM.
- Decide whether the action is internal-only or customer-facing.
- If customer-facing, require a valid email and the right consent or transactional basis.
- Send a concise, relevant message through Volanea.
- Save the Volanea message identifier and call ID together for later support investigations.
Before a customer-facing send, you may also validate an address at the point of capture with the free email address verification tool. Address validation is useful for reducing obvious errors, but it does not replace consent, suppression handling, or a clear transactional reason for the email.
When this breaks: failures specific to the CallHippo-to-email hop
Webhook automation is a distributed system. The same event can arrive more than once, an event can arrive without all optional fields, or CallHippo can be waiting for your endpoint while your endpoint is waiting for another service. Design for those conditions before they become customer-facing duplicates.
CallHippo retries create duplicate sends
A delivery can be repeated when CallHippo does not receive a timely successful response, when a network connection fails after your server has already started work, or when an operator replays a workflow manually. If every received webhook immediately produces a new POST /v1/send, recipients can receive duplicate alerts.
Use two layers of protection:
- Your own durable event ledger. Store a uniqueness key such as
callhippo:<call_id>:<call_status>before sending. Make the database write atomic. - Volanea idempotency. Send the same logical key in the
Idempotency-Keyheader every time you retry the same email request.
Volanea documents safe retries through Idempotency-Key, which is precisely the protection needed when the caller cannot tell whether a timed-out POST was processed. (volanea.com) Do not use a randomly generated key for every retry; that would turn retries back into new sends.
Your endpoint times out
Do not perform long work synchronously inside the webhook handler. A slow CRM lookup, report generation job, recording download, or third-party outage can cause CallHippo to consider delivery unsuccessful and attempt it again.
The production pattern is:
- Validate the inbound request.
- Write the raw event and dedupe key to durable storage or enqueue a job.
- Return a successful response quickly.
- Let a worker perform CRM enrichment and the Volanea send.
The worker can retry transient failures with the same Volanea idempotency key. If you use a queue, make the queue job ID or the call ID plus status part of the deduplication strategy. Do not rely on process memory, because a server restart erases it.
Optional payload fields are missing
Caller names, agents, durations, timestamps, recordings, and notes can be conditional. A missed call may have no connected-agent data. A newly created event may not yet have an end time. A blocked caller ID may leave from incomplete. Some CallHippo features also vary by account capability; for example, Call Notify is described as available on request and tied to predictive dialing. (callhippo.ladesk.com)
Make required and optional fields explicit. In the example, call_id, call_status, and call_type are required to make a routing decision. caller_name, agent_name, and timing fields get safe fallbacks. If a field is necessary for a particular workflow—such as a CRM contact ID for a customer follow-up—stop the send and put the event into a review queue rather than manufacturing a value.
The same call produces several status transitions
Call Status notification is intentionally broad: it can sync all call events to your webhook URL. That is useful for analytics, but it means “received a webhook” is not synonymous with “send an email now.” (callhippo.ladesk.com)
Keep the trigger filter close to the top of your worker. Decide whether you want only Missed, only Completed, or a precise combination of direction and status. If your payload exposes status labels with different capitalization or naming, normalize them to lowercase before comparison. Log unknown statuses and review them rather than accidentally treating all unknown events as actionable.
A webhook request is forged or malformed
Your endpoint is internet-facing. Reject unexpected methods, content types, oversized bodies, missing core fields, and requests that fail your endpoint-secret or signature verification. Escape every webhook-derived value before inserting it into HTML. Never log the Volanea API key, and minimize logging of call notes, recording URLs, and caller numbers.
For higher-sensitivity teams, store only the fields needed to trigger and audit the email. Link to the authorized CallHippo activity in an internal system rather than copying transcripts or recordings into email, where forwarding and retention become harder to control.
Test the workflow with real call scenarios
A production-quality test is more than a successful API response. Place calls that generate the exact states and missing-field conditions your team expects, then inspect both your webhook logs and Volanea email events.
Use this test matrix:
- Answered inbound call: Confirm your completed-call rule sends exactly one internal email.
- Missed inbound call: Confirm the alert contains a sensible fallback when no agent or duration exists.
- Outbound completed call: Confirm it is ignored if your rule is inbound-only.
- Duplicate delivery simulation: Send the same captured body twice and confirm one logical email is created.
- Malformed body: Remove
call_idand confirm the relay rejects it without attempting a Volanea request. - Volanea temporary failure: Simulate a network failure, retry with the same idempotency key, and confirm the retry does not create a second email.
- Unknown caller: Confirm the workflow does not invent a customer email address.
Record correlation data at each stage: received webhook timestamp, call ID, normalized status, dedupe key, queue job ID, Volanea response data, and the chosen recipient. This lets support staff answer the three questions that matter after an incident: Did CallHippo send the event? Did our service decide to send? Did Volanea accept the message?
Direct webhook relay versus Zapier or Make
CallHippo supports Custom Webhooks and also documents a Zapier integration. (help.callhippo.com) A direct relay is the better choice when you need secure server-side secrets, custom filtering, deterministic idempotency, CRM lookups, audit data, or precise retry behavior.
Zapier or Make can be useful when the workflow is simple and an operations team needs to own it without deploying code. However, do not expose a Volanea secret in any client-visible form, and confirm how the automation platform stores connection credentials, retries failed HTTP steps, represents the CallHippo trigger data, and handles duplicate task execution before using it for customer-facing email.
A practical hybrid approach is to have CallHippo post to your relay first, validate and deduplicate the call event there, and then enqueue an approved automation event to your preferred workflow tool. That keeps the inbound trust boundary and Volanea API key under your control while allowing non-engineering teams to manage downstream routing.
Operational checklist before you switch it on
Before enabling Call Status notification in production, verify the following:
- Your CallHippo Custom Webhook points to an HTTPS endpoint you own.
- The webhook receiver authenticates or otherwise protects inbound requests.
- You have captured real account payloads for completed, missed, inbound, and outbound calls.
- Your code requires a stable call identifier and has safe fallbacks for optional fields.
- Your business logic sends only for selected statuses and directions.
- Your Volanea API key is stored in a server-side secret manager or environment variable.
- Your Volanea sender identity uses a domain configured for that project.
- Every logical send has a deterministic
Idempotency-Key. - You persist a call-event ledger or queue job before acknowledging the webhook.
- You have a way to correlate CallHippo call IDs with Volanea send results.
- You have tested duplicate events, missing fields, rejected requests, and temporary provider failures.
Conclusion
To send email from CallHippo with Volanea, use CallHippo’s Call Status notification Custom Webhook as the event source and put a small, secure service between CallHippo and Volanea. That relay turns telephony event data into a carefully scoped email request, keeps the Volanea secret key private, and gives you the controls that a direct point-to-point webhook cannot provide.
The reliable version of this integration is intentionally conservative: send only after selected call states, use a stable call ID to deduplicate, acknowledge webhooks quickly, preserve data for troubleshooting, and treat phone-event data as context rather than automatic permission for customer marketing. With those controls in place, a missed call or completed conversation can become a useful, timely email workflow without creating a duplicate-send or credential-exposure problem.
FAQ
Can I install a Volanea app from the CallHippo marketplace?
No. This workflow does not depend on a native CallHippo marketplace app or plug-in. It uses CallHippo Custom Webhooks to post call-event JSON to a server you operate, which then calls Volanea’s REST API.
What exactly triggers the email in CallHippo?
The CallHippo trigger is Call Status notification in Custom Webhook settings. It sends call events to your configured webhook URL. Your relay then filters for the statuses you consider actionable, such as a missed or completed inbound call. (callhippo.ladesk.com)
Should I put the Volanea API key in CallHippo?
No. Store the Volanea secret key only in server-side environment configuration or a secret manager used by your webhook relay. Never expose it in browser code, a public URL, or a client-visible configuration.
How do I stop duplicate call-alert emails?
Deduplicate using a stable value such as the CallHippo call ID plus status, persist that key in your own database or queue, and use the same value in Volanea’s Idempotency-Key header whenever retrying the same logical send. (volanea.com)
Can I email the caller directly after a CallHippo event?
Only if your own CRM or contact system can safely map the caller’s phone number to a verified email address and your message has the appropriate transactional purpose or consent basis. A CallHippo call event alone does not provide a reliable email address or blanket marketing permission.