Skip to content

Updating visuals

If you see any images containing outdated UI, please bear with us.

We are updating all content as quickly as possible to mirror our new UI.

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

  1. In Resend, create an API key.
  2. In WeWeb, add your Resend API key to the Editor and Production mode. 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.

  1. 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.

  1. Verify your domains in Resend to be able to set a custom from and to email.

Sending test emails

Before verifying your domain, you can send test emails using Resend's test domain:

  1. Set the From Email to onboarding@resend.dev
  2. Set the To Email(s) to your Resend account email address
  3. Fill in your Subject and email content (HTML Content or Text Content)
  4. 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

  1. Click on the HTML Content field in the Send Email action
  2. Click the plug icon beside the field to open the binding window
  3. 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

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):

  1. In the Attachments field, add a new attachment
  2. Set Filename to the name you want recipients to see (e.g., invoice.pdf)
  3. Set Attachment Source to File URL
  4. 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}

Using base64 content

If you have file data as base64 (from a file upload component or generated file):

  1. In the Attachments field, add a new attachment
  2. Set Filename to the name you want recipients to see (e.g., receipt.pdf)
  3. Set Attachment Source to Base64 Content
  4. 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.

ActionDescription
Send EmailSend a transactional email via Resend

Action details

Send Email

Send a transactional email via Resend.

Inputs

Display KeyExample InputDescriptionRestrictions
From Email"onboarding@resend.dev"Sender’s email addressMust 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 lineRecommended limit: ≤ 998 characters
HTML Content
Optional
<p style='margin:0'>Hey {{name}}, here's your magic link: <a href='{{magicLink}}'>Sign in</a></p>HTML content of the emailValid HTML string
Text Content
Optional
"Hello world!"Plain text content of the emailPlain text string
Reply To
Optional
"support@example.com"Reply-to email addressMust be a valid email
BCC Recipients
Optional
["bcc1@example.com","bcc2@example.com"]Blind carbon copy recipientsArray of valid emails
CC Recipients
Optional
["cc1@example.com","cc2@example.com"]Carbon copy recipientsArray of valid emails
Tags
Optional
[{"name":"category","value":"newsletter"}]Tags for categorization/analyticsArray of tag objects
Attachments
Optional
See structure belowFiles to include with the emailArray 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

FieldExample inputDescriptionRestrictions
filename"invoice.pdf"File name as it should appear to recipients
attachmentType"path"How the attachment is providedAllowed values: path or content
path
Optional
"https://example.com/file.pdf"Public URL to the file when using pathRequired when attachmentType is path; mutually exclusive with content
content
Optional
base64 stringBase64‑encoded file content when using contentRequired 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 typeReason
401 UnauthorizedInvalid or missing API key.
400 Bad RequestInvalid parameters (e.g., malformed email addresses, subject length, payload shape).
403 ForbiddenDomain/sender not verified or API key restricted; sending to non-self recipients is blocked.
429 Too Many RequestsRate 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.