Embedding Images in Power Automate Emails: A Cross-Client Compatibility Guide
Discover the trade-offs between Content-ID, Base64, and the Microsoft Graph API for embedding images in Power Automate emails. This guide covers which method works best for Outlook, Gmail, and more.
When building automated email notifications with Power Automate, ensuring embedded images render correctly across all clients is a surprisingly complex problem. An image that displays perfectly in Outlook Desktop might appear as a broken link or a download prompt in Gmail or Outlook Web. Having worked through these challenges with both Standard and Premium licensing, I want to share three battle-tested strategies for embedding images inline, along with the exact trade-offs each one presents.
The Example Scenario
Let's imagine a company, Contoso, wants to send a weekly project status report. The email must include a branded header image stored in a SharePoint document library named ProjectAssets. The file we will work with is called Contoso-Banner.png.
The goal is to have this image appear inline in the email body, not as a downloadable attachment.
Method 1: The Content-ID (CID) Approach
The Content-ID approach is the most universally compatible method available with Standard licenses. It works by attaching the image file to the email and then referencing that attachment in the HTML body.
Step-by-Step Flow:
- Trigger the flow (e.g., on a schedule).
- Get file content using path: Retrieve
Contoso-Banner.pngfrom theProjectAssetslibrary. - Compose: Build the HTML image tag. The
cid:value must exactly match the attachment name. - Send an email (V2):
- To: Recipient.
- Subject: Weekly Project Status Report.
- Is HTML: Yes.
- Body: Output of the Compose action.
- Attachments: Add
Contoso-Banner.pngusing the file content from step 2.
Compatibility:
- ✅ Outlook Desktop (Classic & New)
- ✅ Outlook mobile (iOS, Android)
- ✅ Outlook Web App (OWA)
- ✅ Gmail
The Catch: An attachment paperclip icon will appear in the recipient's inbox alongside the subject line. This is a known limitation of the standard Send Email connector when using CID.
Method 2: The Base64 Data URI Method
If you need to eliminate the attachment icon completely without upgrading to Premium, the Base64 Data URI method is your only option—but it comes with significant compatibility restrictions.
Step-by-Step Flow:
- Get file content using path: Retrieve
Contoso-Banner.png. - Compose: Use the Power Automate
dataUri()expression to embed the image directly in the HTML.
- Send an email (V2):
- Body: The compose output.
- Do not add the image as an attachment.
Compatibility:
- ✅ Outlook Desktop (Classic & New)
- ✅ Outlook mobile (iOS, Android)
- ⌠Outlook Web App (OWA)
- ⌠Gmail
Before using the Data URI method, verify which email clients your recipients use. It fails silently on OWA and Gmail, displaying no image at all.
The Catch: Major web-based email clients deliberately block inline Base64 images for security and rendering reasons. Only use this method if you are certain your recipients use fully compatible desktop clients.
Method 3: Hidden Content-ID via Microsoft Graph API
For flows running on a Premium license, calling the Microsoft Graph API directly provides the definitive solution. It combines the universal compatibility of the CID method with the clean, attachment-free appearance of the Base64 method.
Step-by-Step Flow:
- Get file content using path.
- Compose: Build the HTML with the
cid:reference exactly as in Method 1.
- Invoke an HTTP Request: Replace the standard Send Email action.
- Method: POST
- URI:
https://graph.microsoft.com/v1.0/me/sendMail - Headers:
Content-Type: application/json - Body: The specific JSON structure that defines the attachment as inline.
{
"message": {
"subject": "Weekly Status Report from Contoso",
"body": {
"contentType": "HTML",
"content": "@{outputs('Compose_Image_Tag')}"
},
"toRecipients": [
{
"emailAddress": {
"address": "recipient@contoso.com"
}
}
],
"attachments": [
{
"@odata.type": "#microsoft.graph.fileAttachment",
"name": "Contoso-Banner.png",
"contentBytes": "@{body('Get_file_content_using_path')?['$content']}",
"contentType": "@{body('Get_file_content_using_path')?['$content-type']}",
"isInline": true
}
]
}
}Compatibility:
- ✅ Outlook Desktop (Classic & New)
- ✅ Outlook mobile (iOS, Android)
- ✅ Outlook Web App (OWA)
- ✅ Gmail
- ✅ No attachment icon
The Microsoft Graph API approach requires a Power Automate Premium license. The standard Send an email (V2) action cannot hide the attachment icon.
Security and Performance Considerations
- Graph API Scopes: When using the Invoke an HTTP Request action with Microsoft Entra ID, the connection uses delegated permissions. Ensure the application registration has the
Mail.Sendscope. If you need to send mail as a shared mailbox, use the user ID in the URI:https://graph.microsoft.com/v1.0/users/{user-id}/sendMail. - Image Size: For the Base64 Data URI method, the image content is directly embedded in the email body. Power Automate standard limits apply (8 MB total). An image larger than 1 MB can cause delays or rejections in some email clients. Stick to optimized web-resolution images (72 DPI, 600px width).
- Encoding Check: The
Get file content using pathaction returns a JSON object. When referencing the binary content, always use?['$content']to extract the Base64-encoded bytes.
Common Mistakes and Troubleshooting
1. CID Mismatch
The most frequent error with Methods 1 and 3 is a mismatch between the attachment name and the cid: value in the HTML. The attachment name and the cid: value must be exactly identical, including the file extension. Even a single character difference will cause the image to break.
2. Base64 Size Limits Very large images embedded via Base64 can trigger size limits in Standard connectors or cause email clients to reject the entire message. Keep embedded images under 1 MB for best results.
3. Graph API Permissions
The Invoke an HTTP Request action requires the Mail.Send permission for the signed-in user. If the flow fails with a 403 Forbidden error, check the API permissions granted to the Microsoft Entra ID application used by the connection.
4. "Sent" Folder Confusion Emails sent via the Graph API (Method 3) will appear in the sent items folder of the authenticated user, exactly as if they sent it manually. The Standard connector also sends from the user's mailbox.
Final Recommendation
Which method should you build into your production flow?
- Standard License + Must work everywhere: Use Content-ID. The attachment icon is a small price to pay for full compatibility.
- Standard License + No icon required + Controlled client base: Use Base64/Data URI. Ideal for internal apps where only desktop Outlook is used.
- Premium License (The Best Experience): Use the Graph API with
isInline. It delivers the image perfectly in every client without the attachment icon. - Building a proof of concept: Start with Content-ID. It is the fastest to configure and debug, and you can always migrate to the Graph API later.
References
- Original research by Matthew Devaney: Easiest Power Automate Embed Image In Email Method
- Microsoft Graph API sendMail documentation: Microsoft Learn
- Data URI scheme: MDN Web Docs