listmonk Campaigns API
Create, schedule, test, preview, and send email campaigns to one or more lists, change campaign status, publish to a public archive, and pull running stats and view/click/bounce analytics.
Create, schedule, test, preview, and send email campaigns to one or more lists, change campaign status, publish to a public archive, and pull running stats and view/click/bounce analytics.
openapi: 3.0.1
info:
title: listmonk API
description: >-
REST API for listmonk, the free and open-source, self-hosted newsletter and
mailing-list manager. All endpoints are served by a self-hosted listmonk
instance under the /api path and are secured with HTTP Basic auth using an
API user and token (or an equivalent `Authorization: token api_user:token`
header). There is no hosted SaaS; replace the server host with your own
instance.
termsOfService: https://listmonk.app
contact:
name: listmonk
url: https://listmonk.app/docs/apis/apis/
license:
name: AGPL-3.0
url: https://github.com/knadh/listmonk/blob/master/LICENSE
version: '4.1'
servers:
- url: http://localhost:9000/api
description: Default local self-hosted instance
- url: '{host}/api'
description: Self-hosted instance
variables:
host:
default: http://localhost:9000
description: Base URL of your listmonk instance
security:
- BasicAuth: []
- TokenAuth: []
tags:
- name: Subscribers
- name: Lists
- name: Campaigns
- name: Templates
- name: Media
- name: Transactional
- name: Import
- name: Bounces
paths:
/subscribers:
get:
operationId: getSubscribers
tags: [Subscribers]
summary: Query and retrieve subscribers.
parameters:
- { name: query, in: query, schema: { type: string }, description: "SQL expression to filter subscribers, e.g. subscribers.name LIKE '%john%'." }
- { name: list_id, in: query, schema: { type: array, items: { type: integer } } }
- { name: page, in: query, schema: { type: integer } }
- { name: per_page, in: query, schema: { type: integer } }
responses:
'200':
description: A paginated list of subscribers.
content:
application/json:
schema: { $ref: '#/components/schemas/SubscribersResponse' }
post:
operationId: createSubscriber
tags: [Subscribers]
summary: Create a new subscriber.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/SubscriberRequest' }
responses:
'200':
description: The created subscriber.
content:
application/json:
schema: { $ref: '#/components/schemas/SubscriberResponse' }
delete:
operationId: deleteSubscribers
tags: [Subscribers]
summary: Delete multiple subscribers by ID.
parameters:
- { name: id, in: query, schema: { type: array, items: { type: integer } } }
responses:
'200': { description: Deletion result. }
/subscribers/{subscriber_id}:
parameters:
- { name: subscriber_id, in: path, required: true, schema: { type: integer } }
get:
operationId: getSubscriber
tags: [Subscribers]
summary: Retrieve a specific subscriber.
responses:
'200':
description: The subscriber.
content:
application/json:
schema: { $ref: '#/components/schemas/SubscriberResponse' }
put:
operationId: updateSubscriber
tags: [Subscribers]
summary: Update a specific subscriber.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/SubscriberRequest' }
responses:
'200':
description: The updated subscriber.
content:
application/json:
schema: { $ref: '#/components/schemas/SubscriberResponse' }
delete:
operationId: deleteSubscriber
tags: [Subscribers]
summary: Delete a specific subscriber.
responses:
'200': { description: Deletion result. }
/subscribers/{subscriber_id}/optin:
post:
operationId: sendSubscriberOptin
tags: [Subscribers]
summary: Send an opt-in confirmation email to a subscriber.
parameters:
- { name: subscriber_id, in: path, required: true, schema: { type: integer } }
responses:
'200': { description: Opt-in email queued. }
/subscribers/{subscriber_id}/export:
get:
operationId: exportSubscriber
tags: [Subscribers]
summary: Export a subscriber's data.
parameters:
- { name: subscriber_id, in: path, required: true, schema: { type: integer } }
responses:
'200': { description: Exported subscriber data. }
/subscribers/lists:
put:
operationId: manageSubscriberLists
tags: [Subscribers]
summary: Add, remove, or unsubscribe subscribers from lists.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/SubscriberListsRequest' }
responses:
'200': { description: List membership updated. }
/subscribers/query/lists:
put:
operationId: manageSubscriberListsByQuery
tags: [Subscribers]
summary: Add, remove, or unsubscribe subscribers from lists by SQL query.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/SubscriberListsRequest' }
responses:
'200': { description: List membership updated. }
/subscribers/{subscriber_id}/blocklist:
put:
operationId: blocklistSubscriber
tags: [Subscribers]
summary: Blocklist a single subscriber.
parameters:
- { name: subscriber_id, in: path, required: true, schema: { type: integer } }
responses:
'200': { description: Subscriber blocklisted. }
/subscribers/blocklist:
put:
operationId: blocklistSubscribers
tags: [Subscribers]
summary: Blocklist multiple subscribers by ID.
requestBody:
content:
application/json:
schema:
type: object
properties:
ids: { type: array, items: { type: integer } }
responses:
'200': { description: Subscribers blocklisted. }
/subscribers/query/blocklist:
put:
operationId: blocklistSubscribersByQuery
tags: [Subscribers]
summary: Blocklist subscribers matching a SQL expression.
responses:
'200': { description: Subscribers blocklisted. }
/subscribers/query/delete:
post:
operationId: deleteSubscribersByQuery
tags: [Subscribers]
summary: Delete subscribers matching a SQL expression.
responses:
'200': { description: Subscribers deleted. }
/lists:
get:
operationId: getLists
tags: [Lists]
summary: Retrieve all lists.
parameters:
- { name: query, in: query, schema: { type: string } }
- { name: page, in: query, schema: { type: integer } }
- { name: per_page, in: query, schema: { type: integer } }
responses:
'200':
description: A paginated list of lists.
content:
application/json:
schema: { $ref: '#/components/schemas/ListsResponse' }
post:
operationId: createList
tags: [Lists]
summary: Create a new list.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/ListRequest' }
responses:
'200':
description: The created list.
content:
application/json:
schema: { $ref: '#/components/schemas/ListResponse' }
delete:
operationId: deleteLists
tags: [Lists]
summary: Delete multiple lists by ID.
parameters:
- { name: id, in: query, schema: { type: array, items: { type: integer } } }
responses:
'200': { description: Deletion result. }
/lists/{list_id}:
parameters:
- { name: list_id, in: path, required: true, schema: { type: integer } }
get:
operationId: getList
tags: [Lists]
summary: Retrieve a specific list.
responses:
'200':
description: The list.
content:
application/json:
schema: { $ref: '#/components/schemas/ListResponse' }
put:
operationId: updateList
tags: [Lists]
summary: Update an existing list.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/ListRequest' }
responses:
'200':
description: The updated list.
content:
application/json:
schema: { $ref: '#/components/schemas/ListResponse' }
delete:
operationId: deleteList
tags: [Lists]
summary: Delete a specific list.
responses:
'200': { description: Deletion result. }
/public/lists:
get:
operationId: getPublicLists
tags: [Lists]
summary: Retrieve public lists (unauthenticated, for subscription forms).
security: []
responses:
'200': { description: Public lists. }
/campaigns:
get:
operationId: getCampaigns
tags: [Campaigns]
summary: Retrieve all campaigns.
parameters:
- { name: query, in: query, schema: { type: string } }
- { name: status, in: query, schema: { type: array, items: { type: string } } }
- { name: page, in: query, schema: { type: integer } }
- { name: per_page, in: query, schema: { type: integer } }
responses:
'200':
description: A paginated list of campaigns.
content:
application/json:
schema: { $ref: '#/components/schemas/CampaignsResponse' }
post:
operationId: createCampaign
tags: [Campaigns]
summary: Create a new campaign.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/CampaignRequest' }
responses:
'200':
description: The created campaign.
content:
application/json:
schema: { $ref: '#/components/schemas/CampaignResponse' }
delete:
operationId: deleteCampaigns
tags: [Campaigns]
summary: Delete multiple campaigns.
responses:
'200': { description: Deletion result. }
/campaigns/{campaign_id}:
parameters:
- { name: campaign_id, in: path, required: true, schema: { type: integer } }
get:
operationId: getCampaign
tags: [Campaigns]
summary: Retrieve a specific campaign.
responses:
'200':
description: The campaign.
content:
application/json:
schema: { $ref: '#/components/schemas/CampaignResponse' }
put:
operationId: updateCampaign
tags: [Campaigns]
summary: Update a campaign.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/CampaignRequest' }
responses:
'200':
description: The updated campaign.
content:
application/json:
schema: { $ref: '#/components/schemas/CampaignResponse' }
delete:
operationId: deleteCampaign
tags: [Campaigns]
summary: Delete an individual campaign.
responses:
'200': { description: Deletion result. }
/campaigns/{campaign_id}/preview:
get:
operationId: previewCampaign
tags: [Campaigns]
summary: Retrieve an HTML preview of a campaign.
parameters:
- { name: campaign_id, in: path, required: true, schema: { type: integer } }
responses:
'200': { description: Rendered campaign HTML. }
/campaigns/{campaign_id}/test:
post:
operationId: testCampaign
tags: [Campaigns]
summary: Send a test of the campaign to arbitrary subscribers.
parameters:
- { name: campaign_id, in: path, required: true, schema: { type: integer } }
requestBody:
content:
application/json:
schema:
type: object
properties:
subscribers: { type: array, items: { type: string }, description: List of test recipient emails. }
responses:
'200': { description: Test message queued. }
/campaigns/{campaign_id}/status:
put:
operationId: updateCampaignStatus
tags: [Campaigns]
summary: Change the status of a campaign (running, paused, cancelled, scheduled).
parameters:
- { name: campaign_id, in: path, required: true, schema: { type: integer } }
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
status: { type: string, enum: [scheduled, running, paused, cancelled, finished] }
responses:
'200': { description: Status updated. }
/campaigns/{campaign_id}/archive:
put:
operationId: archiveCampaign
tags: [Campaigns]
summary: Publish or update a campaign in the public archive.
parameters:
- { name: campaign_id, in: path, required: true, schema: { type: integer } }
responses:
'200': { description: Archive settings updated. }
/campaigns/running/stats:
get:
operationId: getRunningCampaignStats
tags: [Campaigns]
summary: Retrieve stats of running campaigns.
parameters:
- { name: campaign_id, in: query, schema: { type: array, items: { type: integer } } }
responses:
'200': { description: Running campaign stats. }
/campaigns/analytics/{type}:
get:
operationId: getCampaignAnalytics
tags: [Campaigns]
summary: Retrieve view, click, link, or bounce counts for campaigns.
parameters:
- { name: type, in: path, required: true, schema: { type: string, enum: [views, clicks, links, bounces] } }
- { name: id, in: query, schema: { type: array, items: { type: integer } } }
- { name: from, in: query, schema: { type: string, format: date } }
- { name: to, in: query, schema: { type: string, format: date } }
responses:
'200': { description: Campaign analytics. }
/templates:
get:
operationId: getTemplates
tags: [Templates]
summary: Retrieve all templates.
responses:
'200':
description: A list of templates.
content:
application/json:
schema: { $ref: '#/components/schemas/TemplatesResponse' }
post:
operationId: createTemplate
tags: [Templates]
summary: Create a template.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/TemplateRequest' }
responses:
'200':
description: The created template.
content:
application/json:
schema: { $ref: '#/components/schemas/TemplateResponse' }
/templates/{template_id}:
parameters:
- { name: template_id, in: path, required: true, schema: { type: integer } }
get:
operationId: getTemplate
tags: [Templates]
summary: Retrieve a template.
responses:
'200':
description: The template.
content:
application/json:
schema: { $ref: '#/components/schemas/TemplateResponse' }
put:
operationId: updateTemplate
tags: [Templates]
summary: Update an existing template.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/TemplateRequest' }
responses:
'200':
description: The updated template.
content:
application/json:
schema: { $ref: '#/components/schemas/TemplateResponse' }
delete:
operationId: deleteTemplate
tags: [Templates]
summary: Delete a template.
responses:
'200': { description: Deletion result. }
/templates/{template_id}/preview:
get:
operationId: previewTemplate
tags: [Templates]
summary: Retrieve the rendered HTML preview of a template.
parameters:
- { name: template_id, in: path, required: true, schema: { type: integer } }
responses:
'200': { description: Rendered template HTML. }
/templates/{template_id}/default:
put:
operationId: setDefaultTemplate
tags: [Templates]
summary: Set a template as the default.
parameters:
- { name: template_id, in: path, required: true, schema: { type: integer } }
responses:
'200': { description: Default template set. }
/templates/preview:
post:
operationId: previewTemplateBody
tags: [Templates]
summary: Render and preview a template body without saving it.
requestBody:
content:
application/json:
schema: { $ref: '#/components/schemas/TemplateRequest' }
responses:
'200': { description: Rendered HTML. }
/media:
get:
operationId: getMedia
tags: [Media]
summary: Retrieve uploaded media files.
responses:
'200':
description: A list of media files.
content:
application/json:
schema: { $ref: '#/components/schemas/MediaResponse' }
post:
operationId: uploadMedia
tags: [Media]
summary: Upload a media file.
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file: { type: string, format: binary }
responses:
'200':
description: The uploaded media file.
content:
application/json:
schema: { $ref: '#/components/schemas/MediaResponse' }
/media/{media_id}:
parameters:
- { name: media_id, in: path, required: true, schema: { type: integer } }
get:
operationId: getMediaFile
tags: [Media]
summary: Retrieve a specific media file.
responses:
'200': { description: The media file. }
delete:
operationId: deleteMedia
tags: [Media]
summary: Delete an uploaded media file.
responses:
'200': { description: Deletion result. }
/tx:
post:
operationId: sendTransactionalMessage
tags: [Transactional]
summary: Send a transactional message to one or more subscribers.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/TransactionalRequest' }
multipart/form-data:
schema:
type: object
properties:
data: { type: string, description: JSON-encoded transactional payload. }
file: { type: string, format: binary, description: Optional attachment. }
responses:
'200': { description: Message accepted and queued. }
/import/subscribers:
get:
operationId: getImportStatus
tags: [Import]
summary: Retrieve the status of an ongoing import.
responses:
'200': { description: Import status. }
post:
operationId: importSubscribers
tags: [Import]
summary: Upload a CSV (optionally ZIP-compressed) file to import subscribers.
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
params: { type: string, description: JSON-encoded import params (mode, lists, delimiter, overwrite). }
file: { type: string, format: binary }
responses:
'200': { description: Import started. }
delete:
operationId: stopImport
tags: [Import]
summary: Stop and delete an ongoing import.
responses:
'200': { description: Import stopped. }
/import/subscribers/logs:
get:
operationId: getImportLogs
tags: [Import]
summary: Retrieve logs from an ongoing import.
responses:
'200': { description: Import logs. }
/bounces:
get:
operationId: getBounces
tags: [Bounces]
summary: Retrieve bounce records.
parameters:
- { name: campaign_id, in: query, schema: { type: integer } }
- { name: page, in: query, schema: { type: integer } }
- { name: per_page, in: query, schema: { type: integer } }
responses:
'200':
description: A paginated list of bounce records.
content:
application/json:
schema: { $ref: '#/components/schemas/BouncesResponse' }
delete:
operationId: deleteBounces
tags: [Bounces]
summary: Delete bounce records by ID or all.
parameters:
- { name: id, in: query, schema: { type: array, items: { type: integer } } }
- { name: all, in: query, schema: { type: boolean } }
responses:
'200': { description: Deletion result. }
/bounces/{bounce_id}:
delete:
operationId: deleteBounce
tags: [Bounces]
summary: Delete a single bounce record.
parameters:
- { name: bounce_id, in: path, required: true, schema: { type: integer } }
responses:
'200': { description: Deletion result. }
components:
securitySchemes:
BasicAuth:
type: http
scheme: basic
description: HTTP Basic auth using an API user name and token (api_user:token).
TokenAuth:
type: apiKey
in: header
name: Authorization
description: "Authorization header in the form: token api_user:token."
schemas:
SubscriberRequest:
type: object
properties:
email: { type: string, format: email }
name: { type: string }
status: { type: string, enum: [enabled, disabled, blocklisted] }
lists: { type: array, items: { type: integer }, description: List IDs to subscribe to. }
attribs: { type: object, additionalProperties: true, description: Arbitrary JSON attributes. }
preconfirm_subscriptions: { type: boolean }
required: [email]
SubscriberResponse:
type: object
properties:
data: { $ref: '#/components/schemas/Subscriber' }
SubscribersResponse:
type: object
properties:
data:
type: object
properties:
results: { type: array, items: { $ref: '#/components/schemas/Subscriber' } }
total: { type: integer }
page: { type: integer }
per_page: { type: integer }
Subscriber:
type: object
properties:
id: { type: integer }
uuid: { type: string }
email: { type: string }
name: { type: string }
status: { type: string }
attribs: { type: object, additionalProperties: true }
lists: { type: array, items: { type: object } }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
SubscriberListsRequest:
type: object
properties:
ids: { type: array, items: { type: integer } }
query: { type: string }
action: { type: string, enum: [add, remove, unsubscribe] }
target_list_ids: { type: array, items: { type: integer } }
status: { type: string, enum: [unconfirmed, confirmed, unsubscribed] }
ListRequest:
type: object
properties:
name: { type: string }
type: { type: string, enum: [public, private] }
optin: { type: string, enum: [single, double] }
tags: { type: array, items: { type: string } }
description: { type: string }
required: [name]
ListResponse:
type: object
properties:
data: { $ref: '#/components/schemas/List' }
ListsResponse:
type: object
properties:
data:
type: object
properties:
results: { type: array, items: { $ref: '#/components/schemas/List' } }
total: { type: integer }
List:
type: object
properties:
id: { type: integer }
uuid: { type: string }
name: { type: string }
type: { type: string }
optin: { type: string }
tags: { type: array, items: { type: string } }
subscriber_count: { type: integer }
created_at: { type: string, format: date-time }
CampaignRequest:
type: object
properties:
name: { type: string }
subject: { type: string }
lists: { type: array, items: { type: integer } }
from_email: { type: string }
type: { type: string, enum: [regular, optin] }
content_type: { type: string, enum: [richtext, html, markdown, plain] }
body: { type: string }
template_id: { type: integer }
messenger: { type: string }
tags: { type: array, items: { type: string } }
send_at: { type: string, format: date-time }
required: [name, subject, lists]
CampaignResponse:
type: object
properties:
data: { $ref: '#/components/schemas/Campaign' }
CampaignsResponse:
type: object
properties:
data:
type: object
properties:
results: { type: array, items: { $ref: '#/components/schemas/Campaign' } }
total: { type: integer }
Campaign:
type: object
properties:
id: { type: integer }
uuid: { type: string }
name: { type: string }
subject: { type: string }
status: { type: string }
type: { type: string }
content_type: { type: string }
lists: { type: array, items: { type: object } }
sent: { type: integer }
to_send: { type: integer }
created_at: { type: string, format: date-time }
TemplateRequest:
type: object
properties:
name: { type: string }
type: { type: string, enum: [campaign, campaign_visual, tx] }
subject: { type: string }
body: { type: string }
required: [name, type, body]
TemplateResponse:
type: object
properties:
data: { $ref: '#/components/schemas/Template' }
TemplatesResponse:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/Template' } }
Template:
type: object
properties:
id: { type: integer }
name: { type: string }
type: { type: string }
subject: { type: string }
body: { type: string }
is_default: { type: boolean }
created_at: { type: string, format: date-time }
MediaResponse:
type: object
properties:
data:
oneOf:
- { $ref: '#/components/schemas/Media' }
- { type: array, items: { $ref: '#/components/schemas/Media' } }
Media:
type: object
properties:
id: { type: integer }
uuid: { type: string }
filename: { type: string }
content_type: { type: string }
url: { type: string }
thumb_url: { type: string }
created_at: { type: string, format: date-time }
TransactionalRequest:
type: object
properties:
subscriber_email: { type: string, format: email }
subscriber_id: { type: integer }
subscriber_emails: { type: array, items: { type: string } }
subscriber_ids: { type: array, items: { type: integer } }
template_id: { type: integer }
subscriber_mode: { type: string, enum: [default, fallback, external] }
from_email: { type: string }
subject: { type: string }
data: { type: object, additionalProperties: true, description: "Custom variables available in templates via {{ .Tx.Data.* }}." }
headers: { type: array, items: { type: object, additionalProperties: { type: string } } }
messenger: { type: string, default: email }
content_type: { type: string, enum: [html, markdown, plain] }
altbody: { type: string }
required: [template_id]
BouncesResponse:
type: object
properties:
data:
type: object
properties:
results: { type: array, items: { $ref: '#/components/schemas/Bounce' } }
total: { type: integer }
Bounce:
type: object
properties:
id: { type: integer }
type: { type: string, enum: [hard, soft, complaint] }
source: { type: string }
subscriber_id: { type: integer }
campaign_id: { type: integer }
email: { type: string }
created_at: { type: string, format: date-time }