How to Send an Email with Embedded Image in Power Automate Easily 2026
By Impran M NLast checked against official docs
An image that shows up as a paperclip attachment instead of sitting inline in the email body looks unfinished, especially for automated reports or notifications you want to look intentional. Power Automate can embed an image directly into the HTML body without attaching it or hosting it anywhere public, using a short chain of actions: pull the file content, convert it to a data URI with the dataUri() expression, then drop that string into an img tag. This guide follows that flow screen by screen, and flags the one mainstream client, Gmail, where this exact technique doesn't render at all.
Before you start
- The image file already stored somewhere Power Automate can read it, such as OneDrive or SharePoint
- An email action with an HTML body option, such as Send an email (V2)
01Start the flow from the Create page
Open Create in Power Automate and choose to build an instant cloud flow if you want to trigger it manually for testing, or pick a trigger that matches your real use case. The "Build an instant cloud flow" dialog lists a long set of trigger options beyond the obvious manual button: SharePoint events, HTTP requests, webhooks, and more, scrollable in a panel on the right. For this walkthrough the flow starts with "Manually trigger a flow," which is the simplest way to test the email-building logic before wiring it to a real trigger.

02Get the image file's content
Add a "Get file content" action pointed at wherever the image lives, OneDrive or SharePoint are the common choices, and this pulls the raw file bytes into the flow as an output you can reference in later steps. This step alone doesn't do anything with the image yet; it just makes the binary data available to whatever comes next in the chain.
03Convert the file into a data URI with Compose
This is the step that makes inline embedding work. A Compose action takes the file content from the previous step and wraps it with the dataUri() expression, which converts the binary image data into a base64-encoded data URI string: the kind of value you'd normally see as a very long "data:image/png;base64,..." string.
That single string is everything an img tag needs to render the picture without linking out to any external file or attaching it separately. In the flow shown, this Compose step briefly flagged "Invalid parameters" until the file content reference was correctly wired into its Inputs field. That's the most common cause if your Compose step shows the same warning.

04Store the data URI in a variable
Add an "Initialize variable" action after Compose and set its value to the Compose output. This isn't strictly required, you could reference the Compose output directly in the email body, but it keeps the HTML template easier to read, since you're inserting a short variable name into your img src attribute instead of a Compose reference buried in expression syntax. It also makes the flow easier to debug, since you can inspect the variable's run history separately from the Compose step.
05Reference the data URI inside your HTML email body
In your "Send an email (V2)" action, switch the body to HTML mode and write an img tag whose src attribute points to the variable you just initialized, something like <img src="@{variables('ImageDataUri')}" />. Because the data URI contains the full image data as text, the email client renders it inline directly from the HTML: no attachment, no external image request, and nothing that can break because a hosted file got moved or deleted later.

06Test the flow, especially in Gmail
Run the flow and open the resulting email in more than one client if you can. Outlook desktop renders a data URI image without issue, and so does Outlook on iOS.
Gmail is the exception: it strips data-URI images out of HTML email as an anti-abuse measure, so an image that looks perfect in Outlook can simply not appear at all for a Gmail recipient. This isn't a flow bug or a rendering glitch; it's a deliberate filter on Gmail's side. If any of your recipients read mail in Gmail, test there specifically before relying on this method, and consider a Content-ID (CID) attachment instead for that audience.
When it doesn't work
Compose shows 'Invalid parameters'
Why: The Inputs field isn't wired to the Get file content action's output.
Fix: Click into Compose's Inputs field, pick File Content from Get file content's dynamic content list, and wrap it as dataUri(body('Get_file_content')).
The image renders in Outlook but never shows up for a Gmail recipient
Why: Gmail strips data-URI (base64) images from HTML email; this is a client-side filter, not a flow error.
Fix: For Gmail recipients, attach the image and reference it by Content-ID (CID) instead of a data URI.
The email arrives with a broken image icon even in a client that supports data URIs
Why: Initialize variable's Value field isn't pointed at Compose's output, often because it references Get file content directly instead.
Fix: Check that Initialize variable's Value field references the Compose action's output, not the raw file content.
Frequently asked questions
What's the difference between a data URI and a CID reference for embedding images?
A data URI encodes the whole image as base64 text directly inside the HTML, built here with dataUri(), so nothing else needs to load. A CID reference attaches the image to the same email and points to it by content ID; it's the more broadly compatible option, including for Gmail, but means managing an attachment alongside the HTML.
Will embedded images work in every email client?
No. Outlook desktop and Outlook on iOS render a data URI image without issue, but Gmail strips data-URI images from HTML email as a security measure, so Gmail recipients won't see it at all. Test with the actual clients your recipients use before relying on this method broadly.
Can I use this for automated newsletters or reports?
Yes, as long as none of your recipients read mail in Gmail, or you fall back to a CID attachment for the ones who do. This same Get file content → Compose → Send an email (V2) pattern works well for branded report headers and notification logos otherwise.
Why did my Compose action show 'Invalid parameters'?
This usually means the Inputs field isn't correctly wired to the Get file content output yet. Confirm the dataUri() expression references the right file content field before running the flow.
Do I need coding skills to build the HTML email?
Basic HTML knowledge helps for writing the img tag and structuring the body, but the data URI conversion itself is handled entirely by the dataUri() expression inside Compose, no scripting required.
Sources and last check
Click path and screens come from the original recording. The expression name was corrected: the flow uses dataUri(), not dataUriBody() as the earlier version of this guide called it everywhere the term appeared. That correction, and the base64/data-URI approach itself, were checked against Microsoft's official Power Automate and Logic Apps documentation in September 2026. The Gmail limitation isn't documented by Microsoft; it's a widely reported behavior (Gmail strips data-URI images from HTML email), added here because it directly affects whether this method works for a reader's actual recipients.
About the author

Impran M N
I've been hooked on technology for as long as I can remember — especially the new tools and AI apps that seem to land every other week. Easy Tech Tuts is where I write up whatever I've just worked out: I do the task in the real product, record the screen, and turn it into the guide I wish I'd found first.



