Send email from Pipedrive without treating your CRM as an email delivery platform: use a Pipedrive webhook to detect a qualifying deal-stage change, then let secure middleware call Volanea’s email API. This approach is flexible enough for deal notifications, onboarding messages, document follow-ups, and internal alerts while keeping delivery credentials out of the browser and out of CRM fields.

Pipedrive does not need a native Volanea marketplace app for this workflow. Its webhook capability can publish CRM events to an HTTPS endpoint you control. That endpoint is where you apply business rules, fetch any missing contact data, prevent duplicate sends, render a message, and make the authenticated request to Volanea.

The distinction matters. A Pipedrive webhook is an event notification, not an email-template engine and not a safe place to expose a sending key. Build the small layer between the two systems deliberately and you get an integration that is easier to audit, test, and extend.

What this Pipedrive-to-Volanea integration does

This guide uses one precise event: a deal is updated and its stage changes. In Pipedrive’s webhook event naming, that is the updated.deal event. The webhook fires for deal updates generally, so your receiver compares the previous.stage_id value with current.stage_id and sends only when the deal reaches the stage you have chosen.

For example, a sales team could use a stage named “Proposal sent.” When a representative moves a deal into that stage, the integration can send the associated person a message containing a proposal link. Another team may use “Won” to deliver a welcome email or “Waiting for customer” to send a reminder.

The end-to-end flow is:

  1. A Pipedrive user changes a deal’s pipeline stage.
  2. Pipedrive sends an updated.deal webhook to your HTTPS endpoint.
  3. Your endpoint confirms that stage_id changed and that the new stage is the one that should trigger mail.
  4. The endpoint gets the primary email address for the deal’s linked person when it is not already safely available in the event data.
  5. The endpoint builds a Volanea send request and submits it with a server-side API key.
  6. The endpoint records an idempotency key so a retried Pipedrive webhook does not create another email.

That sequence works for transactional messages because the message is connected to a meaningful CRM event. It is not a substitute for consent management or a reason to turn every deal edit into marketing automation. If you want to use deal data for campaign audiences, define the consent and suppression rules first, then separate campaign logic from operational messages.

Why a webhook needs middleware

Pipedrive can deliver outbound webhooks, but a webhook subscription does not transform a Pipedrive event into a custom Volanea email request. The JSON Pipedrive sends has its own envelope and resource format. Volanea’s sending endpoint needs a recipient, sender, subject, and content in its own request format.

Middleware is the adapter between those formats. It can be a small Node.js service, a serverless function, a Cloudflare Worker, AWS Lambda, Google Cloud Function, or an endpoint in your existing application. The implementation can be modest, but it has several responsibilities that should not be skipped:

  • validate that the request is genuinely from the route you configured and reject arbitrary callers;
  • identify the event and discard unrelated deal updates;
  • compare previous and current values rather than assuming every update is a stage transition;
  • retrieve the linked person’s email address if the webhook does not contain a usable address;
  • apply recipient, consent, and suppression checks;
  • call Volanea with credentials stored in a server-side secret store;
  • make retries safe through idempotency and persistent logging.

This is also why a direct browser-side request is the wrong architecture. A frontend application would expose the Volanea API key to users, browser extensions, network logs, and anyone who can inspect deployed JavaScript. A Pipedrive custom field is not an appropriate secret store either: CRM access is generally broader than production email-infrastructure access, and field history can make a leaked key hard to fully contain.

For the sending request’s accepted fields, authentication model, and current endpoint details, use Volanea’s email API reference and setup guides. Keep the API contract in one function in your middleware so future template or provider changes remain localized.

Configure the Pipedrive trigger

Create a Pipedrive webhook subscription for deal updates and point its subscription URL at a public HTTPS route, such as:

https://hooks.example.com/pipedrive/deal-stage-email

Select the deal object and update action. In Pipedrive’s event vocabulary, the event received by the endpoint is updated.deal. Pipedrive also has events such as added.deal; do not subscribe to added.deal for this particular workflow unless a newly created deal should immediately trigger the same message.

The actual stage test belongs in middleware because the webhook is sent when a deal is updated, not solely when it crosses one particular pipeline stage. A deal owner change, title edit, expected-close-date revision, or custom-field update may all be updates. Comparing previous.stage_id to current.stage_id is what makes the trigger specific.

