Sending email from Streak with Volanea is a useful way to make a CRM pipeline event trigger an operational email without putting sending credentials in Gmail or a browser extension. The reliable pattern is Streak webhook → server-side middleware → Volanea REST API, rather than a native Streak marketplace installation.

Streak does not provide a native Volanea app, plugin, or marketplace connection. That is not a blocker, but it does define the architecture: Streak reports that something happened to a Box in a pipeline, your endpoint validates and translates that event, and the endpoint calls Volanea with the recipient, content, and sender details.

The integration architecture

Streak is a CRM that works around pipelines and Boxes. A Box is the individual record moving through a pipeline: for example, a lead, customer, order, candidate, or renewal. Boxes have a name, a pipeline, a stage, contacts, comments, tasks, and custom fields.

For this integration, the meaningful event is generally a Box entering a particular stage. A common example is a sales lead moving into a stage called Demo booked, or an onboarding record moving to Welcome email ready. Streak's webhook event tells your application that the Box changed; your application decides whether that change should result in email.

The flow has three distinct responsibilities:

  1. Streak detects the CRM event. Configure a webhook for the relevant pipeline event, such as a Box edit or stage change event.
  2. Your middleware applies business rules. It identifies the Box, checks the stage and required custom fields, prevents duplicate sends, and builds the email payload.
  3. Volanea delivers the message. The middleware makes an authenticated REST request using a Volanea API key held in server-side environment variables.

This separation matters. Streak is the source of workflow context, while Volanea is the sending infrastructure. The adapter is where you safely join those two systems and make the send deterministic.

Choose a Streak trigger that represents intent

Do not send an email merely because any Box changed. A Box may change because a teammate corrected a phone number, added a note, updated a custom field, or assigned an owner. The trigger should represent a deliberate workflow transition.

Recommended trigger: a Box changes stage

For most CRM-driven email, use a stage change. Streak represents a pipeline record as a Box and stores its current stage in the Box data. Configure a webhook around the Box event that Streak exposes for changes, then have middleware compare the Box's current stageKey with the stage key that should initiate the email.

Typical examples include:

  • A lead moves to Trial started: send setup instructions.
  • A deal moves to Contract sent: send a copy of next steps.
  • A customer moves to Onboarding complete: send a handoff or survey email.
  • A candidate moves to Interview scheduled: send practical interview details.

A stage name is understandable to people, but a stage key is safer in code. Names can be edited and duplicated; keys are the stable identifiers returned by Streak's API. Store the approved pipelineKey and stageKey in server-side configuration.

Alternative trigger: a Box is created

A Box-create webhook can work for a confirmation email immediately after a form, import, or manual process creates a record. It is best when the initial record is guaranteed to contain an email address and consent status.

Creation is less suitable if a team usually creates incomplete Boxes and fills contacts later. In that case, a creation event can race ahead of the required data. Use a later stage instead, or have middleware retrieve the Box and defer processing until mandatory fields exist.

What Streak webhooks provide

Streak webhooks notify an HTTPS endpoint with an event envelope. The payload identifies the event and includes data associated with it. For Box activity, use the Box key as the durable identifier and retrieve the current Box from Streak's API if your sending decision requires complete, current contacts or fields.

The exact fields available in an event can vary by event type and Streak feature access, so do not treat a webhook body as a permanent full copy of your CRM record. Design the webhook as a notification and make a server-to-server Streak API lookup when complete record data is needed.

Build a safe field model in Streak

Before writing code, decide which Streak fields are the source of truth. This avoids the fragile practice of parsing a Box name or guessing which contact address should receive a message.

A practical pipeline uses custom columns such as the following:

Streak field or propertyPurpose in the integration
Box contact emailRecipient address when the Box has one clear primary contact
First name custom fieldPersonalization variable
Send consent custom fieldExplicit gate for promotional or optional messages
Email locale custom fieldTemplate or language selection
Volanea send status custom fieldOptional human-visible status
Volanea message ID custom fieldOptional traceability reference

For a transactional email, consent requirements depend on the message and jurisdiction, but relevance still matters. A password, appointment, or order notice is different from a marketing update. Do not use a stage automation to convert ordinary CRM contacts into an unsolicited campaign.

Pick one recipient rule

A Box can have multiple contacts. Define what that means before deployment. For example: send to the contact whose email is in the Primary email custom field; otherwise, send only if there is exactly one contact with an email address; otherwise, flag the Box for manual resolution.

That rule is preferable to emailing every contact in a Box by default. A deal can include a buyer, technical evaluator, finance contact, and internal address. Blindly sending to all of them can disclose information and creates a difficult unsubscribe and audit story.

