How to Send an AI-Personalized Follow-Up Sequence with Resend

Build a Spojit workflow that wakes up every weekday morning, finds the Monday.com leads whose follow-up date is due, drafts a personalized message that references each lead's last activity, and sends it from your own domain through Resend before stamping the CRM so no lead is ever emailed twice.

What This Integration Does

Manual follow-up is where most sales sequences fall apart: someone has to remember who is due, write something that does not read like a template, send it, then update the record so the same person does not get the same email tomorrow. This workflow does all of that on a schedule. Each morning it pulls the leads on a Monday.com board whose follow-up date has arrived, loops over them one by one, and uses Miraxa, the intelligent layer across your automation, to draft a short, specific message that names the lead and references their last logged activity. The email goes out through the Resend connector so it arrives from your own verified domain rather than Spojit's built-in mail service, which keeps deliverability and branding in your control.

A Schedule trigger starts the run on a cron expression in your own timezone. A Connector node on the monday connector reads the leads, a Loop node iterates them, a Condition node skips anyone missing an email, a Connector node in Agent mode drafts the copy, and a Resend send delivers it. The last step writes the new touch count and next follow-up date straight back to Monday.com, so the run leaves clean state behind: tomorrow's query naturally excludes anyone already contacted today. Re-running the workflow on the same day is safe because each lead's follow-up date is advanced the moment its email is sent, so it falls out of the due window.

Prerequisites

  • A Resend connection in Spojit (API key) with a verified sending domain. See the Resend connector article to set this up.
  • A monday connection (API token) and the board ID of the board that holds your leads. Use list-boards once to find the ID if you do not know it.
  • On that board, columns for the lead's email, their last activity note, a numeric touch count, and a date column for the next follow-up. Note each column's ID (visible via get-board).
  • Optionally a Slack connection if you want a daily summary posted to a channel.
  • AI credits available, since the drafting step runs a Connector node in Agent mode.

Step 1: Schedule the run with cron and a timezone

Add a Trigger node and set its type to Schedule. Enter a 5-field Unix cron expression and an IANA timezone so the job fires at the right local hour. For 8am every weekday:

Cron:     0 8 * * 1-5
Timezone: Australia/Sydney

The fields are minute, hour, day-of-month, month, and day-of-week; 1-5 covers Monday through Friday. A single Schedule trigger can hold more than one schedule if you want two send windows. The trigger output is {{ scheduledAt }}, which you can include later as a timestamp. Choose your real timezone here rather than relying on UTC, or the run will drift relative to your team's working hours.

Step 2: Pull the leads that are due today

Add a Connector node on the monday connector in Direct mode and pick the list-items tool. Set boardId to your leads board and limit to the page size you want (the default is 25). The tool returns each item with its column_values, including the follow-up date, last activity, and touch count you mapped in the prerequisites.

Because list-items returns every item on the board, add a Transform node next to keep only the rows that are actually due. In the Transform, walk the returned items and keep those whose follow-up date column is on or before today, producing a clean array your loop can iterate. A compact shape to aim for:

[
  {
    "itemId": "123456",
    "name": "Acme Corp - Dana Lee",
    "email": "dana@acme.example",
    "lastActivity": "Demo call on 12 June, asked about pricing tiers",
    "touchCount": 2,
    "followUpDate": "2026-06-21"
  }
]

Filtering here means the loop only ever touches leads that need an email today, which keeps both Monday.com and AI usage low.

Step 3: Loop over the due leads

Add a Loop node set to ForEach and point it at the array your Transform produced (for example {{ dueLeads }}). Each pass exposes the current lead as the loop item, so inside the loop you can reference fields like {{ lead.email }}, {{ lead.name }}, {{ lead.lastActivity }}, and {{ lead.touchCount }}. Everything in the following steps lives inside this loop so it runs once per lead. If your board can return large pages, iterate in modest batches so a slow downstream step does not stall the whole run.

Step 4: Skip leads that cannot be emailed

Inside the loop, add a Condition node as a guard. Configure the true branch to fire only when the lead has a usable address, for example when {{ lead.email }} is not empty. Route the drafting and sending steps off the true branch; the false branch simply ends that iteration so a row with a missing email never reaches Resend. This keeps the sequence from burning an AI draft and a send attempt on an unreachable record.

