Sending Jabber/XMPP Messages via HTTP

Published: (March 10, 2026 at 09:29 AM EDT)
3 min read

Source: Hacker News

The goal of this tutorial is to set up a simple REST API that allows you to send XMPP messages to an existing XMPP account. This can be easily integrated into monitoring solutions or other scripts that send out status information.

While there are command‑line tools like go‑sendxmpp that send messages by connecting to an XMPP server directly, this guide is specifically about providing an HTTP interface.

curl "https://ntfy.stdmsg.tech:5281/msg/user@example.com" \
  -u coffee@ntfy.stdmsg.tech:secret \
  -H "Content-Type: text/plain" \
  -d "Your flat white is done"

Hint: If you don’t have an XMPP account to receive these messages, you can create one on a public server from within Conversations (F‑Droid, Google Play) or another XMPP client of your choosing.

Requirements

This guide assumes a relatively clean install of Debian 13. Other Linux distributions or an existing installation will probably work as well. You also need a domain (any subdomain you control). In the examples the domain ntfy.stdmsg.tech is used—replace it with your own.

Setup

Installation

We install Prosody IM, the community modules, and Certbot:

apt install prosody prosody-modules lua-unbound liblua5.4-dev certbot

The Prosody community module we need isn’t included in the prosody-modules Debian package, so we use the Prosody plugin installer:

prosodyctl install --server=https://modules.prosody.im/rocks/ mod_post_msg

Configuration

Create a minimal Prosody configuration that disables everything except what is required for the REST API. Replace /etc/prosody/prosody.cfg.lua with the following:

pidfile = "/var/run/prosody/prosody.pid"

modules_enabled = {
	"tls";
	"dialback";
	"http";
	"admin_shell";
	"post_msg";
}
modules_disabled = {
	"c2s";
	"offline";
}

log = {
	info = "prosody.log";
	error = "prosody.err";
}

certificates = "certs"

VirtualHost "ntfy.stdmsg.tech"

Getting certificates

Use Certbot to obtain Let’s Encrypt certificates. If you already have a Certbot setup, adjust the --standalone flag accordingly.

certbot certonly --standalone -d ntfy.stdmsg.tech
prosodyctl --root cert import /etc/letsencrypt/live/

Make sure the A record of your domain points to your server.

Check and first start

Validate the configuration and restart Prosody:

prosodyctl check
systemctl restart prosody

You can verify that Prosody is listening on port 5269 (XMPP S2S) and port 5281 (the HTTPS port used for the REST API) with:

ss -ltnp

Send your first message

Creating a user

prosodyctl adduser coffee@ntfy.stdmsg.tech

Enter a password of your choice when prompted (the example uses “secret”).

Using the REST API

curl "https://ntfy.stdmsg.tech:5281/msg/user@example.com" \
  -u coffee@ntfy.stdmsg.tech:secret \
  -H "Content-Type: text/plain" \
  -d "Your flat white is done"

user@example.com (the path component) is the recipient. The -u credentials are the sender you just created.

You can create multiple users if you need separation of concerns.

A notification on Android from the app Conversations that shows the message ‘Your flat white is done’ coming from the user ‘coffee’

Additional reading

The module used is mod_post_msg. Its documentation describes how it can accept JSON payloads, which may be more appropriate for some use cases.

You can also configure the built‑in HTTP server or place it behind a reverse proxy.

For a more permanent setup, consider a Certbot hook that re‑imports fresh certificates into Prosody.

0 views
Back to Blog

Related posts

Read more »