Keep templates out of arbitrary CRM text

You can store a short customer-facing value, such as a booking date or onboarding link, in Streak. Keep the full HTML structure and sender identity in your application or an approved template system. This reduces accidental markup errors, prevents a user from changing deliverability-sensitive content in a spreadsheet-like field, and makes reviews easier.

For implementation details on authentication, request formats, and sending configuration, consult the email API reference and setup guides alongside this workflow design.

The webhook payload and field mapping

A Streak Box webhook is not itself an email request. It is a CRM event envelope. The important identifier is the Box key, which lets your middleware look up the canonical Box data and evaluate the latest state.

The following is the shape to expect conceptually from a Box event: an event type, a timestamp, and a data object containing the affected Box or its identifying data. The Box object includes identifiers such as key, pipelineKey, and stageKey; contacts and custom fields are associated with the Box record.

{
  "event": "BOX_EDIT",
  "timestamp": 1710000000000,
  "data": {
    "box": {
      "key": "agxzfm...",
      "name": "Acme onboarding",
      "pipelineKey": "agxzfm...",
      "stageKey": "agxzfm...",
      "contacts": [
        {
          "key": "agxzfm...",
          "name": "Avery Chen",
          "email": "avery@example.com"
        }
      ],
      "fields": {
        "first_name_field_key": "Avery",
        "consent_field_key": "yes"
      }
    }
  }
}

Treat the field keys in that example as placeholders, not labels you can paste into production. Custom-field keys are unique to a Streak pipeline. Retrieve them from your own pipeline/API data, store them in environment variables, and map them deliberately.

The field mapping below is explicit:

Streak sourceVolanea email fieldRule
data.box.contacts[0].emailtoUse only after recipient selection and validation
data.box.fields[firstNameKey]HTML/text personalizationEscape before interpolating in HTML
data.box.keyidempotency or correlation valueOne logical send per Box and purpose
configured server valuefromNever accept sender addresses from the webhook
configured server valuesubjectKeep workflow language versioned in code

A working server-side adapter

The following Node.js example shows the core adapter. It accepts a Streak Box event, verifies that the Box is in the intended pipeline and stage, maps the contact and custom field, records an idempotency key, and sends through Volanea's REST email endpoint.

The handler intentionally does not trust a Box name, a browser value, or a supplied from address. It uses environment variables for all sensitive and deployment-specific settings.

import express from "express";

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

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

const required = [
  "VOLANEA_API_KEY",
  "VOLANEA_FROM",
  "STREAK_PIPELINE_KEY",
  "STREAK_TRIGGER_STAGE_KEY",
  "STREAK_FIRST_NAME_FIELD_KEY",
  "STREAK_CONSENT_FIELD_KEY"
];
for (const name of required) {
  if (!process.env[name]) throw new Error(`Missing ${name}`);
}

app.post("/webhooks/streak", async (req, res) => {
  const event = req.body;
  const box = event?.data?.box;

  // Acknowledge malformed or irrelevant notifications without sending.
  if (!box?.key) return res.status(202).json({ ignored: "no box" });
  if (box.pipelineKey !== process.env.STREAK_PIPELINE_KEY) {
    return res.status(202).json({ ignored: "different pipeline" });
  }
  if (box.stageKey !== process.env.STREAK_TRIGGER_STAGE_KEY) {
    return res.status(202).json({ ignored: "different stage" });
  }

  const fields = box.fields || {};
  if (String(fields[process.env.STREAK_CONSENT_FIELD_KEY]).toLowerCase() !== "yes") {
    return res.status(202).json({ ignored: "consent not present" });
  }

  const recipient = (box.contacts || []).find(c => c.email)?.email;
  if (!recipient) return res.status(202).json({ ignored: "no recipient" });

  // One Box can legitimately generate several different email purposes.
  const purpose = "onboarding-welcome-v1";
  const idempotencyKey = `${box.key}:${purpose}`;
  if (sent.has(idempotencyKey)) return res.status(200).json({ duplicate: true });

  const firstName = String(fields[process.env.STREAK_FIRST_NAME_FIELD_KEY] || "there")
    .replace(/[&<>"']/g, ch => ({ "&":"&amp;", "<":"&lt;", ">":"&gt;", "\"":"&quot;", "'":"&#39;" }[ch]));

  const emailPayload = {
    from: process.env.VOLANEA_FROM,
    to: [recipient],
    subject: "Welcome — here are your next steps",
    html: `<p>Hi ${firstName},</p><p>Your onboarding is ready. Reply to this email if you need help.</p>`,
    text: `Hi ${firstName},\n\nYour onboarding is ready. Reply to this email if you need help.`,
    tags: [
      { name: "source", value: "streak" },
      { name: "box_key", value: box.key }
    ]
  };

  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": idempotencyKey
    },
    body: JSON.stringify(emailPayload)
  });

  if (!response.ok) {
    const detail = await response.text();
    console.error("Volanea send failed", response.status, detail);
    return res.status(502).json({ error: "email provider rejected send" });
  }

  const result = await response.json();
  sent.add(idempotencyKey);
  console.log("Sent Volanea email", { boxKey: box.key, result });
  return res.status(200).json({ accepted: true });
});

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

