Publish once. Reach every chat, webhook, and phone.

hooka is a self-hosted, Telegram-first notification bus for people and agents. Publish to a topic, and its routes deliver to Telegram chats and forum threads, webhooks, and SMS. Every message is stored, along with the outcome of each delivery.

Open source under Apache-2.0. The repository goes public soon.

POST /publish/deploys

{"title":"Release","text":"api@a1b2c3 is live on prod"}

deploys stored as message 4711
  1. Telegram forum thread sent
    Ops / deploys
    Release api@a1b2c3 is live on prod 14:02
  2. Webhook ci.example.com/hooks/deploy sent
  3. SMS +1 ••• ••• 0142 sent
One publish to the deploys topic, stored once and delivered to a Telegram forum thread, a webhook, and an SMS number. Response: "delivered": 3, "failed": 0

Publish in one line

A publish is one HTTP request with a bearer token. The response tells you where the message went, and the message stays in history with each route's outcome.

  • Add an Idempotency-Key header and a retried request returns the original message instead of sending twice.
  • Mint a scoped hk_ token that can only publish to deploys*, and keep the master key to yourself.
  • Failed deliveries retry with backoff. What still fails lands in dead letters you can replay.
Request
curl https://api.tryhooka.xyz/publish/deploys \
  -H "Authorization: Bearer hk_your_token" \
  -H "Content-Type: application/json" \
  -d '{"title":"Release","text":"api@a1b2c3 is live on prod"}'
Response
{
  "ok": true,
  "message": "published",
  "message_id": 4711,
  "topic": "deploys",
  "delivered": 3,
  "failed": 0,
  "idempotency_hit": false,
  "destinations": [
    {
      "provider": "telegram",
      "chat_id": "-1001234567890",
      "message_thread_id": "42",
      "status": "sent"
    },
    { "provider": "webhook", "status": "sent" },
    { "provider": "sms", "status": "sent" }
  ],
  "store_only": false
}

Placeholder token. Use your own instance URL when you self-host.

The whole delivery path in one binary

The server is a single Go binary backed by Postgres. The MCP server, agent bridge, and dashboard are optional companions that talk to it over HTTP.

Deliver

Topics and routes
Publish once to a topic. Its routes deliver to Telegram chats or forum threads, webhooks with custom headers, and SMS through Twilio or Telnyx.
Safe retries
Idempotency keys make retries safe. Failed deliveries back off and try again, and terminal failures become dead letters you can replay.
Telegram, fully
HTML and Markdown, rich messages, inline keyboards, documents, photos, albums, and voice notes, posted into the forum thread you choose.
Push to your own iOS app
Optional APNs support lets an iOS app you build and sign register devices and receive pushes.

Read it back

History and search
Every message is kept with its per-route outcome. Filter a topic's history, or search across all topics with full-text search.
Live streams
Subscribe to any topic over Server-Sent Events, filtered by priority or tag, and resume from where you left off.
Chats that listen
Send /capture deploys in a Telegram chat or thread, and what people type there is stored on that topic too.

Build on it

Commands become events
Register an app and its bot commands. Each command, or tap on one of its buttons, arrives as an app.command event on a topic, and the app answers by publishing.
Capability URLs
Give a third party a publish-only /in/{token} URL: one topic, rate-limited, revocable. GitHub webhooks sent to it arrive rendered, and Alertmanager has its own endpoint.
Reminders and forms
One-shot and cron reminders go through the same delivery path, retries included. Native forms give you a public link and stored responses.
MCP server and agent bridge
hooka-mcp gives MCP-capable agents publish, search, reminders, and forms. The agent bridge connects a topic to OpenCode or Pi.

Run it

Access control
A master key for you, scoped hk_ tokens per topic pattern for everything else, and an audit topic that reports token, route, and login changes.
Operations built in
Prometheus metrics, health and readiness checks, and retention cleanup you configure per kind of record.
Optional dashboard
A Next.js control panel for topics, routes, tokens, reminders, forms, and the audit log.

What to wire it to

Four common jobs, all handled by the server and its own clients.

Let an agent ask before it acts

Publish the question with inline buttons. A tap comes back as an app.command event, with who pressed it, on your app's topic. The agent reads it over SSE or a webhook and carries on.

Post CI and deploy results

Publish from any job with a scoped token. The idempotency key makes a re-run return the original message instead of posting twice. For GitHub itself, register a capability URL as the webhook, and pushes, PRs, reviews, releases, and CI failures arrive rendered.

Route alerts by severity

Point Alertmanager at /alertmanager/{topic}. Severity sets the priority, watchdog alerts arrive silently, and a topic for critical alerts can post to its own forum thread.

Collect answers with a form

An agent can create a form through MCP or the CLI and share one public link. Respondents need no account, and you read responses in the dashboard, as CSV, or over the API. The waitlist on this page is a hooka form.

Use the hosted beta, or run your own

Join the waitlist for the hosted beta, or run the open-source server yourself.

Waitlist open

Hosted beta

We run hooka for you, so there is no server or database to look after. The hosted tier isn't open yet. Join the waitlist and we'll tell you when it is.

Join the waitlist

The waitlist is itself a hooka form. It asks for your email and, if you like, what you'd use hooka for.

Apache-2.0

Self-host

One Go binary and Postgres on your own infrastructure. Telegram updates arrive by long-polling, so you don't need a public URL to start.

One click on Railway Soon

A Railway template that starts hooka, Postgres, and the dashboard from your bot token. It builds from the source, so it opens when the repository does.

Docker Compose Soon

A compose file for hooka and Postgres, with the dashboard behind a profile. The clone-and-run steps appear here when the source goes public.