Decide the stage identifier before deploying

Use the numeric Pipedrive stage ID in code or configuration, not a stage name. A display name can be edited, localized, or duplicated across pipelines. A stage ID is the stable value Pipedrive sends in the deal record.

Set the expected stage as a server environment variable, for example:

PIPEDRIVE_TRIGGER_STAGE_ID=12

Before enabling email, send a test deal through the pipeline and log only the event metadata and stage IDs. Confirm that the stage you selected is the stage received by the webhook. This avoids the common mistake of using a pipeline ID where a stage ID is required.

Use a dedicated webhook route

Do not reuse a generic /webhook endpoint shared by unrelated systems without clear routing and authentication controls. A dedicated route makes it easier to set request limits, inspect failures, rotate access controls, and revoke the integration if necessary.

Pipedrive supports webhook subscriptions through its API and webhook settings depend on the account and API setup. Treat the subscription URL as infrastructure configuration. Use HTTPS, avoid putting credentials or API keys in a query string, and restrict the endpoint to the minimum events it requires.

Understand the Pipedrive webhook payload

A Pipedrive webhook is an event envelope. For an updated deal, the important top-level parts are event, meta, current, and previous. current is the post-update representation; previous contains values from before the update that are useful for detecting what changed.

A representative updated.deal payload has this shape. IDs, timestamps, and optional fields will differ in a real account, and Pipedrive can include additional properties.

{
  "v": 1,
  "event": "updated.deal",
  "retry": 0,
  "meta": {
    "v": 1,
    "action": "updated",
    "object": "deal",
    "id": 481,
    "company_id": 9001,
    "user_id": 44,
    "host": "acme.pipedrive.com",
    "timestamp": 1720000000,
    "timestamp_micro": 1720000000123456,
    "permitted_user_ids": [44]
  },
  "current": {
    "id": 481,
    "title": "Acme proposal",
    "value": 12000,
    "currency": "USD",
    "stage_id": 12,
    "pipeline_id": 3,
    "person_id": 195,
    "org_id": 61,
    "owner_id": 44,
    "status": "open"
  },
  "previous": {
    "stage_id": 9
  }
}

The important mapping in this example is not speculative: current.id is the deal identifier, current.person_id identifies the linked Pipedrive person, and the difference between previous.stage_id and current.stage_id identifies the stage change. Do not assume that every optional contact, custom, form, or add-on-specific field will be present in every event.

If your email requires a custom deal property, identify its API field key from Pipedrive’s field metadata rather than using the label visible to sales users. Labels are human-facing and mutable; API keys are the appropriate integration contract. Also test payloads generated by deals created manually, imported in bulk, created through forms, and updated by automations. Those routes can produce different data completeness and timing.

Field mapping: deal event to email message

For a proposal email, a useful mapping might be:

Pipedrive sourceMiddleware useVolanea message field
current.idCreates a traceable event key and proposal URLmetadata / idempotency record
current.titlePersonalizes the subject and bodysubject, html, text
current.value and current.currencyShows the quoted value when appropriatehtml, text
current.person_idFetches the linked person’s primary emailrecipient
Person nameGreets the contacthtml, text
Person primary email[].valueReceives the messagerecipient
configured sender addressEstablishes the authenticated sendersender

A deal can exist without an associated person, and a person can exist without a usable email address. Those are ordinary CRM states, not exceptional programming bugs. Your handler should return a successful no-send outcome for them, record why the message was skipped, and avoid attempting delivery to an empty or guessed address.

Likewise, do not make a recipient address out of a deal title, organization domain, or a custom field that has not been validated. If you collect addresses into Pipedrive through a form, validate them at capture time and recheck before important sends. Volanea provides a free email address verification tool for checking an address before you add it to a high-value workflow.

Working Node.js webhook handler and Volanea send call

The following Express example filters a real updated.deal envelope, checks that the deal entered the configured stage, retrieves the Pipedrive person, selects that person’s primary email, and posts a transactional email request to Volanea. It uses environment variables for all credentials and deployment-specific values.

import express from "express";