In a production service, replace the in-memory Set with durable storage. A database row with a unique index on (box_key, purpose) is a straightforward choice. Insert the row atomically before sending, or use an outbox/job design so concurrent retries cannot both create a send.

If your Streak webhook event only contains a partial Box object, use box.key to fetch the Box through Streak's server-side API before constructing emailPayload. That extra lookup is worthwhile when contacts or fields can change frequently, because it ensures the stage and recipient are evaluated from authoritative data.

Store authentication in the right place

The Volanea API key belongs in the middleware runtime, not in Streak, Gmail, frontend JavaScript, a Streak custom field, or a webhook URL query string. Set it as a secret environment variable in the hosting platform used for your endpoint: for example, a serverless function's encrypted environment settings, a container secret, or a managed secret store.

There should be no Volanea API key on the Streak side of this direct-webhook architecture. Streak needs only the HTTPS webhook URL. This is a feature, not an inconvenience: Streak's event payload reaches your endpoint, while only the endpoint can access VOLANEA_API_KEY and create a send.

Why client-visible configuration is dangerous

A browser extension, page source, custom JavaScript bundle, spreadsheet-like field, or webhook URL can be copied by users and captured by logs. If an email API key appears there, anyone who obtains it may be able to send mail as your domain, consume your quota, damage sender reputation, or inspect provider data allowed by that key.

Use separate keys for development and production where available. Rotate a key immediately if it appears in a commit, a support ticket, or an HTTP URL. Limit access to the secret store to the service identity that runs the adapter.

Also secure the inbound Streak webhook. Use a high-entropy unguessable endpoint path at a minimum, restrict accepted methods and content types, and validate any webhook authentication or verification mechanism available in your Streak configuration. Do not assume that a public endpoint is safe merely because its URL is obscure.

Test the workflow before enabling real sends

Start with a test pipeline and an internal mailbox. Use a verified Volanea sending domain and a recipient you control. Record the webhook body, the Box key, your chosen recipient, the Volanea response status, and the returned message identifier in structured logs.

A useful test matrix includes:

  1. Create a Box directly in the trigger stage and confirm whether your selected event catches it.
  2. Move a Box into the trigger stage and verify exactly one email is sent.
  3. Edit the Box after it is in that stage and verify no additional email is sent.
  4. Move it out and back into the stage; decide whether that should send again and test the intended policy.
  5. Test a Box without a contact email, without consent, and with multiple contacts.
  6. Make Volanea return an error in a test environment and confirm that the event is retried or queued safely.

For recipient hygiene, validate addresses before adding them to an automated workflow. The free address verification tool can help catch malformed or risky addresses before they become repeated delivery failures.

Separate acknowledgment from delivery work

Webhook providers expect a prompt HTTP response. If your application performs a Streak API lookup, template rendering, database writes, and an external email request before responding, it may exceed the sender's timeout. A timeout can lead Streak to retry even if your application eventually sends the message.

The durable pattern is to validate and persist the event quickly, return a successful response, and process the email in a background job. The job has a stable idempotency key and its own retry policy. This improves reliability and gives you a clear operational queue when Volanea or your own database is temporarily unavailable.

When this breaks

Every integration has failure modes. The important thing is to make them visible and non-destructive rather than treating an email send as a one-line side effect.

Streak retries can create duplicate messages

A webhook can be delivered more than once, especially when your endpoint times out, returns a 5xx status, or has a transient network failure. A Box can also generate several edits while remaining in the same trigger stage. Without idempotency, each delivery can produce another welcome email.

Use a durable key such as boxKey:emailPurpose:templateVersion. Enforce uniqueness in storage and pass the same idempotency value to Volanea if the API supports it. Do not mark a record as permanently sent before you have a known outcome; instead track states such as pending, accepted, and failed.

Webhook timeouts hide successful processing

The most confusing failure occurs when Streak considers a webhook attempt unsuccessful but your service completes the email send after the timeout. The sender retries, and now two processes race. Queue work and acknowledge quickly; if synchronous sending is unavoidable, make the database uniqueness check happen before the provider call.

