Skip to main content
The media manager allows you to upload images and files for use in email campaigns and templates. Media can be stored on the local filesystem or in S3-compatible cloud storage.

Media Data Model

Each media file has:
  • ID: Unique numeric identifier
  • UUID: Unique universal identifier
  • Filename: Sanitized filename
  • Content Type: MIME type (e.g., image/jpeg, image/png)
  • Provider: Storage provider (filesystem or s3)
  • Thumb: Thumbnail filename (auto-generated for images)
  • Meta: JSONB metadata (width, height for images)
  • URL: Full public URL to access the file
  • Created At: Upload timestamp

Uploading Media

1

Navigate to Media

Click Media in the main menu
2

Upload File

  • Click Upload button
  • Select file(s) from your computer
  • Multiple files can be uploaded at once
3

Use in Campaigns

  • Copy media URL
  • Insert into campaign content
  • Or use media picker in visual editor

Supported File Types

Configure allowed extensions in Settings → Upload:

Default Extensions

["jpg", "jpeg", "png", "gif", "svg", "*"]
  • jpg, jpeg: JPEG images (thumbnail generated)
  • png: PNG images (thumbnail generated)
  • gif: GIF images (thumbnail generated)
  • svg: Vector graphics (no thumbnail, uses original)
  • *: Wildcard to allow all file types
Remove * from the list to restrict uploads to specific extensions only

File Size Limits

Configure maximum file size in Settings → Upload → Max File Size:
  • Default: 5000 KB (5 MB)
  • Enforced during upload
  • Returns error if exceeded

Image Processing

Images are automatically processed during upload:

Thumbnail Generation

1

Image Validation

Uploaded file is validated as a valid image format
2

Dimension Detection

Original image width and height are detected
3

Thumbnail Creation

Thumbnail is generated:
  • Max width: 250px
  • Height: Proportional (maintains aspect ratio)
  • Format: PNG
  • Algorithm: Lanczos resampling
4

Storage

Both original and thumbnail are saved:
  • Original: filename.jpg
  • Thumbnail: thumb_filename.jpg

Image Metadata

Image files include metadata:
{
  "width": 1920,
  "height": 1080
}
Stored in the meta JSONB field for quick access without reading the file.

Vector Graphics (SVG)

SVG files are handled specially:
  • No thumbnail generation
  • Thumbnail URL points to original file
  • No dimension metadata
  • Served as-is

Storage Providers

Local Filesystem Storage

Store media files on the server’s local filesystem.Configuration:Settings → Upload → Provider: filesystem
{
  "upload.provider": "filesystem",
  "upload.filesystem.upload_path": "uploads",
  "upload.filesystem.upload_uri": "/uploads"
}
Settings:
  • Upload Path: Directory to store files (relative or absolute)
  • Upload URI: Public URL path to access files
File URLs:
http://localhost:9000/uploads/image.jpg
http://localhost:9000/uploads/thumb_image.jpg
Pros:
  • Simple setup
  • No external dependencies
  • Fast local access
  • No additional costs
Cons:
  • Not scalable for distributed systems
  • Requires disk space on server
  • No built-in CDN
  • Backups needed

Using Media in Campaigns

In HTML Content

Insert media URLs directly into HTML:
<img src="http://localhost:9000/uploads/image.jpg" alt="Description">

In Templates

Embed media in templates:
<div class="header">
  <img src="http://localhost:9000/uploads/logo.png" alt="Logo" width="200">
</div>

<div class="content">
  {{ template "content" . }}
</div>

In Rich Text Editor

Use the image insertion tool:
  1. Click image icon in toolbar
  2. Select from uploaded media
  3. Or paste URL directly

Attaching to Campaigns

Attach media to campaigns for tracking:
{
  "name": "Newsletter",
  "subject": "Latest Updates",
  "media": [1, 2, 3]
}
Attached media is tracked in campaign_media table for analytics.

Managing Media

Viewing Media

List all uploaded media:
curl -u 'username:password' 'http://localhost:9000/api/media'
With pagination and search:
curl -u 'username:password' 'http://localhost:9000/api/media?query=logo&page=1&per_page=20'

Searching Media

Search by filename:
  • Use the search box in admin interface
  • Or ?query= parameter in API
  • Searches filename field

Deleting Media

Deleting media removes files from storage and database. URLs in sent campaigns will break.
1

Delete from Admin

Select media item and click Delete button
2

Confirm Deletion

System confirms deletion intent
3

Files Removed

Both original and thumbnail are deleted from storage
4

Database Updated

