Flow.Documentation
Professional

From a CSV to personal e-mails

14 steps± 10 minVideoVerified 22 Oct 2026
  1. Step 1 · Open your development environment
  2. Step 2 · Put your CSV in a table
  3. Step 3 · Name the table and check the columns
  4. Step 4 · Import the rows
  5. Step 5 · Connect Microsoft 365
  6. Step 6 · Fill in your app registration
  7. Step 7 · Create a workflow that fetches the contacts
  8. Step 8 · Show the list as a chat widget
  9. Step 9 · Go through the contacts one by one
  10. Step 10 · Let an AI Colleague write the mail per contact
  11. Step 11 · Give the agent only what it needs
  12. Step 12 · Send the mail with Outlook
  13. Step 13 · Save and run
  14. Step 14 · See what was sent

You have a list of contacts in Excel or as a CSV, and everyone should get their own personal e-mail. In this path you put the list in a table, show it as a chat widget, let a workflow go through the rows one by one, have an AI Colleague write each mail and let Outlook send it. Along the way you connect Microsoft 365. You need: a CSV file and an app registration in Microsoft Entra ID (tenant ID, client ID and client secret).

Watch the whole guide as a video14 steps in one film
Step 1 / 14

Open your development environment

In the portal, under Environments, click Development, and there Open. Flow opens in a new tab and you are signed in straight away.

  1. Click Development
Open your development environment · Click Development
  1. Click Open ↗
Open your development environment · Click Open ↗
Step 2 / 14

Put your CSV in a table

Click + next to General and choose Table from a file. Drop your CSV in the window or click to pick it. Flow recognises the separator and the column names, and shows the first rows before anything is stored.

  1. Click Add to General
Put your CSV in a table · Click Add to General
  1. Click Table from a file (CSV/Excel)
Put your CSV in a table · Click Table from a file (CSV/Excel)
  1. Click the box for your file
Put your CSV in a table · Click the box for your file
Put your CSV in a table · The number of rows and columns, and a preview of your data.
  1. Click Next
Put your CSV in a table · Click Next
Step 3 / 14

Name the table and check the columns

Flow proposes a type per column from what is in it. Untick columns you do not need. That way every next step knows exactly which fields there are.

  1. In Table name, type Mailing contacts
Name the table and check the columns · In Table name, type Mailing contacts
Name the table and check the columns · Every column from your file, with the proposed name and type.
  1. Click Next
Name the table and check the columns · Click Next
Step 4 / 14

Import the rows

Under Security you decide who may see the data; for now you leave it as it is. On Import, Flow checks every row before it goes in. Rows that do not fit are skipped and reported.

  1. Click Next
Import the rows · Click Next
  1. Click Import
Import the rows · Click Import
Import the rows · 5 rows imported.
  1. Click Open table
Import the rows · Click Open table
Import the rows · Your contacts, as rows in the table.
Step 5 / 14

Connect Microsoft 365

Connections are at the bottom of the explorer. Choose Microsoft 365: on the right you see exactly what to arrange in Microsoft Entra ID and which permissions each building block needs. Sending needs Mail.Send.

  1. Click Connections
Connect Microsoft 365 · Click Connections
  1. Click Microsoft 365
Connect Microsoft 365 · Click Microsoft 365
Connect Microsoft 365 · What you need, step by step.
Step 6 / 14

Fill in your app registration

As an app, Flow sends mail on behalf of a mailbox the app may use, without anyone having to be signed in. The client secret is stored encrypted and can never be read back. Choose Read and write: with read only, Flow refuses every step that sends something.

  1. In Name, type Outlook · sales@
  2. In **Tenant ID ***, type fietsenmakerdewit.onmicrosoft.com
  3. In **Client ID ***, type 3f2b9c1e-7a44-4c1d-9e0b-5d6f8a2c4e71
  4. In **Client secret ***, type ••••••••
  5. In Default mailbox, type sales@dewitbikes.com
Fill in your app registration · In Name, type Outlook · sales@; In **Tenant ID ***, type fietsenmakerdewit.onmicrosoft.com; In **Client ID ***, type 3f2b9c1e-7a44-4c1d-9e0b-5d6f8a2c4e71; In **Client secret ***, type ••••••••; In Default mailbox, type sales@dewitbikes.com
  1. Click Read and write
Fill in your app registration · Click Read and write
  1. Click Save
Fill in your app registration · Click Save
Fill in your app registration · The connection, with its key stored safely.
Step 7 / 14

Create a workflow that fetches the contacts

A new workflow starts with a trigger. Add the Table step and choose your contacts table: it looks up every row and passes them on as rows.

  1. Click Add to General
Create a workflow that fetches the contacts · Click Add to General
  1. Click New workflow
Create a workflow that fetches the contacts · Click New workflow
  1. In Workflow name, type Mailing to contacts
Create a workflow that fetches the contacts · In Workflow name, type Mailing to contacts
  1. Click Add node
Create a workflow that fetches the contacts · Click Add node
  1. Click Table
Create a workflow that fetches the contacts · Click Table
  1. In Table, choose Mailing contacts · 5
Create a workflow that fetches the contacts · In Table, choose Mailing contacts · 5
  1. Click the dot of ‘Event trigger’
Create a workflow that fetches the contacts · Click the dot of ‘Event trigger’
  1. Click the dot of ‘Mailing contacts’
Create a workflow that fetches the contacts · Click the dot of ‘Mailing contacts’
Step 8 / 14

Show the list as a chat widget