const app = express();
app.use(express.json({ limit: "256kb" }));

const {
  PIPEDRIVE_ACCESS_TOKEN,
  PIPEDRIVE_TRIGGER_STAGE_ID,
  VOLANEA_API_KEY,
  VOLANEA_FROM
} = process.env;

async function getPipedrivePerson(personId) {
  const response = await fetch(
    `https://api.pipedrive.com/v1/persons/${encodeURIComponent(personId)}`,
    {
      headers: {
        Authorization: `Bearer ${PIPEDRIVE_ACCESS_TOKEN}`,
        Accept: "application/json"
      }
    }
  );

  if (!response.ok) {
    throw new Error(`Pipedrive person lookup failed: ${response.status}`);
  }

  const payload = await response.json();
  return payload.data;
}

function primaryEmail(person) {
  const emails = Array.isArray(person.email) ? person.email : [];
  const primary = emails.find((item) => item.primary && item.value);
  return primary?.value || emails.find((item) => item.value)?.value || null;
}

async function sendWithVolanea({ to, subject, html, text }) {
  const response = await fetch("https://api.volanea.com/v1/emails", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${VOLANEA_API_KEY}`,
      "Content-Type": "application/json",
      Accept: "application/json"
    },
    body: JSON.stringify({
      from: VOLANEA_FROM,
      to: [to],
      subject,
      html,
      text
    })
  });

  if (!response.ok) {
    throw new Error(`Volanea send failed: ${response.status} ${await response.text()}`);
  }

  return response.json();
}

app.post("/pipedrive/deal-stage-email", async (req, res) => {
  const event = req.body;

  // Acknowledge non-target events without sending.
  if (event.event !== "updated.deal") {
    return res.sendStatus(204);
  }

  const deal = event.current;
  const previous = event.previous || {};
  const triggerStageId = Number(PIPEDRIVE_TRIGGER_STAGE_ID);

  // The concrete trigger: the deal entered the selected Pipedrive stage.
  if (
    !deal ||
    Number(deal.stage_id) !== triggerStageId ||
    Number(previous.stage_id) === Number(deal.stage_id)
  ) {
    return res.sendStatus(204);
  }

  // Persist this before sending in production. See idempotency section below.
  const idempotencyKey = `pipedrive:deal:${deal.id}:stage:${deal.stage_id}`;

  try {
    if (!deal.person_id) {
      console.info("Skipping deal without person", { dealId: deal.id, idempotencyKey });
      return res.sendStatus(204);
    }

    const person = await getPipedrivePerson(deal.person_id);
    const recipient = primaryEmail(person);
    if (!recipient) {
      console.info("Skipping person without email", { dealId: deal.id, personId: person.id });
      return res.sendStatus(204);
    }

    const amount = deal.value ? `${deal.value} ${deal.currency || ""}`.trim() : "your proposal";
    const name = person.name || "there";
    const proposalUrl = `https://app.example.com/proposals/${deal.id}`;

    const result = await sendWithVolanea({
      to: recipient,
      subject: `Your proposal: ${deal.title}`,
      text: `Hi ${name},\n\nYour proposal for ${amount} is ready: ${proposalUrl}\n\nRegards,\nThe team`,
      html: `<p>Hi ${escapeHtml(name)},</p><p>Your proposal for <strong>${escapeHtml(amount)}</strong> is ready.</p><p><a href="${proposalUrl}">View your proposal</a></p><p>Regards,<br>The team</p>`
    });

    console.info("Volanea message accepted", { dealId: deal.id, idempotencyKey, result });
    return res.sendStatus(202);
  } catch (error) {
    console.error(error);
    return res.sendStatus(500);
  }
});

function escapeHtml(value) {
  return String(value).replace(/[&<>'"]/g, (character) => ({
    "&": "&amp;", "<": "&lt;", ">": "&gt;", "'": "&#39;", "\"": "&quot;"
  }[character]));
}

app.listen(3000);

The escapeHtml call is intentional. CRM fields are user-entered data, and interpolating them into HTML without encoding can create malformed emails or injection issues. Keep text content alongside HTML too: it improves accessibility and provides a meaningful fallback for recipients whose clients do not render HTML.

