Skip to main content
A channel is “where does the human find out about the task and respond?” awaithumans ships with three: You activate channels per-task via notify=:
The dashboard always sees the task regardless of notify= — the queue is the operator’s source of truth.

Notify-string format

notify= is a list of strings, each prefixed by the channel: Multiple notifications fire in parallel — slow Slack API calls don’t block email.

Dashboard

Always on. Operators log in at /login, see their task queue, click in to fill the form. The dashboard reads the same task data the SDK created — there’s nothing channel-specific about it. By default a non-operator user sees only tasks routed to them. Operators see everything.

Why not webhooks-as-channels?

We deliberately don’t expose “raw webhook” as a channel — notify=["webhook:https://..."] isn’t a thing. The reason: the channel layer owns the human-facing UI generation. A webhook destination has no UI to render; you’d be implementing one ad-hoc on the receiving end. If you want webhook delivery for a system (not a human), use the callback_url= parameter, which fires on every terminal status transition. That’s how the Temporal and LangGraph adapters get their signals.

Adding a custom channel

Channels live in server/channels/. A channel module exports:
  • A notify_task(task_id, task_title, notify, form_definition, ...) function — called from BackgroundTasks after task creation
  • A webhook route under /api/channels/<your-channel>/... that handles inbound messages
See server/channels/slack/ and server/channels/email/ for the canonical examples. New channels are a Phase-2 community contribution surface — see the contribution guide.