Send emails using a Resend hosted template. The template (layout, branding, subject) lives in the Resend dashboard; this action passes the template id and the variables, and Resend renders and sends the email.
It mirrors the template_id + dynamic_template_data model of the old SendGrid action,
with one addition that works around a Resend limit (see Long values below).
- A verified sending domain in Resend (Settings → Domains).
- A published template in Resend; note its id or alias.
- A Resend API key stored as a secret in the consuming repository.
| Input | Required | Description |
|---|---|---|
resend_api_key |
yes | Your Resend API key. |
to |
yes | Recipient address(es), comma-separated. Max 50. |
from |
yes | Sender, e.g. Acme <noreply@your-verified-domain.com>. |
template_id |
yes | Resend template id or alias. |
subject |
no | Overrides the template's default subject when set. |
dynamic_template_data |
no | Newline-separated env var names → template variables (each ≤ 2000 chars). |
chunked_template_data |
no | Newline-separated env var names for large values (see below). |
chunk_slots |
no | Slots per chunked variable. Default 20 (~38k chars). |
cc / bcc |
no | Extra recipients, comma-separated. |
reply_to |
no | Reply-To address(es), comma-separated. |
Like the SendGrid action, dynamic_template_data lists the names of environment
variables; the value of each is read from the environment at run time. On success the
action logs Email sent successfully. Id: <id>; on any failure it fails the step with a
clear message — it never reports success for a send that did not go out.
Resend caps every template variable value at 2,000 characters. Release notes routinely
exceed that. Rather than truncate, list such variables under chunked_template_data: the
action splits each value into chunk_slots pieces — release_notes_1, release_notes_2, …
— each safely under the limit. Because the pieces are concatenated with no separator,
your template reproduces the original value exactly:
Notes:
- Use triple braces
{{{ }}}so HTML in the value renders instead of being escaped. - Keep the placeholders adjacent (no spaces/newlines between them) or the value won't reconstruct.
- The count must match
chunk_slots(default 20). If a value needs more slots than available, the action fails with a clear message — raisechunk_slotsand add matching placeholders. - Empty trailing slots render to nothing, so short values are fine too.
- name: Send release email
uses: liquidlab-agency/resend-action@master
env:
client_name: ${{ env.CLIENT_NAME }}
release_version: ${{ inputs.tag_name }}
release_notes: ${{ steps.html_convert.outputs.result }} # full HTML, any length
with:
resend_api_key: ${{ secrets.RESEND_API_KEY }}
from: 'LiquidLab <releases@your-verified-domain.com>'
to: ${{ vars.RELEASE_RECIPIENTS }}
template_id: ${{ vars.RESEND_RELEASE_EMAIL_TEMPLATE_ID }}
dynamic_template_data: |
client_name
release_version
chunked_template_data: |
release_notesA workflow_dispatch workflow (Manual Resend Test) is included. Add the
RESEND_API_KEY secret, then run it from the Actions tab to send a real test
email against a template id with values you type into the form.