Skip to main content

Start import

curl -u 'username:password' 'https://listmonk.mysite.com/api/import/subscribers' \
  -F 'file=@subscribers.csv' \
  -F 'params={
    "mode": "subscribe",
    "delim": ",",
    "lists": [1, 2],
    "overwrite": true,
    "subscription_status": "confirmed"
  }'
Starts a bulk subscriber import from a CSV or ZIP file. Authentication: Required
Permission: subscribers:import

Request Body

file
file
required
CSV or ZIP file containing subscriber data (multipart/form-data)
params
string
required
JSON string with import parameters

Import Parameters (params)

mode
string
required
Import mode:
  • subscribe: Import and subscribe to lists
  • blocklist: Import and blocklist subscribers
lists
array
required
Array of list IDs to subscribe/manage (filtered by user permissions)
subscription_status
string
Status for new subscriptions:
  • unconfirmed: Requires opt-in confirmation
  • confirmed: Active subscription
  • unsubscribed: Unsubscribed status
Defaults: unconfirmed for subscribe mode, unsubscribed for blocklist mode
delim
string
default:","
CSV delimiter character (must be a single character)
overwrite
boolean
default:"false"
If true, updates existing subscribers with imported data

CSV Format

The CSV file must have a header row with the following columns: Required columns:
  • email: Email address (required)
Optional columns:
  • name: Subscriber name
  • status: Subscriber status (enabled, disabled, blocklisted)
  • attributes: JSON object with custom attributes
Example CSV:
email,name,status,attributes
john@example.com,John Doe,enabled,"{""city"": ""Bangalore"", ""age"": 30}"
j ane@example.com,Jane Smith,enabled,"{""city"": ""New York""}"
bob@example.com,Bob Johnson,enabled,

Response

data
object
Returns the import status object

Get import status

curl -u 'username:password' 'https://listmonk.mysite.com/api/import/subscribers'
Retrieves the status of the current or last import. Authentication: Required
Permission: subscribers:import

Response

data
object

Get import logs

curl -u 'username:password' 'https://listmonk.mysite.com/api/import/subscribers/logs'
Retrieves detailed logs from the current or last import. Authentication: Required
Permission: subscribers:import

Response

data
string
Returns import log messages as plain text

Stop import

curl -u 'username:password' -X DELETE 'https://listmonk.mysite.com/api/import/subscribers'
Stops an ongoing import or clears the state of a finished import. Authentication: Required
Permission: subscribers:import

Response

data
object
Returns the updated import status

Import Examples

Subscribe Mode

Import subscribers and add them to lists:
curl -u 'username:password' 'https://listmonk.mysite.com/api/import/subscribers' \
  -F 'file=@new-subscribers.csv' \
  -F 'params={
    "mode": "subscribe",
    "lists": [1, 2],
    "subscription_status": "confirmed",
    "delim": ",",
    "overwrite": false
  }'
CSV:
email,name,attributes
john@example.com,John Doe,"{""source"": ""webinar""}"
jane@example.com,Jane Smith,"{""source"": ""webinar""}"

Blocklist Mode

Import and blocklist email addresses:
curl -u 'username:password' 'https://listmonk.mysite.com/api/import/subscribers' \
  -F 'file=@blocklist.csv' \
  -F 'params={
    "mode": "blocklist",
    "lists": [],
    "delim": ","
  }'
CSV:
email
spammer@example.com
abuse@example.com

Update Existing Subscribers

Update subscriber data with overwrite:
curl -u 'username:password' 'https://listmonk.mysite.com/api/import/subscribers' \
  -F 'file=@updates.csv' \
  -F 'params={
    "mode": "subscribe",
    "lists": [1],
    "overwrite": true,
    "delim": ","
  }'
CSV:
email,name,attributes
john@example.com,John Doe Updated,"{""city"": ""San Francisco""}"

Import from ZIP

Import multiple CSV files from a ZIP archive:
curl -u 'username:password' 'https://listmonk.mysite.com/api/import/subscribers' \
  -F 'file=@subscribers.zip' \
  -F 'params={
    "mode": "subscribe",
    "lists": [1],
    "delim": ","
  }'
When importing from ZIP, only the first CSV file in the archive is processed.

Monitoring Import Progress

Poll the import status endpoint to monitor progress:
#!/bin/bash

while true; do
  STATUS=$(curl -s -u 'username:password' \
    'https://listmonk.mysite.com/api/import/subscribers' | \
    jq -r '.data.status')
  
  echo "Import status: $STATUS"
  
  if [ "$STATUS" = "finished" ] || [ "$STATUS" = "failed" ]; then
    break
  fi
  
  sleep 2
done

echo "Import complete!"

Import Behavior

New Subscribers

  • Creates new subscriber records
  • Subscribes to specified lists
  • Sets the specified subscription status

Existing Subscribers

Without overwrite (overwrite: false):
  • Skips existing subscribers
  • Logs as “already exists”
With overwrite (overwrite: true):
  • Updates name if provided
  • Updates attributes (merges with existing)
  • Updates status if provided
  • Adds to new lists without removing from existing lists

Attributes Handling

Attributes in CSV must be valid JSON:
email,name,attributes
user@example.com,User,"{""city"": ""NYC"", ""age"": 30}"
When overwriting:
  • New attributes are merged with existing
  • Existing attribute values are updated
  • Attributes not in CSV are preserved

Validation and Errors

Email Validation

  • Email addresses are validated and sanitized
  • Invalid emails are skipped and logged
  • Duplicate emails in the CSV are ignored

Common Errors

Invalid file format:
{"message": "invalid file: not a CSV or ZIP"}
Invalid delimiter:
{"message": "invalid delimiter: must be a single character"}
Invalid mode:
{"message": "invalid mode: must be 'subscribe' or 'blocklist'"}
Import already running:
{"message": "an import is already running"}

Performance Considerations

Batch Size

Imports are processed in batches (default batch size configured by admin). Large imports may take time.

Concurrent Imports

Only one import can run at a time. Wait for the current import to finish before starting a new one.

Resource Usage

  • Large CSV files are processed line-by-line to minimize memory usage
  • Database writes are batched for efficiency
  • Import progress is persisted and can survive server restarts

Best Practices

  1. Test with small files first: Validate CSV format with a small sample
  2. Clean data: Remove duplicates and invalid emails before import
  3. Use compression: ZIP large CSV files to reduce upload time
  4. Monitor logs: Check logs for errors and warnings
  5. Schedule imports: Run large imports during off-peak hours

Build docs developers (and LLMs) love