The Show widget step fills a chat widget with data from the workflow. Give the widget the rows from the table; in the chat, and at the bottom under Output, a neat table then appears instead of raw data.

  1. Click Show widget
Show the list as a chat widget · Click Show widget
  1. In Widget, choose Contact overview · v1
Show the list as a chat widget · In Widget, choose Contact overview · v1
  1. Click Code
Show the list as a chat widget · Click Code
  1. In Data for the widget, type `{
Show the list as a chat widget · In Data for the widget, type `{; ; ;
  1. Click the dot of ‘Mailing contacts’
Show the list as a chat widget · Click the dot of ‘Mailing contacts’
  1. Click the dot of ‘Show widget’
Show the list as a chat widget · Click the dot of ‘Show widget’
Step 9 / 14

Go through the contacts one by one

A Loop repeats the steps in its area for every item in a list. Choose the list rows and call the current item contact: inside the loop the steps then read {{contact.email}} and {{contact.name}}.

  1. Click Loop
Go through the contacts one by one · Click Loop
  1. In Which list do you want to process? The list comes from the previous node., type rows
  2. In Name of the current item Steps read the item as {{contact.naam}}., type contact
Go through the contacts one by one · In Which list do you want to process? The list comes from the previous node., type rows; In Name of the current item Steps read the item as {{contact.naam}}., type contact
  1. Click the dot of ‘Show widget’
Go through the contacts one by one · Click the dot of ‘Show widget’
  1. Click the dot of ‘Loop’
Go through the contacts one by one · Click the dot of ‘Loop’
Step 10 / 14

Let an AI Colleague write the mail per contact

Inside the loop choose Add step → AI agent, and create the writer right away with + New agent. Describe in the instructions what a good mail is, and what is never allowed. Flow tests the agent with sample data and publishes it; workflows always use a published version.

  1. In AI agent, choose AI agent
Let an AI Colleague write the mail per contact · In AI agent, choose AI agent
  1. Click + New agent
Let an AI Colleague write the mail per contact · Click + New agent
  1. In **Name ***, type Mail writer
  2. In What does the agent do?, type Writes a short, personal e-mail to one contact.
  3. In Method Rules (no AI model) Echo (test, no model) Anthropic Claude · not configur, choose Scripted AI (test street)
  4. In **Instructions ***, type Write a friendly e-mail of at most 120 words to the contact, about the interest that is listed. Address the person by first name. Never mention prices and promise nothing.
  5. In **Answer is called ***, type mailtext
Let an AI Colleague write the mail per contact · In **Name ***, type Mail writer; In What does the agent do?, type Writes a short, personal e-mail to one contact.; In Method Rules (no AI model) Echo (test, no model) Anthropic Claude · not configur, choose Scripted AI (test street); In **Instructions ***, type Write a friendly e-mail of at most 120 words to the contact, about the interest that is listed. Address the person by first name. Never mention prices and promise nothing.; In **Answer is called ***, type mailtext
  1. Click Create, test and publish
Let an AI Colleague write the mail per contact · Click Create, test and publish
Let an AI Colleague write the mail per contact · The step uses the published agent, version 1.
Step 11 / 14

Give the agent only what it needs

By default an agent sees all the workflow's data. Choose Only what I choose and pass on just the current contact: less data is safer (GDPR) and cheaper.

  1. Click Only what I choose
Give the agent only what it needs · Click Only what I choose
  1. In Field, type contact
  2. In value, type {{contact}}
Give the agent only what it needs · In Field, type contact; In value, type {{contact}}
Step 12 / 14

Send the mail with Outlook

Inside the loop add Outlook · Send email and choose your Microsoft 365 connection. To becomes the contact's e-mail address, the message is what the agent wrote: the answer in mailtext.answer (next to .outcome, the box's outcome). Leave Mailbox empty: Flow then sends from the default mailbox.

  1. In Outlook · Send email, choose Outlook · Send email
  2. In Connection Choose a connection… Outlook · sales@ + New connection, choose Outlook · sales@
  3. In To * One or more addresses, separated by commas., type {{contact.email}}
  4. In **Subject ***, type Something for {{contact.company}}?
  5. In **Message ***, type {{mailtext.answer}}
Send the mail with Outlook · In Outlook · Send email, choose Outlook · Send email; In Connection Choose a connection… Outlook · sales@ + New connection, choose Outlook · sales@; In To * One or more addresses, separated by commas., type {{contact.email}}; In **Subject ***, type Something for {{contact.company}}?; In **Message ***, type {{mailtext.answer}}
  1. Click the dot of ‘AI agent’
Send the mail with Outlook · Click the dot of ‘AI agent’
  1. Click the dot of ‘Outlook · Send email’
Send the mail with Outlook · Click the dot of ‘Outlook · Send email’
Step 13 / 14

Save and run

At the bottom, under Output, you follow every pass: which contact, what the agent wrote and that Outlook sent the mail. The chat widget is there too, exactly as it appears in the chat.

  1. Click Save
Save and run · Click Save
  1. Click Run
Save and run · Click Run
Save and run · The loop ran 5 times: one mail per contact.
Save and run · The chat widget with your contacts.
Step 14 / 14

See what was sent

Every pass says the mail was sent; under Data after the run you find the result per contact. In Outlook the mails are in the mailbox's Sent Items.

See what was sent · The last mail was sent.
See what was sent · The last contact's address in the run's data.

This guide was carried out step by step on 22 Oct 2026 by an automated test on Flow (version 3e563176).