Self-hosted HTTP gateway that gives AI agents a human-in-the-loop line to Telegram, Slack, Microsoft Teams, Discord, Google Chat, WhatsApp, and Messenger — interactive prompts, per-channel credentials, and signed callbacks.
Platform credentials are registered per channel via API (not global env vars).
Documentation: run npm run dev:docs (http://localhost:3003) or see docs-site/.
- Human-in-the-loop — interactive prompts with buttons and optional free text; signed callbacks deliver answers to your agent or workflow
- Talk to your agent in chat — MESSAGE channels forward inbound chat to your webhook; reply with
POST /send - Many workflows, one approval channel — multiple automations can post prompts to the same PROMPT
channel_id; each prompt’s answer goes to its owncallback_url - Seven platforms — Telegram, Slack, Teams, Discord, Google Chat, WhatsApp, Messenger
- Per-channel credentials — register bots and tokens per channel via API (not global env vars)
- Works with your stack — plain HTTP Agent API; n8n, Zapier, Make, custom agents — no Greenlight plugin required
- Self-hosted — Postgres + Docker; credentials and traffic stay on your infra
PROMPT channels are for outbound approvals (many workflows → one chat). MESSAGE channels are for ongoing conversation (one inbound callback_url per channel). Details: Features & benefits.
Hybrid (recommended): Postgres in Docker, apps with hot reload via npm.
npm run setup # creates .env with generated secrets if missing,
# then install + Postgres + migrate
npm run dev # core :8100, ui :3001, docs :3003
curl http://localhost:8100/healthzOr create the env file alone: npm run env:ensure (dev) /
npm run env:ensure -- --profile self-host.
| Service | URL |
|---|---|
| API + webhooks | http://localhost:8100 |
| Admin UI | http://localhost:3001 |
| Docs | http://localhost:3003 |
| Postgres | localhost:5431 (POSTGRES_PORT if remapped) |
Full Docker (no Node hot reload — smoke / demos):
npm run docker:full # docker compose --profile full up -d --buildRegister a channel, then send a prompt:
export API_KEY="$(grep '^API_KEY=' .env | cut -d= -f2)"
curl -X POST http://localhost:8100/register-channel \
-H "X-API-Key: $API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"channel_id": "my-telegram-prompts",
"platform": "telegram",
"target_chat_id": "-1001234567890",
"credentials": { "bot_token": "123456789:YOUR_TOKEN" },
"channel_type": "PROMPT"
}'
curl -X POST http://localhost:8100/v1/prompts \
-H "X-API-Key: $API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"channel_id": "my-telegram-prompts",
"text": "Ready to deploy v2.4.1?",
"options": ["Deploy", "Cancel"],
"callback_url": "https://your-agent.example.com/on_answer"
}'Full guides: Quickstart, Platforms, API Reference, Configuration.
| Platform | Delivery | Credentials |
|---|---|---|
telegram |
Polling (default) or webhook | bot_token |
slack |
Webhook | bot_token, signing_secret |
teams |
Webhook | app_id, app_password (+ optional app_tenant_id) |
discord |
Webhook + Gateway | bot_token, public_key, application_id |
gchat |
Webhook | service_account_json, google_chat_project_number |
whatsapp |
Webhook (GET+POST) | access_token, app_secret, phone_number_id, verify_token |
messenger |
Webhook (GET+POST) | page_access_token, app_secret, verify_token |
Prompt limits: WhatsApp and Messenger support at most 3 button options per prompt.
- Run
npm run dev(ornpm run docker:full) - Open
http://localhost:3001/setupto create the super admin - Sign in at
/login— manage channels, prompts, messages, and retention settings
Telegram walkthrough: Quickstart and
Telegram. Canonical product docs live in docs-site/.
core/ — Hono API gateway (port 8100)
ui/ — Next.js admin app (port 3001)
docs-site/ — Product documentation (Nextra, port 3003)
| Script | Purpose |
|---|---|
npm run setup |
First-time: .env, install, Postgres, migrate |
npm run dev |
Hybrid: infra + core + ui + docs |
npm run infra:up / infra:down |
Start/stop Postgres only |
npm run infra:reset |
Wipe Postgres volume |
npm run db:migrate |
Apply UI admin_users migration |
npm run docker:full |
Full containerized stack |
npm run docker:full:down |
Stop full stack |
# Self-host: docker-compose.self-host.yml
# Swarm: add -c docker-compose.self-host.stack.yml — see docs-site Self-Hosting
npm run env:ensure -- --profile self-host
docker compose -f docker-compose.self-host.yml --env-file .env.self-host up -dDokploy domains (same host, API under path prefix):
| Service | Port | Traefik path | Public URL example |
|---|---|---|---|
greenlight-ui |
3000 | / |
https://greenlight.hashterm.com/ |
greenlight |
8100 | /wh |
https://greenlight.hashterm.com/wh/* |
API path in Dokploy must be /wh (leading slash required). Traefik strips /wh when forwarding to core.
AUTH_URL=https://greenlight.hashterm.com
PUBLIC_WEBHOOK_URL=https://greenlight.hashterm.com/whInternal health only (container probes — not public Traefik routes):
| Service | Internal URL |
|---|---|
greenlight-ui |
http://127.0.0.1:3000/api/health |
greenlight |
http://127.0.0.1:8100/healthz |
/wh/healthz is not valid — API health is not under the webhook path prefix.
Full deploy guide: Dokploy, Coolify, Configuration.
See CONTRIBUTING.md and CODE_OF_CONDUCT.md.
Greenlight is source-available under the Business Source License 1.1 (BUSL-1.1) — not an OSI-approved open source license.
Community (core/, ui/, docs-site/) |
Enterprise | |
|---|---|---|
| Location | This repository | Commercial license from the Licensor (not in this repo) |
| License | BUSL-1.1 | Proprietary |
| Self-host | Yes | Paid license only (when available) |
| Sell as competing hosted subscription | No | No |
Details: docs/LICENSING.md and docs-site Legal.