Send Email

Sends transactional emails via Resend — notifications, confirmations, alerts, or any programmatic email from a workflow.

When to Use

Use Send Email when you need to:

  • Send confirmation or notification emails triggered by webhook events
  • Deliver plain-text or HTML emails from workflow data
  • Notify users after a payment, signup, or status change
  • Send dynamic emails where the recipient or subject comes from upstream data

Inputs

HandleTypeDescription
textstringPlain text email body from a prior node. Shown by default on the canvas.
htmlstringHTML email body. Takes priority over text when connected.
tostringRecipient address override. Overrides the to setting when connected — useful when the recipient is fully dynamic.

Output

HandleTypeDescription
resultobjectEmail send result

The result (accessed as {{ email_result.* }}) shape:

FieldTypeDescription
idstringResend message ID
successbooleanWhether the send succeeded
errorstringError message if success is false
{
  "id": "abc123-def456",
  "success": true,
  "error": null
}

Settings

SettingTypeDefaultDescription
fromstringSender email address (e.g. [email protected]). Must be from a verified Resend domain. Required.
fromNamestringSender display name. If set, appears as "Name <address>" in the recipient's inbox.
tostringRecipient email address. Supports {{ }} template expressions (e.g. {{ trigger.payload.email }}). Required unless overridden by the to input handle.
subjectstringEmail subject line. Supports {{ }} template expressions. Required.
replyTostringReply-to email address. Replies from the recipient go to this address instead of the sender.

Required Secrets

  1. Sign up at resend.com and verify your sending domain.
  2. Create an API key at resend.com/api-keys.
  3. Add it on the Env Vars page:
VariableDescription
RESEND_API_KEYResend API key (starts with re_...)

Example

Canvas

Payment confirmation email after a Stripe webhook:

Webhook Trigger → Transform → Send Email

Send Email settings:

  • From: [email protected]
  • From Name: Your App Billing
  • To: {{ transform.customerEmail }}
  • Subject: Payment received — ${{ transform.amountFormatted }}
  • Text input handle: connected from a Code node that builds the email body

Code node building the body:

return f"""Hi {input['customerName']},

Your payment of ${input['amountFormatted']} has been received.

Order ID: {input['orderId']}
Date: {input['date']}

Thank you for your business.
"""

For HTML emails, connect an HTML string to the html input handle instead. When both text and html are connected, html takes priority.

TSL

import webhook from @tensorify/webhook-trigger:4.0.0
import email from @tensorify/resend-send-email:1.0.0

node trigger @tensorify/webhook-trigger:4.0.0 {
    path = "/stripe/events"
    method = "POST"
}

node send @tensorify/resend-send-email:1.0.0 {
    from = "[email protected]"
    fromName = "Your App Billing"
    to = "{{ webhook.body.data.object.customer_email }}"
    subject = "Payment received"
}

trigger.payload -> send.text

Error Handling

Send Email has an On Error control output branch. Enable it via the "Error output handle" toggle at the bottom of the settings panel.

The error branch fires when:

  • RESEND_API_KEY is missing or invalid
  • The sender domain is not verified in Resend
  • The Resend API returns an error (invalid recipient, rate limit, etc.)

Connect the error branch to a fallback notification or logging action. You can also check {{ email_result.success }} on the main output path without enabling the error handle.

Common Gotchas

  • Unverified domain: Resend rejects sends from unverified domains. Verify your domain at resend.com/domains before going to production.
  • Missing RESEND_API_KEY: The node fails at runtime with an authentication error if the env var is not set.
  • HTML vs text: When both input handles are connected, html takes priority. Provide text as a fallback for clients that do not render HTML.
  • Dynamic recipients: When the recipient comes from upstream data, either use a binding in the To Address setting or connect the to input handle for a full override.
  • Check email_result.success: The node does not automatically stop execution on send failure unless you connect the On Error branch or add an If node checking {{ email_result.success }}.

See Also

On this page