Listmonk
A resource-oriented Ruby client for the listmonk HTTP API.
Installation
Add the gem to your bundle:
bundle add listmonk
The gem requires Ruby 3.3 or newer.
Configuration
Listmonk supports Basic authentication and its Authorization: token header. Basic authentication is the default:
client = Listmonk::Client.new(
base_url: "https://newsletter.example.com",
username: ENV.fetch("LISTMONK_USERNAME"),
token: ENV.fetch("LISTMONK_TOKEN")
)
Use token-header authentication when needed:
client = Listmonk.client(
base_url: "https://newsletter.example.com/api",
username: ENV.fetch("LISTMONK_USERNAME"),
token: ENV.fetch("LISTMONK_TOKEN"),
auth: :token,
timeout: 30,
open_timeout: 10
)
The client accepts a server root or an URL ending in /api. Credentials may be omitted for public endpoints.
Usage
Every method returns a Listmonk::Response. Use data for the API payload, or inspect status, headers, and body when needed.
response = client.subscribers.list(page: 1, per_page: 50, list_id: [1, 2])
subscribers = response.data.fetch("results")
subscriber = client.subscribers.create(
email: "reader@example.com",
name: "A Reader",
lists: [1],
attribs: {source: "website"}
).data
client.subscribers.update(subscriber.fetch("id"), name: "Reader")
client.subscribers.send_optin(subscriber.fetch("id"))
Campaigns and transactional messages:
campaign = client.campaigns.create(
name: "July news",
subject: "What's new",
lists: [1],
from_email: "News <news@example.com>",
content_type: "html",
messenger: "email",
type: "regular"
).data
client.campaigns.create_content(campaign.fetch("id"), body: "<h1>Hello</h1>")
client.campaigns.start(campaign.fetch("id"))
client.transactional.deliver(
template_id: 3,
subscriber_email: "reader@example.com",
data: {confirmation_url: "https://example.com/confirm"}
)
Subscriber imports and media uploads use multipart requests:
client.imports.create(
file: "/tmp/subscribers.zip",
params: {
mode: "subscribe",
subscription_status: "confirmed",
lists: [1],
overwrite: true
}
)
client.media.upload(file: "/tmp/banner.png", content_type: "image/png")
Resources cover all operations in the published Swagger collection:
miscellaneous,settings,admin, andlogssubscribers,lists,imports, andbouncescampaigns,templates,media, andtransactionalmaintenanceandpublic
For an undocumented or newly added endpoint, use the low-level request method:
client.request(:get, "new-endpoint", params: {page: 1})
client.request(:post, "new-endpoint", json: {enabled: true})
Errors
Non-successful responses raise typed exceptions. Every HTTP exception exposes status, body, and response.
begin
client.lists.retrieve(999)
rescue Listmonk::NotFoundError => error
warn "List not found: #{error.body.inspect}"
rescue Listmonk::RateLimitError
# Retry with application-specific backoff.
end
Connection failures raise Listmonk::ConnectionError, timeouts raise Listmonk::TimeoutError, and malformed JSON raises Listmonk::ParseError.
Development
Install dependencies and run the complete verification task:
bin/setup
bundle exec rake
RSpec uses WebMock for request-level tests and SimpleCov for coverage.
Docker integration tests
Run the opt-in integration suite against an ephemeral Listmonk 6.1.0 and PostgreSQL 17 environment:
bundle exec rake integration
The task starts Docker Compose on 127.0.0.1:19000, creates a temporary API user, runs live list, subscriber, template, authentication, and health checks, then removes the containers and database volume. Override the defaults with LISTMONK_PORT or LISTMONK_IMAGE.
Normal bundle exec rake runs only the WebMock suite and does not require Docker.
Releasing
Publishing uses RubyGems trusted publishing, so no long-lived RubyGems API key is stored in GitHub.
Before the first release, create a pending trusted publisher in your RubyGems.org profile with:
- Gem name:
listmonk - Repository owner:
polydice - Repository name:
listmonk-ruby - Workflow filename:
release.yml - Environment:
release
To publish a version:
- Update
lib/listmonk/version.rbandCHANGELOG.md. - Run
bundle exec rake,bundle exec rake integration, andbundle exec rbs validate. - Run
bundle exec rake buildand inspect the generated package underpkg/. - Commit the release and create a matching version tag, for example
git tag v0.1.0. - Push
mainand the tag. ThePublish gemGitHub workflow validates that the tag matchesListmonk::VERSIONand publishes the gem.
License
The gem is available under the terms of the MIT License.