# Listmonk Exporter
[](https://github.com/meysam81/listmonk-exporter/actions/workflows/ci.yml)
[](https://pypi.org/project/listmonk-exporter/)
[](https://pypi.org/project/listmonk-exporter/)
[](https://pypi.org/project/listmonk-exporter/)
[](LICENSE)
[](https://github.com/astral-sh/ruff)
[](https://github.com/meysam81/listmonk-exporter/stargazers)
[](https://github.com/meysam81/listmonk-exporter/network/members)
[](https://github.com/meysam81/listmonk-exporter/issues)
[](https://github.com/meysam81/listmonk-exporter/pulls)
[](https://github.com/meysam81/listmonk-exporter/commits/main)
[](https://github.com/meysam81/listmonk-exporter/graphs/contributors)
[](https://github.com/meysam81/listmonk-exporter/graphs/commit-activity)
[](http://makeapullrequest.com)
A Prometheus exporter for [Listmonk](https://listmonk.app/), the self-hosted newsletter and mailing list manager. Monitor your email campaigns, subscriber counts, bounce rates, and more with this lightweight exporter.
## Features
- 📊 **Subscriber Metrics**: Track subscriber counts by status (confirmed, unconfirmed, unsubscribed)
- 📧 **Campaign Statistics**: Monitor sent, opened, clicked, and bounced emails per campaign
- 📋 **List Metrics**: View subscriber counts across all your lists
- 🔄 **Bounce Tracking**: Track bounce counts by type (hard, soft, complaint)
- ⚡ **Lightweight**: Built with Python and runs as a single process
- 🐳 **Docker Ready**: Includes official Docker image for easy deployment
- 🔧 **Configurable**: Flexible configuration via environment variables or CLI arguments
## Installation
### Via pip
```bash
pip install listmonk-exporter
```
### Via Docker
```bash
docker pull ghcr.io/meysam81/listmonk-exporter:latest
```
## Configuration
Configure the exporter using environment variables or command-line arguments.
### Required Configuration
| Environment Variable | Description | Example |
| -------------------- | --------------------- | ------------------------------ |
| `LISTMONK_HOST` | Listmonk instance URL | `https://listmonk.example.com` |
| `LISTMONK_API_USER` | Listmonk API username | `admin` |
| `LISTMONK_API_TOKEN` | Listmonk API token | `your-api-token` |
| `LIST_ID` | List ID to monitor | `1` |
| `LIST_NAME` | Name of the list | `Newsletter` |
### Optional Configuration
| Environment Variable | Default | Description |
| -------------------- | ------- | ------------------------------------------- |
| `SCRAPE_INTERVAL` | `60` | Scrape interval in seconds |
| `PORT` | `8000` | Port for Prometheus HTTP server |
| `LOG_LEVEL` | `INFO` | Logging level (DEBUG, INFO, WARNING, ERROR) |
## Usage
### Quick Start with pip
```bash
# Set required environment variables
export LISTMONK_HOST=https://listmonk.example.com
export LISTMONK_API_USER=admin
export LISTMONK_API_TOKEN=your-api-token
export LIST_ID=1
export LIST_NAME="Newsletter"
# Run the exporter
listmonk-exporter
```
### Docker Compose
```yaml
version: "3.8"
services:
listmonk-exporter:
image: ghcr.io/meysam81/listmonk-exporter:latest
ports:
- "8000:8000"
environment:
LISTMONK_HOST: https://listmonk.example.com
LISTMONK_API_USER: admin
LISTMONK_API_TOKEN: your-api-token
LIST_ID: 1
LIST_NAME: Newsletter
SCRAPE_INTERVAL: 60
LOG_LEVEL: INFO
restart: unless-stopped
```
### Docker Run
```bash
docker run -d \
-p 8000:8000 \
-e LISTMONK_HOST=https://listmonk.example.com \
-e LISTMONK_API_USER=admin \
-e LISTMONK_API_TOKEN=your-api-token \
-e LIST_ID=1 \
-e LIST_NAME=Newsletter \
ghcr.io/meysam81/listmonk-exporter:latest
```
### Kubernetes
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: listmonk-exporter
spec:
replicas: 1
selector:
matchLabels:
app: listmonk-exporter
template:
metadata:
labels:
app: listmonk-exporter
spec:
containers:
- name: listmonk-exporter
image: ghcr.io/meysam81/listmonk-exporter:latest
ports:
- containerPort: 8000
env:
- name: LISTMONK_HOST
value: "https://listmonk.example.com"
- name: LISTMONK_API_USER
valueFrom:
secretKeyRef:
name: listmonk-credentials
key: username
- name: LISTMONK_API_TOKEN
valueFrom:
secretKeyRef:
name: listmonk-credentials
key: token
- name: LIST_ID
value: "1"
- name: LIST_NAME
value: "Newsletter"
---
apiVersion: v1
kind: Service
metadata:
name: listmonk-exporter
spec:
selector:
app: listmonk-exporter
ports:
- port: 8000
targetPort: 8000
```
## Exported Metrics
The exporter provides the following Prometheus metrics:
| Metric Name | Type | Description | Labels |
| ---------------------------------- | --------- | ------------------------------------------------------------- | -------------------------------------------------------------- |
| `listmonk_subscribers_by_status` | Gauge | Number of subscribers by subscription status | `list_name`, `subscription_status` |
| `listmonk_subscribers_total` | Gauge | Total number of subscribers in the list | `list_name` |
| `listmonk_campaign_stats` | Gauge | Campaign statistics (sent, opened, clicked, bounced) | `campaign_id`, `campaign_name`, `campaign_status`, `stat_type` |
| `listmonk_list_subscribers` | Gauge | Total subscribers per list | `list_id`, `list_name`, `list_type` |
| `listmonk_bounces_total` | Gauge | Total number of bounces by type | `bounce_type` |
| `listmonk_scrape_duration_seconds` | Histogram | Duration of scrape operations | `operation` |
| `listmonk_scrape_success` | Gauge | Whether the last scrape was successful (1=success, 0=failure) | `operation` |
| `listmonk_scrape_errors_total` | Counter | Total number of scrape errors | `operation` |
### Metric Details
**Subscriber Metrics:**
- `subscription_status` values: `confirmed`, `unconfirmed`, `unsubscribed`
**Campaign Metrics:**
- `stat_type` values: `sent`, `opened`, `clicked`, `bounced`
- `campaign_status` values: `draft`, `scheduled`, `running`, `paused`, `finished`, `cancelled`
**Bounce Metrics:**
- `bounce_type` values: `hard`, `soft`, `complaint`
**Exporter Metrics:**
- `operation` values: `subscribers`, `campaigns`, `lists`, `bounces`
## Prometheus Configuration
Add the following to your `prometheus.yml`:
```yaml
scrape_configs:
- job_name: "listmonk"
static_configs:
- targets: ["localhost:8000"]
```
> **Note:** For complete configuration examples including scrape jobs and alerting rules, see the [examples directory](examples/).
## Grafana Dashboard
Import the provided Grafana dashboard (coming soon) or create your own using the exported metrics.
Example queries:
```promql
# Total subscribers
listmonk_subscribers_total{list_name="Newsletter"}
# Confirmed subscribers
listmonk_subscribers_by_status{list_name="Newsletter",subscription_status="confirmed"}
# Campaign open rate
(listmonk_campaign_stats{stat_type="opened"} / listmonk_campaign_stats{stat_type="sent"}) * 100
```
## Development
### Prerequisites
- Python 3.11 or higher
- pip
### Setup
```bash
# Clone the repository
git clone https://github.com/meysam81/listmonk-exporter.git
cd listmonk-exporter
# Install dependencies
pip install -e .
# Run locally
python main.py
```
### Building Docker Image
```bash
docker build -t listmonk-exporter .
```
## Troubleshooting
### Exporter can't connect to Listmonk
- Verify `LISTMONK_HOST` is correct and accessible
- Check that API credentials are valid
- Ensure Listmonk API is enabled
### Metrics not updating
- Check `SCRAPE_INTERVAL` setting
- Review logs with `LOG_LEVEL=DEBUG`
- Verify the list ID exists in Listmonk
### High memory usage
- Increase `SCRAPE_INTERVAL` to reduce scraping frequency
- Check Listmonk API response sizes
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.
## Support
- 🐛 [Issue Tracker](https://github.com/meysam81/listmonk-exporter/issues)
- 💬 [Discussions](https://github.com/meysam81/listmonk-exporter/discussions)
- 📧 Email: [Your email]
## Acknowledgments
- [Listmonk](https://listmonk.app/) - The amazing newsletter manager
- [Prometheus](https://prometheus.io/) - Monitoring and alerting toolkit
- [prometheus_client](https://github.com/prometheus/client_python) - Python client for Prometheus
---
_Made with ❤️ for the open-source community._
Raw data
{
"_id": null,
"home_page": null,
"name": "listmonk-exporter",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.11",
"maintainer_email": "Meysam Azad <contact@meysam.io>",
"keywords": "listmonk, prometheus, exporter, monitoring, metrics, newsletter, email, mailing-list",
"author": null,
"author_email": "Meysam Azad <contact@meysam.io>",
"download_url": "https://files.pythonhosted.org/packages/bb/64/59f495dcf6f52bc6e5244cdd3f3336d928d1a20a448cf659390f9e223880/listmonk_exporter-0.2.0.tar.gz",
"platform": null,
"description": "# Listmonk Exporter\n\n[](https://github.com/meysam81/listmonk-exporter/actions/workflows/ci.yml)\n[](https://pypi.org/project/listmonk-exporter/)\n[](https://pypi.org/project/listmonk-exporter/)\n[](https://pypi.org/project/listmonk-exporter/)\n[](LICENSE)\n[](https://github.com/astral-sh/ruff)\n[](https://github.com/meysam81/listmonk-exporter/stargazers)\n[](https://github.com/meysam81/listmonk-exporter/network/members)\n[](https://github.com/meysam81/listmonk-exporter/issues)\n[](https://github.com/meysam81/listmonk-exporter/pulls)\n[](https://github.com/meysam81/listmonk-exporter/commits/main)\n[](https://github.com/meysam81/listmonk-exporter/graphs/contributors)\n[](https://github.com/meysam81/listmonk-exporter/graphs/commit-activity)\n[](http://makeapullrequest.com)\n\nA Prometheus exporter for [Listmonk](https://listmonk.app/), the self-hosted newsletter and mailing list manager. Monitor your email campaigns, subscriber counts, bounce rates, and more with this lightweight exporter.\n\n## Features\n\n- \ud83d\udcca **Subscriber Metrics**: Track subscriber counts by status (confirmed, unconfirmed, unsubscribed)\n- \ud83d\udce7 **Campaign Statistics**: Monitor sent, opened, clicked, and bounced emails per campaign\n- \ud83d\udccb **List Metrics**: View subscriber counts across all your lists\n- \ud83d\udd04 **Bounce Tracking**: Track bounce counts by type (hard, soft, complaint)\n- \u26a1 **Lightweight**: Built with Python and runs as a single process\n- \ud83d\udc33 **Docker Ready**: Includes official Docker image for easy deployment\n- \ud83d\udd27 **Configurable**: Flexible configuration via environment variables or CLI arguments\n\n## Installation\n\n### Via pip\n\n```bash\npip install listmonk-exporter\n```\n\n### Via Docker\n\n```bash\ndocker pull ghcr.io/meysam81/listmonk-exporter:latest\n```\n\n## Configuration\n\nConfigure the exporter using environment variables or command-line arguments.\n\n### Required Configuration\n\n| Environment Variable | Description | Example |\n| -------------------- | --------------------- | ------------------------------ |\n| `LISTMONK_HOST` | Listmonk instance URL | `https://listmonk.example.com` |\n| `LISTMONK_API_USER` | Listmonk API username | `admin` |\n| `LISTMONK_API_TOKEN` | Listmonk API token | `your-api-token` |\n| `LIST_ID` | List ID to monitor | `1` |\n| `LIST_NAME` | Name of the list | `Newsletter` |\n\n### Optional Configuration\n\n| Environment Variable | Default | Description |\n| -------------------- | ------- | ------------------------------------------- |\n| `SCRAPE_INTERVAL` | `60` | Scrape interval in seconds |\n| `PORT` | `8000` | Port for Prometheus HTTP server |\n| `LOG_LEVEL` | `INFO` | Logging level (DEBUG, INFO, WARNING, ERROR) |\n\n## Usage\n\n### Quick Start with pip\n\n```bash\n# Set required environment variables\nexport LISTMONK_HOST=https://listmonk.example.com\nexport LISTMONK_API_USER=admin\nexport LISTMONK_API_TOKEN=your-api-token\nexport LIST_ID=1\nexport LIST_NAME=\"Newsletter\"\n\n# Run the exporter\nlistmonk-exporter\n```\n\n### Docker Compose\n\n```yaml\nversion: \"3.8\"\n\nservices:\n listmonk-exporter:\n image: ghcr.io/meysam81/listmonk-exporter:latest\n ports:\n - \"8000:8000\"\n environment:\n LISTMONK_HOST: https://listmonk.example.com\n LISTMONK_API_USER: admin\n LISTMONK_API_TOKEN: your-api-token\n LIST_ID: 1\n LIST_NAME: Newsletter\n SCRAPE_INTERVAL: 60\n LOG_LEVEL: INFO\n restart: unless-stopped\n```\n\n### Docker Run\n\n```bash\ndocker run -d \\\n -p 8000:8000 \\\n -e LISTMONK_HOST=https://listmonk.example.com \\\n -e LISTMONK_API_USER=admin \\\n -e LISTMONK_API_TOKEN=your-api-token \\\n -e LIST_ID=1 \\\n -e LIST_NAME=Newsletter \\\n ghcr.io/meysam81/listmonk-exporter:latest\n```\n\n### Kubernetes\n\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: listmonk-exporter\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: listmonk-exporter\n template:\n metadata:\n labels:\n app: listmonk-exporter\n spec:\n containers:\n - name: listmonk-exporter\n image: ghcr.io/meysam81/listmonk-exporter:latest\n ports:\n - containerPort: 8000\n env:\n - name: LISTMONK_HOST\n value: \"https://listmonk.example.com\"\n - name: LISTMONK_API_USER\n valueFrom:\n secretKeyRef:\n name: listmonk-credentials\n key: username\n - name: LISTMONK_API_TOKEN\n valueFrom:\n secretKeyRef:\n name: listmonk-credentials\n key: token\n - name: LIST_ID\n value: \"1\"\n - name: LIST_NAME\n value: \"Newsletter\"\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: listmonk-exporter\nspec:\n selector:\n app: listmonk-exporter\n ports:\n - port: 8000\n targetPort: 8000\n```\n\n## Exported Metrics\n\nThe exporter provides the following Prometheus metrics:\n\n| Metric Name | Type | Description | Labels |\n| ---------------------------------- | --------- | ------------------------------------------------------------- | -------------------------------------------------------------- |\n| `listmonk_subscribers_by_status` | Gauge | Number of subscribers by subscription status | `list_name`, `subscription_status` |\n| `listmonk_subscribers_total` | Gauge | Total number of subscribers in the list | `list_name` |\n| `listmonk_campaign_stats` | Gauge | Campaign statistics (sent, opened, clicked, bounced) | `campaign_id`, `campaign_name`, `campaign_status`, `stat_type` |\n| `listmonk_list_subscribers` | Gauge | Total subscribers per list | `list_id`, `list_name`, `list_type` |\n| `listmonk_bounces_total` | Gauge | Total number of bounces by type | `bounce_type` |\n| `listmonk_scrape_duration_seconds` | Histogram | Duration of scrape operations | `operation` |\n| `listmonk_scrape_success` | Gauge | Whether the last scrape was successful (1=success, 0=failure) | `operation` |\n| `listmonk_scrape_errors_total` | Counter | Total number of scrape errors | `operation` |\n\n### Metric Details\n\n**Subscriber Metrics:**\n\n- `subscription_status` values: `confirmed`, `unconfirmed`, `unsubscribed`\n\n**Campaign Metrics:**\n\n- `stat_type` values: `sent`, `opened`, `clicked`, `bounced`\n- `campaign_status` values: `draft`, `scheduled`, `running`, `paused`, `finished`, `cancelled`\n\n**Bounce Metrics:**\n\n- `bounce_type` values: `hard`, `soft`, `complaint`\n\n**Exporter Metrics:**\n\n- `operation` values: `subscribers`, `campaigns`, `lists`, `bounces`\n\n## Prometheus Configuration\n\nAdd the following to your `prometheus.yml`:\n\n```yaml\nscrape_configs:\n - job_name: \"listmonk\"\n static_configs:\n - targets: [\"localhost:8000\"]\n```\n\n> **Note:** For complete configuration examples including scrape jobs and alerting rules, see the [examples directory](examples/).\n\n## Grafana Dashboard\n\nImport the provided Grafana dashboard (coming soon) or create your own using the exported metrics.\n\nExample queries:\n\n```promql\n# Total subscribers\nlistmonk_subscribers_total{list_name=\"Newsletter\"}\n\n# Confirmed subscribers\nlistmonk_subscribers_by_status{list_name=\"Newsletter\",subscription_status=\"confirmed\"}\n\n# Campaign open rate\n(listmonk_campaign_stats{stat_type=\"opened\"} / listmonk_campaign_stats{stat_type=\"sent\"}) * 100\n```\n\n## Development\n\n### Prerequisites\n\n- Python 3.11 or higher\n- pip\n\n### Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/meysam81/listmonk-exporter.git\ncd listmonk-exporter\n\n# Install dependencies\npip install -e .\n\n# Run locally\npython main.py\n```\n\n### Building Docker Image\n\n```bash\ndocker build -t listmonk-exporter .\n```\n\n## Troubleshooting\n\n### Exporter can't connect to Listmonk\n\n- Verify `LISTMONK_HOST` is correct and accessible\n- Check that API credentials are valid\n- Ensure Listmonk API is enabled\n\n### Metrics not updating\n\n- Check `SCRAPE_INTERVAL` setting\n- Review logs with `LOG_LEVEL=DEBUG`\n- Verify the list ID exists in Listmonk\n\n### High memory usage\n\n- Increase `SCRAPE_INTERVAL` to reduce scraping frequency\n- Check Listmonk API response sizes\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.\n\n## Support\n\n- \ud83d\udc1b [Issue Tracker](https://github.com/meysam81/listmonk-exporter/issues)\n- \ud83d\udcac [Discussions](https://github.com/meysam81/listmonk-exporter/discussions)\n- \ud83d\udce7 Email: [Your email]\n\n## Acknowledgments\n\n- [Listmonk](https://listmonk.app/) - The amazing newsletter manager\n- [Prometheus](https://prometheus.io/) - Monitoring and alerting toolkit\n- [prometheus_client](https://github.com/prometheus/client_python) - Python client for Prometheus\n\n---\n\n_Made with \u2764\ufe0f for the open-source community._\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "A Prometheus exporter for Listmonk newsletter and mailing list manager",
"version": "0.2.0",
"project_urls": {
"Changelog": "https://github.com/meysam81/listmonk-exporter/releases",
"Documentation": "https://github.com/meysam81/listmonk-exporter#readme",
"Homepage": "https://github.com/meysam81/listmonk-exporter",
"Issues": "https://github.com/meysam81/listmonk-exporter/issues",
"Repository": "https://github.com/meysam81/listmonk-exporter"
},
"split_keywords": [
"listmonk",
" prometheus",
" exporter",
" monitoring",
" metrics",
" newsletter",
" email",
" mailing-list"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "28e51fe99fe86bd4964975291e6aec5612a72c554df12196e4cfe53d6b43161d",
"md5": "89e6993a3c8498a4cd9a611061f47309",
"sha256": "38466dd1dc4d58a2f0803d75b709114471e7045b79853e7bdfaa45abb4d3030e"
},
"downloads": -1,
"filename": "listmonk_exporter-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "89e6993a3c8498a4cd9a611061f47309",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.11",
"size": 11908,
"upload_time": "2025-10-24T06:03:54",
"upload_time_iso_8601": "2025-10-24T06:03:54.185951Z",
"url": "https://files.pythonhosted.org/packages/28/e5/1fe99fe86bd4964975291e6aec5612a72c554df12196e4cfe53d6b43161d/listmonk_exporter-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "bb6459f495dcf6f52bc6e5244cdd3f3336d928d1a20a448cf659390f9e223880",
"md5": "9a5815f05d62f3ad4ca5d58290b9ceb9",
"sha256": "8a2776690cd0a8d91973a96e99e70d9217c9ed65dd69debe44b9593a0c4804b4"
},
"downloads": -1,
"filename": "listmonk_exporter-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "9a5815f05d62f3ad4ca5d58290b9ceb9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.11",
"size": 11857,
"upload_time": "2025-10-24T06:03:55",
"upload_time_iso_8601": "2025-10-24T06:03:55.135760Z",
"url": "https://files.pythonhosted.org/packages/bb/64/59f495dcf6f52bc6e5244cdd3f3336d928d1a20a448cf659390f9e223880/listmonk_exporter-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-24 06:03:55",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "meysam81",
"github_project": "listmonk-exporter",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "listmonk-exporter"
}