Notifications and approvals
Outbound webhooks, a local Telegram bot (Professional soft notify), and SaaS Assist HITL (Team+) for /approve and /deny — never diffs or file contents.
Goal#
Get a status ping — never a diff, never file contents — the moment a worker seals or a worktree is promoted, and optionally approve or reject a session from Telegram instead of the CLI. Three independent channels, all opt-in:
- Generic outbound webhooks (any URL — Slack, Discord, n8n, Zapier, your own
receiver) from the local
orchworkshop. - A local Telegram long-polling bot (
orch notify telegram) for the same workshop events and/approve//rejecton sealed sessions. - Orchemax SaaS Assist HITL (Team and above): link a chat under
/app/assist, then/approve//deny//rejecton the Orchemax bot write the same notices the console Assist action writes. Professional keeps soft Telegram notify (telegram_notify) without org Assist.
Steps#
-
Add one or more webhooks to
orch.yaml:notify: webhooks: - url: "https://example.com/orch-hook" events: [sealed, failed, promoted, needs_approval] # omit = all secret_env: ORCH_WEBHOOK_SECRETEvery delivery is a
POSTwith a JSON body —event,workspace,project,session,agent,status,exit,verdict,guard_lines,usage.in/out,log_path,ts— and, whensecret_envnames a set environment variable, anX-Orch-Signatureheader: the hex HMAC-SHA256 of the raw body under that secret. Verify it before trusting the payload. -
Send a synthetic event to check the wiring:
orch notify test [--event sealed|failed|promoted|needs_approval] -
Add a Telegram bot (talk to
@BotFatherfor a token; message the bot once sogetUpdatescan see your chat id):notify: telegram: bot_token_env: ORCH_TELEGRAM_TOKEN chat_allowlist: [123456789] events: [sealed, failed, promoted, needs_approval]orch daemonstarts the long-poll worker automatically whennotify.telegram.bot_token_envis set. To run it on its own:orch notify telegram runFrom an allowlisted chat:
/status,/approve <session>,/reject <session>(mark failed + prune the worktree). A message from any other chat id getsorch: unauthorized chatand nothing else runs. -
Require approval before a clean seal is eligible to merge:
promote: require_approval: trueA session that seals
okthen firesneeds_approvalinstead of being merge-ready;/approve <session>(ororch worktree promote <session>) still does the actual merge.
SaaS Assist HITL (Team+)#
When the workshop is linked to an Orchemax account on Team or Enterprise:
- Open orchemax.com/app/assist and link the
Telegram
chat_idfor the bot your tenant uses. - From that chat send
/approve <subject>,/deny <subject>, or/reject <subject>(/rejectis the deny alias). The server records anorch_noticesHITL event and bumps the entitlement lease — the same path as the Assist approve/deny buttons in the console. - Free, Starter, and Professional get a plan gate (
telegram_hitl_requires_team); upgrade under Billing. Professional still includes soft Telegram notify (telegram_notify) for alerts //answeron the local bot.
This channel is metadata-only (approve/deny subject + tenant). It does not
replace local orch notify telegram for workshop seal/promote events on your
machine — use both when you want local workshop pings and SaaS Assist.
n8n / Zapier#
Both platforms speak plain HTTP — point their "catch webhook" trigger node at
your receiver URL and put that URL in notify.webhooks[].url. No Orchemax-specific
node needed: n8n's Webhook node and Zapier's "Catch Hook" trigger both parse
the JSON body directly; add a Code/Filter step on event if you only want to
react to needs_approval, and verify X-Orch-Signature in that step if the
webhook is reachable from outside your network.
What never leaves the machine#
Payloads carry status and summary only — guard verdict lines, file counts, token usage — never a diff or file content. Code stays local; only the event above crosses the wire, and only to the URLs/chats you configured.
System tray#
For a persistent tray icon that opens orch ui and surfaces the same desktop
toasts, see System tray presence.