Media record removed from database Campaign-media relationships preserved with filename
API deletion:
curl -u 'username:password' -X DELETE 'http://localhost:9000/api/media/1'

Filename Handling

Sanitization

Filenames are automatically sanitized during upload:
  • Non-ASCII characters removed
  • Spaces converted to underscores
  • Special characters stripped
  • Extension preserved
Example:
Original: "My Photo (2024).jpg"
Sanitized: "my_photo_2024.jpg"

Duplicate Handling

If a filename already exists:
  1. Check database for existing filename
  2. Generate random 6-character suffix
  3. Append to filename before extension
Example:
Original upload: image.jpg
Duplicate upload: image_a3f9k2.jpg

Serving S3 Media

For S3 storage with relative public URLs:

Direct S3 URLs

If public_url is set to full domain:
https://cdn.example.com/image.jpg

Proxied URLs

If public_url is relative path:
/s3/image.jpg
listmonk proxies requests:
  1. Request to /s3/image.jpg
  2. Fetched from S3
  3. Served through listmonk
  4. Content-Type auto-detected
Proxying adds latency. Use CDN with full URLs for better performance.

Database Schema

CREATE TABLE media (
    id               SERIAL PRIMARY KEY,
    uuid             UUID NOT NULL UNIQUE,
    provider         TEXT NOT NULL DEFAULT '',
    filename         TEXT NOT NULL,
    content_type     TEXT NOT NULL DEFAULT 'application/octet-stream',
    thumb            TEXT NOT NULL,
    meta             JSONB NOT NULL DEFAULT '{}',
    created_at       TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX idx_media_filename ON media(provider, filename);

Campaign-Media Relationship

CREATE TABLE campaign_media (
    campaign_id  INTEGER REFERENCES campaigns(id) ON DELETE CASCADE,
    media_id     INTEGER NULL REFERENCES media(id) ON DELETE SET NULL,
    filename     TEXT NOT NULL DEFAULT ''
);
  • Links campaigns to attached media
  • Preserves filename even if media is deleted
  • Used for tracking media usage

Performance Considerations

Thumbnails

Faster Loading

Thumbnails load quickly in admin interface and media picker

Reduced Bandwidth

Smaller file sizes for preview purposes

Better UX

Instant preview without loading full images

Consistent Size

Uniform thumbnail dimensions for clean layouts

CDN Integration

For S3 storage, use CDN for optimal performance:
  1. Set up CloudFront, Cloudflare, or similar
  2. Point CDN to S3 bucket
  3. Set upload.s3.public_url to CDN domain
  4. Media URLs will use CDN automatically
Example:
{
  "upload.s3.public_url": "https://cdn.example.com"
}
Results in URLs like:
https://cdn.example.com/image.jpg

Security

Extension Filtering

Restrict file types to prevent malicious uploads:
{
  "upload.extensions": ["jpg", "jpeg", "png", "gif", "svg"]
}
Using * wildcard allows any file type. Only enable if you trust all uploaders.

Content Type Validation

Content-Type header is validated during upload:
  • Checked against file extension
  • Stored in database
  • Used when serving files

File Size Limits

Enforce size limits to prevent abuse:
  • Configured in upload.max_file_size (KB)
  • Default: 5 MB
  • Rejected before processing

Troubleshooting

Upload Fails

1

Check File Size

Ensure file is under max_file_size limit
2

Verify Extension

Check if file extension is in allowed list
3

Test Storage

  • Filesystem: Check directory permissions
  • S3: Verify credentials and bucket access
4

Review Logs

Check listmonk logs for specific error messages

Broken Image URLs

  • Verify media still exists in database
  • Check storage provider is accessible
  • For S3: Ensure bucket permissions are correct
  • For filesystem: Verify upload_uri matches web server config

Thumbnails Not Generating

  • Only applies to: JPG, PNG, GIF
  • SVG files use original as thumbnail
  • Check image file is valid format
  • Review upload logs for resize errors

API Reference

Upload Media

POST /api/media
Content-Type: multipart/form-data

[email protected]

Get All Media

GET /api/media?query=search&page=1&per_page=20

Get Single Media

GET /api/media/:id

Delete Media

DELETE /api/media/:id

Best Practices

Optimize Images

Compress images before upload to reduce file sizes and email load times

Use CDN

For S3 storage, integrate a CDN for faster global delivery

Descriptive Names

Use clear, descriptive filenames for easy identification

Regular Cleanup

Periodically remove unused media to save storage space

Backup Media

Ensure media files are included in backup strategy

Restrict Extensions

Limit allowed file types to only what’s needed

Build docs developers (and LLMs) love