Send email from Tray.io without waiting for a native app integration: Tray.ai’s Webhook Trigger can receive an event, and its HTTP Client can call Volanea’s REST API directly. This guide shows the complete pattern, including the actual workflow payload, field mapping, authentication, retries, and failure handling.
There is no native Volanea connector, Tray marketplace listing, or installable Tray.io app for this integration. That is not a blocker. Tray’s HTTP Client is specifically designed for calling third-party APIs that do not have a prebuilt connector, while the Webhook Trigger can receive real-time events from services that can post JSON to a URL.
The result is a small, explicit workflow: an upstream system posts an event to Tray, Tray validates and maps the event, then Tray sends a JSON request to POST https://api.volanea.com/v1/send. It is a good fit for transactional messages such as lead acknowledgements, support updates, onboarding notices, approval notifications, account alerts, and order-status emails.
What this Tray.io integration does
The direct integration has four pieces:
- An external service emits an event, such as a new lead, completed form, changed deal stage, or approved request.
- Tray receives that event through a Webhook Trigger. In Tray terminology, a trigger starts a workflow run.
- A Tray HTTP Client step maps fields from the incoming JSON into Volanea’s send request.
- Volanea accepts the email for processing, applying the sending domain, suppression checks, contact handling, rendering, tracking, and delivery pipeline.
The concrete trigger in this guide is Tray’s Webhook Trigger. It is the right generic choice when your source can make an outbound HTTP webhook but Tray does not have an appropriate prebuilt service trigger, or when you want one reusable endpoint for events from an internal app.
Tray’s webhook output includes a request envelope with fields such as method, path, body, query, and headers. The JSON posted by the source is available under $.steps.trigger.body. Tray’s mapping syntax starts with $.steps.trigger for values produced by the trigger step.
That distinction matters. The workflow does not need to guess what a “new lead” means across every CRM or form tool. Your source posts the fields it has, the Webhook Trigger captures them, and you map those fields deliberately into an email message.
Why use the HTTP Client instead of a native connector
Tray’s HTTP Client can make GET, POST, PUT, PATCH, DELETE, and other HTTP requests to third-party endpoints. It is intended for exactly this situation: connecting to a service without a prebuilt Tray connector or reaching an endpoint not exposed by a connector.
For Volanea, direct REST is preferable to adding an unnecessary middleware hop. A Zapier or Make scenario could receive the event and send email, but it adds another service, another credential store, another retry policy, and another possible source of duplicate sends. If Tray is already your workflow platform, its HTTP Client is enough.
The direct route is:
- Source system → Tray Webhook Trigger for the business event.
- Tray HTTP Client → Volanea
POST /v1/sendfor the email request. - Volanea → recipient inbox for downstream delivery.
You can also swap the Webhook Trigger for a Tray service trigger if your upstream application has a supported Tray connector. For example, a CRM-specific trigger could start the workflow when a record is created or updated. The Volanea HTTP Client step remains the same; only the JSONPaths used for mapping change.
Prerequisites before you build the workflow
Set up the sending side before you activate the Tray workflow. A successful API request is not useful if the sender identity is unverified, the API key is stored in the wrong place, or the workflow has no plan for retries.
You need:
- A Volanea project and secret API key. Volanea secret keys use
sk_orsk_test_prefixes. - A verified sending domain in Volanea, with the sender address you plan to use, such as
notifications@updates.example.com. - A Tray project and workflow where you can use the Webhook Trigger and HTTP Client.
- An upstream system capable of posting JSON to a webhook URL, or a Tray service trigger that exposes the same recipient and event data.
- A stable source event identifier, such as
lead_id,submission_id,ticket_id, ororder_id, to use as the basis for duplicate protection.
Use a production sender that belongs to a domain your organization controls. Do not map an arbitrary user-entered address into Volanea’s from field. That creates authentication, spoofing, and deliverability problems. User-entered addresses are usually appropriate as a recipient address or, after validation, a reply-to address—not as the authenticated sender.
For the API’s current endpoint details and request options, consult the email API reference and setup guides. This article deliberately focuses on the Tray mapping and workflow behavior around the send request.
Build the Tray workflow with a Webhook Trigger
Create a workflow in the appropriate Tray project. Select Webhook Trigger as the first step. Tray provides a public URL for that trigger; copy the public URL from the trigger step options, then configure your source system to send its event to that URL.
For this example, imagine an internal lead-capture service sends a webhook every time it creates a qualified lead. The source posts this JSON:
{
"event": "lead.created",
"lead_id": "lead_01JQ8T2D7H5Q",
"occurred_at": "2026-09-25T15:42:12Z",
"lead": {
"first_name": "Maya",
"last_name": "Chen",
"email": "maya.chen@example.net",
"company": "Northstar Labs"
},
"owner": {
"name": "Jordan Lee",
"email": "jordan@example.com"
}
}
Tray represents the received request in its trigger output. Conceptually, the relevant section looks like this:
{
"method": "post",
"path": "/",
"body": {
"event": "lead.created",
"lead_id": "lead_01JQ8T2D7H5Q",
"occurred_at": "2026-09-25T15:42:12Z",
"lead": {
"first_name": "Maya",
"last_name": "Chen",
"email": "maya.chen@example.net",
"company": "Northstar Labs"
},
"owner": {
"name": "Jordan Lee",
"email": "jordan@example.com"
}
},
"query": {},
"headers": {
"content-type": "application/json"
}
}
The important point is that the original event is nested inside body. Therefore, the recipient email JSONPath is:
$.steps.trigger.body.lead.email
The source’s event schema is your contract. If the source sends contact.email rather than lead.email, map $.steps.trigger.body.contact.email instead. Do not copy this sample path blindly into production without sending a test event and checking Tray’s Debug output.
Configure the source event
Your source must make an HTTP POST request with JSON content. The configuration differs by product, but the common settings are:
- Webhook URL: the Tray Webhook Trigger public URL.
- HTTP method:
POST. - Content type:
application/json. - Event: the business event that should cause an email, such as
lead.createdorapplication.approved. - Signing secret: configure one when the source supports webhook signing, then validate it before sending email.
Use a test event first. In Tray, enable the workflow only when you are ready to receive it, trigger one harmless test event from the source, and inspect the resulting workflow run in Debug. This gives Tray an observed payload shape and lets you select fields with the mapper rather than relying entirely on handwritten JSONPaths.
Create a secure Volanea authentication in Tray
Do not paste the Volanea key directly into the HTTP Client headers or body. Tray’s documentation explicitly recommends using a proper authentication and referencing it with an $.auth value rather than hard-coding credentials in a step’s properties. That prevents the token from being exposed in normal workflow configuration and obscures it in logs.
In Tray, create a Generic Service Authentication or custom API authentication for Volanea. Store the Volanea secret key in a token field named api_key. Give the authentication a clear environment-specific name, such as:
Volanea production transactional senderVolanea staging test senderVolanea notifications production
Then select that authentication on the HTTP Client step. Reference the stored secret as:
$.auth.api_key
The HTTP request will send it as a bearer token:
Authorization: Bearer $.auth.api_key
Use a workspace or organization authentication when the email workflow is shared and should run with a controlled company credential. A personal authentication may be useful during development, but it creates operational risk if the workflow depends on one employee’s account or access.
Why the key must never be client-visible
A Volanea secret key authorizes email sends. If it appears in browser JavaScript, a public form configuration, a front-end mobile application, a client-side environment variable, or a screenshot of an HTTP request, someone can copy it and send mail through your account.
The browser or form should submit data only to your application or Tray Webhook Trigger. The secret belongs in Tray’s authentication store, where the HTTP Client uses it server-side. The upstream payload should contain ordinary event data—recipient address, event identifier, approved content variables—not privileged send credentials.
Also avoid putting the secret into the Webhook Trigger URL. The URL is not a substitute for authentication. If the originating service supports webhook signatures, validate those signatures. If it does not, limit who can invoke the workflow through an authenticated gateway or an application endpoint you control.
Add the Volanea HTTP Client send step
Add an HTTP Client connector step after the Webhook Trigger. Choose the POST operation. Use the Volanea authentication created above, set the URL to https://api.volanea.com/v1/send, and set the body type to JSON.
The request needs three standard headers:
Authorizationwith the stored bearer key.Content-Type: application/json.Idempotency-Keywith a stable value derived from the source event.
Volanea’s send endpoint accepts a sender, a recipient array, a subject, HTML, and a text fallback. It also supports safe retries using the Idempotency-Key header. The following configuration shows the actual mapping from the webhook payload to the outgoing Volanea request.
{
"operation": "POST",
"url": "https://api.volanea.com/v1/send",
"headers": {
"Authorization": "Bearer $.auth.api_key",
"Content-Type": "application/json",
"Idempotency-Key": "tray-lead-created-$.steps.trigger.body.lead_id"
},
"body": {
"from": "Northstar Updates <notifications@updates.example.com>",
"to": [
"$.steps.trigger.body.lead.email"
],
"subject": "Thanks for contacting Northstar Labs, $.steps.trigger.body.lead.first_name",
"html": "<p>Hi $.steps.trigger.body.lead.first_name,</p><p>Thanks for contacting Northstar Labs. A member of our team will follow up shortly.</p><p>Company: $.steps.trigger.body.lead.company</p>",
"text": "Hi $.steps.trigger.body.lead.first_name,\n\nThanks for contacting Northstar Labs. A member of our team will follow up shortly.\n\nCompany: $.steps.trigger.body.lead.company"
}
}
In the Tray builder, use the data mapper for each dynamic value rather than treating the sample above as a file to upload. The JSONPaths resolve during the workflow run. Once the sample event is in the Debug history, select lead.email, lead.first_name, lead.company, and lead_id from the trigger output.
Field mapping, line by line
| Volanea field or header | Tray value | Purpose |
|---|---|---|
Authorization | Bearer $.auth.api_key | Reads the Volanea secret from Tray authentication storage. |
Idempotency-Key | tray-lead-created-$.steps.trigger.body.lead_id | Makes retry attempts for the same source lead event recognizable as one logical send. |
from | Static verified sender | Keeps the sender authenticated and consistent. |
to[0] | $.steps.trigger.body.lead.email | Sends the acknowledgement to the lead’s address. |
subject | Static text plus $.steps.trigger.body.lead.first_name | Produces a recognizable transactional subject. |
html | Static HTML plus mapped fields | Provides the primary rendered email body. |
text | Static plain text plus mapped fields | Gives text-only clients and recipients a readable fallback. |
For a direct API test outside Tray, the resolved request is equivalent to this cURL command. Replace the key, sender domain, and recipient with your own values:
curl --request POST 'https://api.volanea.com/v1/send' \
--header 'Authorization: Bearer sk_test_replace_with_your_key' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: tray-lead-created-lead_01JQ8T2D7H5Q' \
--data '{
"from": "Northstar Updates <notifications@updates.example.com>",
"to": ["maya.chen@example.net"],
"subject": "Thanks for contacting Northstar Labs, Maya",
"html": "<p>Hi Maya,</p><p>Thanks for contacting Northstar Labs. A member of our team will follow up shortly.</p><p>Company: Northstar Labs</p>",
"text": "Hi Maya,\n\nThanks for contacting Northstar Labs. A member of our team will follow up shortly.\n\nCompany: Northstar Labs"
}'
Validate before sending email
An automation should not send simply because an HTTP request arrived. Add validation and branching between the trigger and the HTTP Client step, especially if the webhook endpoint can be called by more than one source or event type.
At a minimum, check:
$.steps.trigger.body.eventequals the expected event, such aslead.created.$.steps.trigger.body.lead.emailexists and is not blank.$.steps.trigger.body.lead_idexists, because it is the idempotency basis.- The recipient is appropriate for the message—for example, a transactional acknowledgement after a submitted form, not an unsolicited marketing send.
- The event came from an authorized source, ideally by validating an upstream signature or using an authenticated ingress route.
A basic branch can send the message only when the event and email fields pass. Route invalid payloads to an error-handling path that records the event ID and missing field names, but avoid logging the entire payload if it contains sensitive information.
Escape untrusted content
The html field is HTML, not a safe templating system by itself. If names, company names, ticket summaries, or form answers come from an untrusted user, escape HTML-sensitive characters before putting them into the message body. Otherwise, a value containing markup can alter the email layout or insert unwanted links.
For simple operational emails, keep the HTML minimal and map only low-risk fields such as a first name. For longer user-authored content, use a template system or a controlled sanitization step before the HTTP Client call. Preserve a plain-text version as well; it improves accessibility and provides a coherent fallback where HTML is disabled.
Prevent duplicate sends with idempotency
Email delivery is a side effect. A network failure can leave Tray unsure whether Volanea accepted a request: the request may have reached Volanea, but the response may not have returned to Tray. If the workflow retries without a stable idempotency key, a recipient can receive the same email twice.
Use Volanea’s Idempotency-Key header on every workflow send. The key should identify one business action, not one workflow attempt. In this example, lead_id is the logical identifier:
tray-lead-created-<lead_id>
If a source can emit multiple distinct events for the same lead, include the event type and a unique event ID or version. For example:
tray-application-approved-<application_id>-<approval_event_id>
Do not use a timestamp generated separately on each retry. That would produce a new idempotency key, defeating duplicate protection. Do not use the email address alone either: the same person may legitimately receive more than one notification over time.
A good idempotency key is stable for retries of the same event, unique across different events, and contains no sensitive data. An internal source event ID is better than a raw email address because IDs are less likely to expose personal data in logs.
When this breaks
Every integration has failure modes. The useful question is not whether an error can happen; it is whether the workflow will make the failure visible and avoid turning it into duplicate or missing mail.
Tray retries can create duplicate sends
Tray documents connector retry behavior for certain failures. Service connector API errors can be retried when error handling is configured to stop the workflow, while internal Tray or connector errors may also be retried under Tray’s platform policy. Meanwhile, an upstream service may retry its webhook if it does not receive a successful response from Tray.
That means one source event can result in repeated workflow execution or repeated API calls. The defense is the same at every layer: derive and reuse a Volanea Idempotency-Key from the source event’s stable ID. If the upstream system provides an event ID, prefer that over a resource ID because it distinguishes separate legitimate changes to the same record.
Also document your chosen behavior for retries. A temporary Volanea 5xx, rate limit, or transport error may be retryable. A malformed recipient, unverified sender, or missing required field is not fixed by repeating the identical request. Send those cases to a review or alert path instead of retrying blindly.
A webhook timeout does not mean the event failed
Tray documents a long wait for the HTTP Client response, but the webhook sender’s timeout may be much shorter. Some sources will retry their webhook after only a few seconds if they do not receive a success response. Others use their own retry schedule.
For a simple transactional-email workflow, avoid adding slow enrichment, large file processing, or multiple dependent API calls before acknowledging the inbound event. If the caller needs a synchronous response, use Tray’s Await workflow and respond behavior with the Trigger Event Reply connector, then return a clear success or failure status. Tray documents a five-minute wait for a webhook trigger using trigger-event replies, but your sender may time out long before that.
When the sender only needs confirmation that Tray accepted the event, respond quickly and complete heavier work asynchronously where your design allows it. Most importantly, preserve the event ID so a sender retry resolves to the same idempotent Volanea operation.
Payload fields may be missing on some source plans or event types
Do not assume every source product, subscription tier, webhook event, or form configuration includes the same fields. An email address might be unavailable because the field was optional, excluded from the webhook configuration, hidden by permissions, or not included in that source’s plan. A deal-stage event may contain only a record ID, requiring a follow-up lookup through a source connector before you can retrieve the contact email.
Treat missing values as expected integration cases, not as a reason to send malformed email. Add a branch that checks for the fields required by the message. If lead.email is absent, stop the send and log something like missing_recipient_email with the source event ID. If the source supplies only an ID, add the appropriate source API lookup step before mapping to Volanea.
Test at least these payload variants:
- A complete valid event.
- An event with no recipient email.
- An event with no stable event ID.
- A repeated event with the same ID.
- An event from a different source plan or account configuration.
- An event whose user-provided fields contain quotes, angle brackets, or non-ASCII characters.
Invalid JSONPaths fail differently from API errors
A typo such as $.steps.trigger.body.leeds.email is a workflow mapping mistake, not a Volanea delivery failure. Tray notes that wrong user input, including an incorrect JSONPath, does not receive the same retry treatment as a connector failure.
Use a test event and Tray’s Debug view after every meaningful payload change. If a field does not appear in the mapper, it may be absent from the observed trigger schema. Send a representative event, inspect the raw trigger output, then update your mapping against the actual shape.
An accepted send is not a delivered email
The Volanea send call starts the email processing pipeline; it is not proof that a specific recipient has placed the message in their inbox. Suppressions, unsubscribes, recipient mailbox behavior, authentication alignment, bounces, and provider-level delivery outcomes all occur after acceptance.
For operationally important messages, capture Volanea’s response in Tray logs and correlate it with the source event ID. Then use Volanea delivery events or send logs to investigate complaints, bounces, deferrals, and suppression outcomes. This makes it possible to answer the support question that matters: not merely “did the workflow run?” but “what happened to the message for this business event?”
Improve reliability and deliverability after the first send
Once the basic workflow is working, make it maintainable. The temptation in low-code automation is to put all logic in one large workflow. A better design separates event intake, validation, message construction, sending, and monitoring.
Use a stable sender and message class
Keep transactional mail separate from marketing mail at the sender and workflow level. A lead acknowledgement should come from a recognizable transactional identity such as notifications@updates.example.com or hello@example.com, not a rotating address assembled from workflow data.
Use subject lines that reflect the recipient’s action. “We received your request” is clearer than “Important update.” Transactional mail should help the recipient understand why they received it and what, if anything, they need to do next.
Keep message content deterministic
The same event should generally create the same message. That is useful for retries, debugging, compliance review, and idempotency. Avoid generating materially different email content every time a retried workflow runs.
If a notification needs a time-sensitive value, decide whether it belongs to the original event or the current workflow attempt. For receipts and approvals, the event-time value is usually correct. For a scheduled reminder, the send-time value may be appropriate, but it should use a separately identified reminder event.
Use tests and environment separation
Keep development and production separate. Use a Volanea test key and a safe recipient set in development, then use a production authentication and verified production domain only after validating the flow.
Exporting or promoting workflows is safer when the authentication is selected by environment rather than embedded in individual HTTP steps. Name every authentication clearly enough that a reviewer can see whether a workflow is about to send real customer email or test messages.
Monitor the right identifiers
For every send, retain three identifiers where possible:
- The source event ID, such as
lead_01JQ8T2D7H5Q. - The idempotency key, such as
tray-lead-created-lead_01JQ8T2D7H5Q. - The Volanea message identifier returned by the send response.
Together, these identifiers make duplicate investigations far easier. If an upstream service retries, you can determine whether Tray ran twice, whether Volanea replayed an idempotent result, and whether the recipient received one or more messages.
Alternatives to the Webhook Trigger pattern
The Webhook Trigger is the broadest solution, but it is not the only Tray trigger type.
Use a prebuilt service trigger when it exposes the exact event
If Tray has a connector for your CRM, help desk, commerce platform, or form tool and it exposes the event you need, start with that service trigger. It can reduce webhook configuration and may provide an authentication-managed connection to the source platform.
The downstream Volanea step is unchanged. Replace paths such as $.steps.trigger.body.lead.email with the paths exposed by the service trigger. Test the resulting trigger payload because connector schemas and field availability vary by service.
Use a Form Trigger for a Tray-hosted internal form
Tray also offers a Form Trigger, which can host a form that starts the workflow. That is useful for staff-facing workflows such as “send an approved customer update” or “request a manual account notification.”
Do not use a publicly exposed form as an unrestricted email relay. Restrict access, validate all inputs, use a fixed verified sender, and do not allow users to freely choose arbitrary HTML, recipients, or subjects without authorization controls.
Use a middleware service only when you need custom logic
A serverless function or application endpoint can be useful if you need cryptographic webhook verification that is not convenient in the workflow, complex HTML escaping, database-backed deduplication beyond source IDs, custom recipient authorization, or detailed audit storage.
But middleware should solve a real requirement. For a standard JSON webhook-to-transactional-email flow, Tray’s Webhook Trigger plus HTTP Client is the simpler architecture. It keeps the secret in Tray authentication storage, avoids a second automation platform, and makes the mapping visible to workflow maintainers.
A production checklist for sending email from Tray.io
Before turning on a production workflow, verify each item below:
- The Volanea sender domain is verified and the
fromaddress belongs to it. - The Volanea API key is stored in Tray authentication storage, not hard-coded in a workflow step.
- The HTTP Client uses
POST https://api.volanea.com/v1/send. - The request sends
Authorization: Bearer $.auth.api_keyandContent-Type: application/json. - The request includes a stable, non-sensitive
Idempotency-Keybased on the source event ID. - A branch validates the expected event type, recipient field, and event ID before calling Volanea.
- The workflow has been tested with real representative payloads from the source.
- Missing fields and malformed data follow an explicit error path rather than producing partial mail.
- Dynamic fields inserted into HTML are escaped or otherwise sanitized.
- The sender, source event ID, idempotency key, and Volanea response are available for troubleshooting.
- You understand whether the source retries webhooks and how Tray handles connector errors.
- Production and test authentications are clearly separated.
The basic workflow is intentionally straightforward. Tray starts a workflow with an event, maps trusted data into a Volanea JSON request, and sends the request with a stored secret. The production-grade parts are validation, idempotency, sender authentication, and observability—not a marketplace button.
FAQ
Does Volanea have a native Tray.io connector?
No. This integration uses Tray’s Webhook Trigger and HTTP Client rather than a native Volanea app, marketplace listing, or plugin. Tray’s HTTP Client is designed to call third-party APIs that do not have a prebuilt connector.
What trigger should I use to send email from Tray.io?
Use a Webhook Trigger when an external system can post events to a URL. Use a Tray service trigger when a supported source connector exposes the exact event you need. In either case, map the trigger output into the Volanea HTTP Client request.
Where should I store the Volanea API key in Tray?
Store it in a Tray Generic Service Authentication or custom API authentication. Reference it through $.auth.api_key in the HTTP Client’s Authorization header. Never put a secret key in client-side code, a public form, or a hard-coded workflow field.
How do I stop Tray retries from sending duplicate email?
Set Volanea’s Idempotency-Key header to a stable value derived from the source event ID. Reuse that same value whenever the same logical event is retried. Do not generate a new timestamp or random value for each attempt.
Why did the workflow run but no email arrive?
The workflow may have accepted the event while the message was later suppressed, bounced, deferred, filtered, or sent to an invalid recipient. Check the Tray run for mapping and API errors, then check Volanea send and delivery records using the source event ID and returned message identifier.