Appearance
Resend integration
Resend is a developer-focused email platform for sending transactional emails. This integration lets your WeWeb backend send emails using Resend’s API.
Use cases
- Send transactional emails from backend workflows (sign-up confirmations, passwordless links, receipts)
- Personalize messages with dynamic variables and HTML or plain text
- Deliver to one or multiple recipients, with optional CC/BCC
- Categorize emails using tags for tracking and analytics
Setup
- In Resend, create an API key.
- In WeWeb, add your Resend API key to the
EditorandProductionmode. If you wish, you can use different keys for the editor environment in WeWeb and your live application,
WHY USE SEPARATE KEYS PER ENVIRONMENT?
Using distinct API keys for the editor and live app helps you prevent accidental production sends during development, and isolate usage between development and your live application.
It is by no means required, but is a recommended best practice.
- Test by sending a simple email (e.g., to yourself).
SENDING TEST EMAILS
To send test emails without yet verifying your domain, you can use the email onboarding@resend.dev for the from email, and the email of your Resend account as the to email.
You are unable to send emails to anyone other than yourself without verifying the domain or sender.
- Verify your domains in Resend to be able to set a custom
fromandtoemail.
Sending test emails
Before verifying your domain, you can send test emails using Resend's test domain:
- Set the
From Emailtoonboarding@resend.dev - Set the
To Email(s)to your Resend account email address - Fill in your
Subjectand email content (HTML ContentorText Content) - Send the email
You will only be able to send to your own Resend account email until you verify your domain or sender.
Sending dynamic values in HTML content
You can make your emails personalized and dynamic by binding values into your HTML content. This allows you to include user names, order numbers, custom links, and any other data from your app.
How to add dynamic values
- Click on the HTML Content field in the Send Email action
- Click the plug icon beside the field to open the binding window
- In the binding window, you can:
- Reference variables by typing their name (e.g.,
userName,orderTotal) - Access user data with
currentUser.name,currentUser.email - Use workflow variables or action results from previous steps
- Write JavaScript expressions for more complex logic
- Reference variables by typing their name (e.g.,
Example with dynamic values
Here's an example of HTML content with dynamic values bound:
html
<h2>Hello ${userName}!</h2>
<p>Thank you for your order #${orderId}.</p>
<p>Your total is ${orderTotal}.</p>
<a href="${confirmationLink}">View your order</a>In the binding window, you would write this as a template literal or concatenated string:
javascript
`<h2>Hello ${variables.userName}!</h2>
<p>Thank you for your order #${variables.orderId}.</p>
<p>Your total is $${variables.orderTotal}.</p>
<a href="${variables.confirmationLink}">View your order</a>`USING TEMPLATE LITERALS
When binding HTML content with multiple dynamic values, use template literals (backticks `) in the formula window. This makes it easier to include variables directly in your HTML using ${variableName} syntax.
Sending attachments
You can attach files to your emails using either publicly accessible URLs or base64-encoded file content.
Using file URLs
If your file is already hosted online (in cloud storage, on your server, or via CDN):
- In the
Attachmentsfield, add a new attachment - Set
Filenameto the name you want recipients to see (e.g.,invoice.pdf) - Set
Attachment Sourceto File URL - Set
File Path (URL)to the publicly accessible URL of your file- Example:
https://cdn.example.com/invoices/12345.pdf - You can bind this to a variable:
${variables.invoiceUrl}
- Example:
Using base64 content
If you have file data as base64 (from a file upload component or generated file):
- In the
Attachmentsfield, add a new attachment - Set
Filenameto the name you want recipients to see (e.g.,receipt.pdf) - Set
Attachment Sourceto Base64 Content - Set
File Content (Base64)to your base64-encoded file data- You can bind this to a variable containing the base64 string
- Example:
${variables.fileBase64}
Multiple attachments
To send multiple files, click the + button in the Attachments array to add more attachment items. Each attachment needs its own filename and content source.
FILE SIZE CONSIDERATIONS
While Resend doesn't publish a strict file size limit, keeping total email size (including attachments) under 10MB is recommended for reliable delivery across email providers.
Common pitfalls (setup & usage)
Unverified sender or domain
If you have not verified your sender or domain, Resend restricts sending to only your own email address. Attempts to send to other recipients will return a 403 error.
To resolve this, make sure you have verified your domain or sender in Resend before attempting to send emails.
If you need to send a test email and you have not verified your domain, make sure you set the from email as onboarding@resend.dev, and the to email as the email of your Resend account.
Invalid email addresses
If any address in from, to, cc, bcc, or reply_to is invalid, the request will fail with a 400 error. Arrays are supported for to/cc/bcc, but every item must be a valid email address.
Validate all addresses before sending. When debugging array payloads, start with a single known-good recipient, then expand the list once the send succeeds.
Subject too long
Very long subjects can be rejected by providers or truncated by clients. Keep subjects concise; staying well below ~998 characters is recommended for broad compatibility.
Write clear, short subjects and avoid excessive personalization tokens that expand length at runtime.
Invalid or heavy HTML
Malformed or very heavy HTML (nested tables, huge inline images, or invalid markup) can be rejected or clipped by providers and clients.
Use clean, valid HTML and keep payloads lightweight. Include a plain Text Content alternative if HTML is optional for your use case.
All Actions
Below is the initial actions set derived from WW-4193. Parameters reflect the Resend Email API.
| Action | Description |
|---|---|
| Send Email | Send a transactional email via Resend |
Action details
Send Email
Send a transactional email via Resend.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
From Email | "onboarding@resend.dev" | Sender’s email address | Must be a valid email; verified domain/sender |
To Email(s) | ["user1@example.com","user2@example.com"] | Recipient email address(es) | One string or array of valid emails |
Subject | "Hello World" | Email subject line | Recommended limit: ≤ 998 characters |
HTML ContentOptional | <p style='margin:0'>Hey {{name}}, here's your magic link: <a href='{{magicLink}}'>Sign in</a></p> | HTML content of the email | Valid HTML string |
Text ContentOptional | "Hello world!" | Plain text content of the email | Plain text string |
Reply ToOptional | "support@example.com" | Reply-to email address | Must be a valid email |
BCC RecipientsOptional | ["bcc1@example.com","bcc2@example.com"] | Blind carbon copy recipients | Array of valid emails |
CC RecipientsOptional | ["cc1@example.com","cc2@example.com"] | Carbon copy recipients | Array of valid emails |
TagsOptional | [{"name":"category","value":"newsletter"}] | Tags for categorization/analytics | Array of tag objects |
AttachmentsOptional | See structure below | Files to include with the email | Array of attachment objects |
HTML CONTENT or TEXT CONTENT
You can send either HTML Content, or Text Content. However, at least one is required.
Attachments structure
| Field | Example input | Description | Restrictions |
|---|---|---|---|
filename | "invoice.pdf" | File name as it should appear to recipients | — |
attachmentType | "path" | How the attachment is provided | Allowed values: path or content |
pathOptional | "https://example.com/file.pdf" | Public URL to the file when using path | Required when attachmentType is path; mutually exclusive with content |
contentOptional | base64 string | Base64‑encoded file content when using content | Required when attachmentType is content; mutually exclusive with path |
Example output
json
{ "id": "email_1234567890" }Documentation of API endpoint that powers action: Resend API – Send email (POST /emails)
HTML examples
In the majority of practical use cases, you will likely want to send emails using HTML content, as this will allow you to add custom styling, formatting, and elements such as buttons.
Below are example HTML templates for some common emails. To work correctly, use them in a binding for the HTML content of an email and replace variables like {{name}}, {{magicLink}}, and {{resetLink}} with your dynamic values (e.g., the value of a variable or input).
Welcome email
Welcome email HTML
html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Welcome to [Product Name]</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="x-apple-disable-message-reformatting" />
<style>
body {
margin: 0;
background: #f3f4f6;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
color: #111827;
}
a { color: #2563eb; }
.wrapper {
width: 100%;
background: #f3f4f6;
padding: 32px 16px;
}
.container {
max-width: 560px;
margin: 0 auto;
background: #ffffff;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.07);
}
.header {
background: #111827;
color: #ffffff;
text-align: center;
padding: 28px 24px 20px;
}
.header h1 {
margin: 0;
font-size: 20px;
letter-spacing: -0.01em;
}
.header p {
margin: 8px 0 0;
font-size: 14px;
opacity: 0.9;
}
.content {
padding: 28px 24px 32px;
}
.content h2 {
margin-top: 0;
font-size: 18px;
}
.btn {
display: inline-block;
background: #2563eb;
color: #ffffff !important;
text-decoration: none;
padding: 11px 20px;
border-radius: 6px;
font-weight: 600;
font-size: 14px;
margin-top: 16px;
}
.footer {
text-align: center;
font-size: 12px;
color: #6b7280;
margin-top: 20px;
padding: 0 16px 16px;
}
.muted {
color: #6b7280;
font-size: 14px;
}
.small {
font-size: 12px;
color: #6b7280;
}
@media (max-width: 600px) {
.content, .header {
padding-left: 16px;
padding-right: 16px;
}
.btn {
display: block;
text-align: center;
width: 100%;
}
.wrapper {
padding: 16px 8px;
}
}
</style>
</head>
<body>
<div style="display:none;font-size:1px;color:#fff;line-height:1px;max-height:0;max-width:0;opacity:0;overflow:hidden;">
Welcome to [Product Name]! Here's how to get started.
</div>
<div class="wrapper">
<div class="container">
<div class="header">
<h1>[Product Name]</h1>
<p>Welcome aboard</p>
</div>
<div class="content">
<p class="muted">Hi {{name}},</p>
<p>Thanks for creating an account with <strong>[Product Name]</strong>. We're excited to have you with us! Let's set up your workspace so you can get started right away.</p>
<h2>Step 1: Open your dashboard</h2>
<p>Everything begins there — you'll find your projects, tools, and first setup steps.</p>
<p>
<a href="{{action_url}}" class="btn" style="background-color: #2563eb; color: #ffffff; text-decoration: none;" target="_blank" rel="noopener">Go to my dashboard</a>
</p>
<p style="margin-top: 28px;">
Need a hand? Our team is happy to help — just <a href="mailto:{{support_email}}">email support</a>.
</p>
<p style="margin-top: 26px;">
Talk soon,<br />
<strong>[Sender Name]</strong><br />
The [Product Name] Team
</p>
<p class="small" style="margin-top: 18px;">
P.S. Want a quick walkthrough? Visit our getting started guide: <a href="{{help_url}}">{{help_url}}</a>
</p>
<p class="small" style="margin-top: 14px;">
If the button above doesn't work, paste this into your browser:<br />
{{action_url}}
</p>
</div>
</div>
<div class="footer">
<p>[Company Name, LLC] · 1234 Street Rd. · Suite 1234<br />
If you didn't create this account, you can safely ignore this email.</p>
</div>
</div>
</body>
</html>Reset password
Reset password HTML
html
<p style="margin:0 0 12px">Hi {{name}},</p>
<p style="margin:0 0 16px">Use the link below to reset your password. This link expires soon.</p>
<a href="{{resetLink}}" style="display:inline-block;padding:10px 14px;background:#111;color:#fff;text-decoration:none;border-radius:6px">Reset password</a>
<p style="margin:12px 0 0;font-size:12px;color:#666">If you didn’t request this, you can safely ignore this email.</p>Error handling
| Error code and type | Reason |
|---|---|
| 401 Unauthorized | Invalid or missing API key. |
| 400 Bad Request | Invalid parameters (e.g., malformed email addresses, subject length, payload shape). |
| 403 Forbidden | Domain/sender not verified or API key restricted; sending to non-self recipients is blocked. |
| 429 Too Many Requests | Rate limiting encountered; reduce concurrency and retry with backoff. |
FAQs
Why do I get a 403 error when sending?
Resend restricts sends to your own email address until you verify a domain or sender. Verify the domain/sender in the Resend dashboard to send to other recipients.
To send test emails without yet verifying your domain, you can use the email onboarding@resend.dev for the from email, and the email of your Resend account as the to email.
Should I send HTML or Text?
If you wish to quickly test sending or do not care for custom styling, opt for Text Content. If custom styling is important, then opt for HTML Content (however, keep HTML simple (inline styles, minimal layout) and avoid heavy markup.)
How can I track delivery, opens, and clicks?
If you wish to monitor this data, refer to your Resend dashboard.
How do I insert dynamic content in emails?
Use HTML Content for your email sending and bind its content. You can then place dynamic content such as the values of variables and inputs inside the content of emails.