Step 5: Draft the personalized message with Miraxa

On the true branch, add a Connector node and switch it to Agent mode. Agent mode lets Miraxa reason over the lead's data and produce tailored copy. Give it a prompt that names the variables explicitly and define a Response Schema so the output is reliable JSON you can map into the email. A prompt to start from:

Write a short, friendly sales follow-up email to {{ lead.name }}.
Reference their last activity: "{{ lead.lastActivity }}".
This is follow-up number {{ lead.touchCount }}, so adjust the tone:
warm and helpful, never pushy. Keep it under 120 words.
Return a subject line and a plain-text body.

Set the Response Schema to force two fields:

{
  "type": "object",
  "properties": {
    "subject": { "type": "string" },
    "body":    { "type": "string" }
  },
  "required": ["subject", "body"]
}

Store the node's output (for example as draft) so the next step can read {{ draft.subject }} and {{ draft.body }}. Agent mode costs AI credits per lead, so the Step 2 filtering and the Step 4 guard directly control your spend.

Step 6: Send from your own domain through Resend

Add a Connector node on the resend connector in Direct mode and pick the send-email tool. This sends from your verified domain rather than Spojit's built-in Send Email node, which is the whole point of using Resend here. Map the fields:

from:    Sales <sales@yourdomain.com>
to:      {{ lead.email }}
subject: {{ draft.subject }}
text:    {{ draft.body }}

If you omit from, Resend uses the default sender configured on the connection, so set a sensible default there too. You can also pass reply_to so replies route to a real inbox. Because the from domain must be verified in Resend, a single unverified domain will fail every send, so confirm verification before turning the workflow on.

Step 7: Stamp the CRM so no lead is emailed twice

Still inside the loop, add a Connector node on the monday connector in Direct mode with the update-item tool. Set boardId and itemId to {{ lead.itemId }}, then pass columnValues keyed by your column IDs to increment the touch count and push the next follow-up date forward (for example seven days out). The shape, using your own column IDs:

{
  "numbers_touch": 3,
  "date_followup": { "date": "2026-06-28" }
}

Compute the new date with the date connector's add tool if you want it relative to today rather than hard-coded. Writing this state is what makes the workflow idempotent: once a lead's follow-up date moves into the future, tomorrow's list-items query no longer returns it, and a same-day re-run skips it too. Optionally end the run with a Slack send-message call posting how many leads were contacted, so the team has a daily record.

Tips

  • Use the date connector (now, add, is-before) for the due check in Step 2 and the next-date math in Step 7 instead of writing date logic by hand.
  • Keep the Agent-mode prompt tight and use the Response Schema; a forced subject and body are far easier to map than free-form prose.
  • Have Miraxa scaffold the canvas for you. Try a prompt like "Add a Loop node over {{ dueLeads }}, a Condition that checks {{ lead.email }} is set, and connect the true branch to a Connector node on resend using send-email", then fine-tune in the properties panel.
  • If your board has many due leads, cap the page size and let the daily cadence work through them rather than blasting hundreds of emails in one run.

Common Pitfalls

  • Timezone drift: a cron with no timezone, or the wrong one, sends at the wrong local hour. Always set the IANA zone in the Schedule trigger.
  • Unverified Resend domain: the from domain must be verified or every send-email call fails. Verify it first and set a default sender on the connection.
  • Forgetting to stamp the CRM: if Step 7 does not advance the follow-up date, the same lead stays in the due window and gets emailed again on the next run.
  • Wrong column IDs: update-item keys columnValues by column ID, not column title. Confirm the IDs with get-board before going live.

Testing

Before scheduling, point the workflow at a small test board with two or three dummy leads, one of them deliberately missing an email so you can confirm the Condition guard skips it. Run it with the Run button instead of waiting for the cron, then check the execution log to confirm list-items returned the right rows, the Agent-mode draft matched each lead, Resend reported a successful send, and update-item advanced the touch count and date. Re-run immediately and verify nobody is emailed twice. Once that passes, enable the Schedule trigger and switch the board ID to your real leads board.

Learn More

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.