Monitor endpoint latency separately from delivery. A 200 response to Streak confirms that your receiver accepted an event. It does not prove that an email reached an inbox. Use Volanea response data and delivery events where configured to understand provider acceptance and downstream outcomes.

Payload data can be incomplete or unavailable

Webhook event types can carry less data than a full Box lookup, and feature availability can differ by Streak plan or account setup. A pipeline's custom field may also be empty for older records, manually created Boxes, imports, or records created before the team adopted a new process.

Handle missing values as a business state, not an exception that triggers an endless retry. Return or record a reason such as no recipient, missing consent, or missing locale; notify an owner or add an internal task when human action is required. For fields essential to the send, retrieve the Box using its key and reject the send if the canonical record still lacks the value.

A stage is changed back and forth

Sales and support teams legitimately move Boxes backward. Decide upfront whether returning to the same stage is a new send opportunity. A one-time onboarding email usually should not send twice, while a new appointment confirmation may need a versioned confirmation every time the appointment date changes.

Encode that decision in the idempotency purpose. For one-time email, boxKey:welcome-v1 is enough. For a message that must be renewed after a material update, include a normalized appointment ID or revision number rather than a raw webhook timestamp.

Deliverability and message design

A technically successful API response is only the beginning. Use a verified sender domain and align the From domain with the domain authenticated for Volanea. Set SPF, DKIM, and DMARC according to your sending-domain configuration, and avoid switching From addresses based on values supplied by Streak users.

Keep CRM-triggered messages specific to the workflow event. A lead who booked a demonstration expects a confirmation; they do not necessarily expect a broad product newsletter. Transactional relevance reduces complaints and makes the pipeline's behavior easier for teammates to explain.

Use both HTML and plain-text content. Avoid putting critical information only in an image or only behind a tracking redirect. Include a reply-capable address when a recipient may need help, and use tags or metadata that let you correlate an email with a Streak Box without placing sensitive CRM details in subject lines.

Direct webhook versus Zapier or Make

A direct webhook and small adapter is the strongest option when you need predictable retries, secure secret handling, a custom recipient rule, or precise idempotency. It is also the best route when a stage change must generate an immediate, auditable transactional email.

Zapier or Make can be appropriate for a low-volume proof of concept. Streak can be used as the trigger in those automation platforms, and an HTTP request or code step can call Volanea. The same constraints still apply: keep the Volanea key in the automation platform's protected connection or secret mechanism, use a deterministic dedupe key where supported, and do not expose the key in a client-side field.

The trade-off is control. Visual automation makes basic mapping approachable, but multi-contact rules, durable deduplication, webhook verification, and error queues are harder to model. Move to a small middleware service when the email affects revenue, access, scheduling, compliance, or customer trust.

Operational checklist and conclusion

Before going live, confirm the following:

  • The Streak webhook points to a production HTTPS endpoint.
  • The endpoint accepts only expected event shapes and pipeline keys.
  • The production Volanea API key exists only in server-side secret storage.
  • The From domain is authenticated and the From address is controlled by configuration.
  • Recipient selection is explicit for Boxes with zero, one, or many contacts.
  • Consent and required fields are checked before optional or marketing-related sends.
  • A durable idempotency record prevents retry-driven duplicates.
  • Failures are logged with Box key, event type, provider status, and a safe error reason.
  • Team members know which Streak stage causes which customer message.

To send email from Streak with Volanea reliably, use Streak for the CRM transition and Volanea for delivery, with a secure server-side boundary between them. That boundary is where you protect credentials, turn an event into a clear business decision, and ensure that retries do not become duplicate email.

FAQ

Does Volanea have a native Streak integration?

No. This workflow does not require a marketplace app: it uses Streak webhooks and a middleware endpoint that calls the Volanea REST API.

What Streak event should trigger the email?

For most workflows, trigger on a Box change and have middleware send only when the Box's pipelineKey and stageKey match the approved pipeline stage. This is safer than sending on every Box edit.

Where should the Volanea API key be stored?

Store it only as an encrypted server-side secret in the middleware or automation platform. Do not put it in Streak fields, browser code, a Gmail extension, or a webhook URL.

How do I prevent Streak retries from sending duplicates?

Create a durable idempotency key based on the Streak Box key and email purpose, enforce it in a database, and reuse that key for provider-level idempotency when available.

What happens if the webhook does not include the recipient field?

Use the Box key from the event to retrieve the current Box through Streak's API. If the canonical Box still has no eligible email address or required field, do not send; record the reason for follow-up instead.