Before production, replace the in-memory comment with a real database-backed idempotency record. Also verify the current Volanea endpoint and request schema in the API documentation for your account before deployment; API versions and available message fields can evolve.

Store and rotate credentials safely

There are two separate credential boundaries in this design.

First, Pipedrive must be able to reach your webhook route. Configure the route over HTTPS and apply the authentication or request-validation mechanism supported by your webhook subscription and infrastructure. Do not rely solely on an obscure URL path as authentication. At minimum, use a dedicated endpoint, rate limits, structured event logging, and a secret validation strategy appropriate to your deployment.

Second, the Volanea API key belongs only in the middleware runtime’s secret manager or encrypted environment configuration. Examples include a cloud secret manager, encrypted serverless environment variable, or deployment platform secret. It should not live in Pipedrive custom fields, a Pipedrive note, a browser environment variable, a client-side integration, source control, or a webhook URL.

Keep these values separate:

PIPEDRIVE_ACCESS_TOKEN=server-side OAuth access token
PIPEDRIVE_TRIGGER_STAGE_ID=12
VOLANEA_API_KEY=server-side Volanea credential
VOLANEA_FROM=Proposals <proposals@updates.example.com>

Use a Pipedrive OAuth token or other currently supported server-to-server authorization method with the smallest practical scope for reading persons and deals. Use a separate Volanea key for this integration rather than sharing a broad production key across unrelated applications. That makes rotation and incident response much less disruptive.

When this breaks: failure modes in this specific hop

A dependable integration assumes failures will happen. The risky boundary is not only the Volanea request; it is the complete Pipedrive webhook → middleware → person lookup → email API chain.

Pipedrive retries create duplicate email risk

If Pipedrive does not receive a timely successful HTTP response, it may retry webhook delivery. A timeout can happen after your middleware has already submitted the Volanea request but before it returned 202. Without idempotency, the retry can create a second email.

Create a durable unique record keyed by a business event, such as deal ID + destination stage ID, before sending. For workflows where a deal may legitimately re-enter the same stage later, use a more precise event occurrence key based on the event metadata and store its processing state. Your database transaction strategy should ensure that two concurrent deliveries cannot both claim the same send.

Webhook timeouts cascade into retries

Do not make the webhook request wait on slow work if your infrastructure cannot complete it quickly. Person lookups, template rendering, database calls, and email submission can add latency. A robust pattern is to validate and enqueue the event quickly, return success, and let a worker perform the lookup and send.

The queue worker still needs idempotency. A queue improves response time and retries, but it does not automatically make an external email send exactly once. Persist the event, claim it atomically, send, then store the provider response and final status.

Some expected fields are absent or inconsistent

Do not assume every Pipedrive deal event includes every business field your template wants. A deal may lack person_id; the person may have no email; custom fields may be unpopulated; an import can bypass assumptions made by a form; and features or fields associated with optional products are not a universal webhook contract across accounts and plans.

Write explicit no-send outcomes for missing recipient data and explicit fallback copy for nonessential values. If a proposal amount is required by policy, stop and create an internal task instead of sending a vague customer email. Observability should distinguish skipped_missing_person, skipped_missing_email, skipped_missing_required_field, duplicate, sent, and provider_failed.

Stage IDs change across environments

A sandbox or test company can have different pipeline and stage IDs than production even if the visible stage names match. Store IDs in environment-specific configuration. Add a startup check or deployment test that confirms the configured stage exists in the intended Pipedrive company.

A successful API response is not the final delivery outcome

A successful Volanea API response means the platform accepted the message for processing; it does not guarantee that every receiving mailbox accepted or displayed it. Monitor provider events, bounces, complaints, suppression decisions, and authentication status. Configure a domain you control with the required sending authentication records before using customer-facing mail.

Make the workflow operationally useful

The simplest email—“your deal changed”—is often not the best one. The value of the integration comes from using Pipedrive as the source of a real business transition while keeping email content and sending policy in your application layer.

For a proposal workflow, include a durable proposal URL rather than attaching a mutable CRM export. For onboarding after a won deal, pass the organization and selected product data to your own account-provisioning service, then send only when provisioning is complete. For an internal alert, use a shared operations mailbox or role address rather than emailing a customer.

