One connector, 100+ notification targets.
Apprise
(BSD-2) turns a single webhook into fan-out to 100+ services — Microsoft
Teams, Matrix, Pushover, Signal, ntfy, Gotify, Telegram, Slack and more. Point the
apprise integration at your own Apprise API server and every submission is
delivered to all of them. Full schema in the API reference.
What it is
- A native form integration (
type: "apprise") that POSTs each submission to your Apprise API instance. - Apprise resolves the destinations from short URLs like
tgram://,msteams://,matrix://,pover://,ntfy://— one integration covers all of them. - Fires on every non-spam submission, alongside your other integrations and webhooks.
Prerequisite: run an Apprise API
Apprise is a Python engine, so you run the small companion Apprise API server (one container) and we POST to it:
$ docker run -p 8000:8000 caronc/apprise:latest
It must be reachable at a public https:// URL. The integration's
serverUrl goes through the same SSRF guard as our webhooks, so
http://, localhost, and private/internal IPs are rejected. Put your
Apprise API behind a reverse proxy or a Cloudflare Tunnel with TLS.
Add the integration
Stateless — pass the Apprise notification URLs inline:
$ curl -X POST https://login.ollastack.com/api/forms/<formId>/integrations \ -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \ -d '{ "type": "apprise", "config": { "serverUrl": "https://apprise.example.com", "urls": "tgram://bottoken/chatid, msteams://token/a/b/c" } }' {"success":true,"data":{"id":"...","type":"apprise"}}
List with GET /api/forms/{formId}/integrations; delete with DELETE /api/forms/{formId}/integrations/{id}.
Stateless vs stateful
- Stateless —
config.urlsis a comma/space-separated list of Apprise URLs, sent to{serverUrl}/notify. Simplest; the URLs live on your Ollastack form. - Stateful — set
config.configKeyinstead (a saved config on your Apprise API); we POST to{serverUrl}/notify/{configKey}, so the destination URLs never leave your Apprise server. Optionally addconfig.tagsto target a subset.
Exactly one of urls or configKey is required.
What gets sent
Each submission becomes a text notification your Apprise instance fans out:
{
"title": "New submission to Contact form",
"body": "name: Ada\nemail: ada@example.com\nmessage: Tell me more\n\nSubmission ID: sub_…",
"type": "info",
"format": "text",
"urls": "tgram://…, msteams://…"
} Notes
- Verified end-to-end against the real Apprise engine — the payload above drives Apprise's
/notifyand delivers with the correct title + body. - Delivery is best-effort per submission; a failing send is recorded on the integration's
lastStatus(visible in the integrations list) and never blocks the submission. - Your Apprise API credentials/tokens live on your server — Ollastack only holds the
serverUrl(and the inlineurlsif you choose stateless).