Skip to main content

What are inline images?

Inline images (also called embedded images) are images that appear directly within your email content, rather than as attachments. They’re referenced using a special cid: (Content-ID) URL scheme in your HTML, making them ideal for:
  • Email signatures: Company logos and branding
  • Transactional emails: Product images, receipts, invoices
  • Branded templates: Headers, footers, and design elements
  • Rich content: Diagrams, charts, and visual elements
Inline images are embedded in the email itself, so recipients see them immediately without downloading attachments—even with images disabled in some email clients.

How inline images work

  1. Attach an image with a unique Content-ID
  2. Reference the image in your HTML using cid:your-content-id
  3. Email clients display the image inline when rendering the email
The Content-ID acts as a unique identifier linking your HTML image references to the actual image data.

Sending inline images via API

Basic example

curl -X POST https://api.lettermint.co/v1/send \
  -H "x-lettermint-token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "sender@yourdomain.com",
    "to": ["recipient@example.com"],
    "subject": "Welcome to our service",
    "html": "<h1>Welcome!</h1><img src=\"cid:logo\" alt=\"Company Logo\">",
    "attachments": [
      {
        "filename": "logo.png",
        "content": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
        "content_id": "logo"
      }
    ]
  }'
The content field must be base64-encoded image data. Most programming languages provide built-in functions for base64 encoding files.

Multiple inline images

You can embed multiple images by using different Content-IDs for each:
curl -X POST https://api.lettermint.co/v1/send \
  -H "x-lettermint-token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "sender@yourdomain.com",
    "to": ["recipient@example.com"],
    "subject": "Your order receipt",
    "html": "<div><img src=\"cid:header\"><h1>Order Confirmation</h1><img src=\"cid:product-image\"><p>Thank you for your order!</p><img src=\"cid:footer\"></div>",
    "attachments": [
      {
        "filename": "header.png",
        "content": "...",
        "content_id": "header"
      },
      {
        "filename": "product.jpg",
        "content": "...",
        "content_id": "product-image"
      },
      {
        "filename": "footer.png",
        "content": "...",
        "content_id": "footer"
      }
    ]
  }'

Sending inline images via SMTP

When using SMTP, the email library handles Content-ID headers automatically for inline attachments.

Nodemailer (Node.js)

const nodemailer = require('nodemailer');
const fs = require('fs');

const transporter = nodemailer.createTransporter({
  host: 'smtp.lettermint.co',
  port: 587,
  auth: {
    user: 'lettermint',
    pass: 'your-api-token'
  }
});

await transporter.sendMail({
  from: 'sender@yourdomain.com',
  to: 'recipient@example.com',
  subject: 'Email with inline image',
  html: '<h1>Hello!</h1><img src="cid:unique-image-id" alt="Embedded Image">',
  attachments: [
    {
      filename: 'image.png',
      path: './path/to/image.png',
      cid: 'unique-image-id' // Content-ID reference
    }
  ]
});

PHPMailer (PHP)

<?php
use PHPMailer\PHPMailer\PHPMailer;

$mail = new PHPMailer(true);

$mail->isSMTP();
$mail->Host = 'smtp.lettermint.co';
$mail->SMTPAuth = true;
$mail->Username = 'lettermint';
$mail->Password = 'your-api-token';
$mail->Port = 587;

$mail->setFrom('sender@yourdomain.com');
$mail->addAddress('recipient@example.com');
$mail->Subject = 'Email with inline image';
$mail->isHTML(true);
$mail->Body = '<h1>Hello!</h1><img src="cid:unique-image-id" alt="Embedded Image">';

// Add inline image
$mail->addEmbeddedImage('/path/to/image.png', 'unique-image-id', 'image.png');

$mail->send();

Python (smtplib)

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage

msg = MIMEMultipart('related')
msg['From'] = 'sender@yourdomain.com'
msg['To'] = 'recipient@example.com'
msg['Subject'] = 'Email with inline image'

# HTML content
html = '<h1>Hello!</h1><img src="cid:unique-image-id" alt="Embedded Image">'
msg.attach(MIMEText(html, 'html'))

# Inline image
with open('image.png', 'rb') as img:
    image = MIMEImage(img.read())
    image.add_header('Content-ID', '<unique-image-id>')
    msg.attach(image)

# Send email
with smtplib.SMTP('smtp.lettermint.co', 587) as server:
    server.starttls()
    server.login('lettermint', 'your-api-token')
    server.send_message(msg)

Content-ID format requirements

Content-IDs must follow these rules:
  • Allowed characters: Letters (a-z, A-Z), numbers (0-9), dots (.), underscores (_), hyphens (-), and at-signs (@)
  • Pattern: Must match ^[a-zA-Z0-9._@-]+$
  • Maximum length: 255 characters
  • Automatic suffix: If your Content-ID doesn’t include @, Lettermint automatically appends @lm to ensure RFC compliance

Valid Content-ID examples

  • logo
  • company-logo
  • header_image
  • product.image.v2
  • banner@example.com
  • invoice-2024-01

Invalid Content-ID examples

  • logo image (spaces not allowed)
  • product#123 (# symbol not allowed)
  • header!image (! symbol not allowed)
  • logo/banner (/ symbol not allowed)
Use descriptive, semantic Content-IDs like company-logo or product-image instead of generic names like image1 or img. This makes your email templates more maintainable.

Troubleshooting

Image not displaying

Check your Content-ID reference
  • Ensure your HTML uses cid:your-content-id (note the cid: prefix)
  • Verify the Content-ID in your attachment matches the HTML reference exactly (case-sensitive)
  • Don’t include angle brackets (<>) in your Content-ID when using the API
Verify base64 encoding
  • The content field must contain valid base64-encoded image data
  • Test your base64 string with an online decoder to ensure it’s valid
Check HTML syntax
<!-- Correct -->
<img src="cid:logo" alt="Logo">

<!-- Incorrect -->
<img src="logo" alt="Logo">
<img src="cid:<logo>" alt="Logo">

Image appears as attachment

If your inline image also appears as a downloadable attachment:
  • Ensure you’re setting content_id in your API request
  • For SMTP, verify your email library supports inline attachments (check library-specific documentation)

Content-ID validation errors

If you receive validation errors:
  • Remove special characters except dots, underscores, hyphens, and @
  • Keep Content-IDs under 255 characters
  • Use only alphanumeric characters if unsure

Best practices

  1. Use descriptive Content-IDs: Choose meaningful names that describe the image’s purpose
  2. Optimize image sizes: Keep images small to reduce email size and improve deliverability
  3. Provide alt text: Always include alt attributes for accessibility and when images are blocked
  4. Test across email clients: Different email clients handle inline images differently—test thoroughly
  5. Consider fallbacks: Some email clients block images by default—design emails that work without them

Summary

Inline images let you embed visual content directly in your emails using Content-ID references. By attaching images with a content_id and referencing them with cid: in your HTML, you create rich, professional emails that display consistently across email clients. For more examples and implementation details, check out our SDK documentation or explore the API reference.