Add these production controls:

  • a per-stage enable switch, so a campaign or process mistake does not require code deployment to stop sends;
  • template version metadata in logs, allowing support staff to identify what content a recipient received;
  • a dry-run mode that writes the rendered recipient and subject to logs but does not call Volanea;
  • a dead-letter queue for repeated lookup or send failures;
  • alerts for sudden increases in retries, skipped records, bounces, or complaint events;
  • a reconciliation job that compares qualifying stage transitions with successful sends.

Be cautious about the sender address. The address in VOLANEA_FROM should use a domain your team has configured and controls. Using a salesperson’s arbitrary address can undermine alignment, reply handling, and domain authentication. If replies should reach the deal owner, use a verified team sender and set an appropriate reply-to mechanism supported by your sending configuration.

Alternatives when you do not want to operate middleware

A no-code or low-code automation platform can act as middleware if it offers a Pipedrive trigger, a webhook or HTTP action, secure connection storage, and sufficient data transformation. The general design remains the same: receive a deal-updated event, filter on a stage change, look up the person, format the message, and send an authenticated HTTP request to Volanea.

This route can be appropriate for a low-volume operational workflow, but inspect three details before relying on it:

  1. Retry behavior: determine whether the platform retries an HTTP request after a timeout and whether it supports an idempotency key or a database-like deduplication step.
  2. Secret handling: the Volanea key must be stored in the platform’s encrypted connection or secret facility, never embedded in a client-visible webhook URL or a publicly shared scenario.
  3. Data lookup: verify that it can retrieve the linked Pipedrive person and reliably select the primary email, rather than assuming a deal event carries a complete recipient address.

For higher-volume, revenue-critical, or regulated workflows, custom middleware is usually clearer. You own the audit trail, deploy process, tests, idempotency behavior, retention policy, and failure recovery instead of trying to recreate those controls in a visual scenario.

Test before enabling real recipients

Start with a separate Pipedrive test pipeline or an unmistakably labeled test stage. Use internal recipients only. Move one test deal from a non-trigger stage to the configured trigger stage, then inspect the received webhook, person lookup response, rendered HTML, text body, and Volanea response.

Test the negative paths too. Update the deal title without changing stage and confirm no email is sent. Repeat the same webhook payload and confirm idempotency prevents a duplicate. Remove the person email and confirm the handler logs a skip. Force an API failure and confirm the event is retried or queued according to your design.

Finally, test a second transition into the trigger stage if your sales process permits moving a deal backward and forward. Decide whether that should send again. There is no universally correct answer; it is a business rule that your idempotency key and event model must encode explicitly.

Conclusion

To send email from Pipedrive with Volanea, use Pipedrive’s updated.deal webhook as the event source and a secure middleware endpoint as the decision and delivery layer. Detect the change from previous.stage_id to current.stage_id, retrieve the linked person’s primary address when needed, then submit a properly rendered email through Volanea.

This architecture avoids a brittle pretend-plugin workflow. More importantly, it keeps credentials private, makes retries safe, handles incomplete CRM records honestly, and gives your team a record of why an email was sent—or deliberately not sent.

FAQ

Can Pipedrive send directly to the Volanea API without middleware?

A Pipedrive webhook can notify an HTTPS endpoint, but it does not transform its deal-event payload into a Volanea email request or safely hold a Volanea API key for that purpose. Use middleware or a secure automation platform to perform mapping, validation, and authenticated sending.

What Pipedrive event should trigger the email?

For a stage-based workflow, subscribe to the updated.deal event. In your receiver, send only when previous.stage_id differs from current.stage_id and the new value equals your configured trigger stage ID.

Where should the Volanea API key be stored?

Store it as a server-side secret in your middleware or automation platform’s encrypted credential store. Never put it in browser code, Pipedrive fields, a public webhook URL, or a repository.

How do I stop duplicate emails after a webhook retry?

Persist an idempotency record before sending. At minimum, key it by the deal ID and triggering stage ID; use event metadata or a transition record if a deal can intentionally enter the same stage more than once.

What if the deal does not have a recipient email address?

Skip the send, log the reason, and optionally create an internal follow-up task. Do not infer an address from a company domain or send to an unverified custom field.