Interfaces

Connect agents to chat interfaces (Slack, Telegram, WhatsApp, Discord), browser applications, and agent protocols.

Product and support teams can expose the same component in an application, team chat, and customer channels. AgentOS interfaces connect components to Slack, Telegram, WhatsApp, A2A, and AG-UI. Each interface handles surface-specific routing and session IDs. Chat interfaces verify their own webhooks; protocol interfaces use AgentOS authorization when it is enabled.

Session history stays tied to each surface's session_id.

Available interfaces

Two categories. Chat surfaces meet humans where they already are. Protocol surfaces are how other systems talk to your agent.

Chat surfaces

InterfaceUse caseSetup
SlackTeam chat, DMs, channel mentions, thread sessionsSlack
TelegramPersonal assistants, mobile chatTelegram
WhatsAppCustomer support and mobile chatWhatsApp
DiscordCommunity servers, gaming, custom commands. Runs in its own process via agno.integrations.discord.Discord

Protocol surfaces

InterfaceUse caseSetup
A2AOther agents talk to yours over a standardized agent-to-agent protocolA2A
AG-UIBrowser clients consuming SSE streams of run outputAG-UI

Setup

Each interface registers its own routes on the FastAPI app. Slack lands events at /slack/events. Telegram at /telegram/webhook. The agent=... parameter tells the interface which agent to dispatch incoming messages to.

from agno.os import AgentOS
from agno.os.interfaces.slack import Slack
from agno.os.interfaces.telegram import Telegram

agent_os = AgentOS(
    agents=[agent],
    db=db,
    interfaces=[
        Slack(agent=agent, token="xoxb-...", signing_secret="..."),
        Telegram(agent=agent, token="bot-token"),
    ],
)

Before registering Telegram’s webhook, set TELEGRAM_WEBHOOK_SECRET_TOKEN on the server and send the same value as secret_token to Telegram’s setWebhook API. The interface reads this secret from the environment; it is not a Telegram constructor parameter. Install each interface’s dependencies as described in its setup guide.

If your AgentOS has multiple agents, wire each interface to a different one (Slack to your customer support agent, Telegram to a personal assistant) or wire several interfaces to the same agent.

Credentials at a glance

Per-interface setup pages have the full OAuth flows, scope lists, and webhook configuration. The summary:

InterfaceNeeds
SlackBot token (xoxb-...), signing secret, OAuth scopes for the events you handle
TelegramBot token from @BotFather and TELEGRAM_WEBHOOK_SECRET_TOKEN, matching the registered webhook secret
WhatsAppBusiness API token, verify token, phone number ID, and WHATSAPP_APP_SECRET for inbound signature verification
DiscordBot token (DISCORD_BOT_TOKEN)
A2ANone by default; behind AgentOS JWT auth when authorization=True
AG-UINone by default; behind AgentOS JWT auth when authorization=True

Sessions per surface

Every interface maps surface state to AgentOS sessions, so a conversation in Slack carries forward like any other session. Accepted replies in the same thread reuse its session. Slack defaults to reply_to_mentions_only=True, so channel replies still need an @mention; direct messages do not. Set reply_to_mentions_only=False and subscribe to the appropriate message events to handle unmentioned channel replies. Persist the component’s sessions and enable history context when the agent should use previous messages.

InterfaceSession IDUser ID
Slack<entity_id>:<channel_id>:<thread_ts>; existing legacy <entity_id>:<thread_ts> sessions are reusedSlack user ID, or resolved email when enabled
Telegramtg:<entity_id>:<chat_id> with an optional topic suffix; /new adds a unique suffixTelegram user ID
WhatsAppwa:<entity_id>:<user_id>; a new conversation can add a unique suffixPhone number or encrypted user ID
DiscordThread IDDiscord user ID
A2AA2A context IDJWT subject, or request metadata when anonymous
AG-UIClient thread IDJWT subject, or client-supplied when anonymous

Slack can resolve a member's email as user_id when resolve_user_identity=True. See the Slack interface guide for identity and permission setup.

One agent, many surfaces

A single agent can answer on every surface at once:

agent_os = AgentOS(
    agents=[support_agent],
    db=db,
    interfaces=[
        Slack(agent=support_agent, token=..., signing_secret=...),
        Telegram(agent=support_agent, token=...),
        Whatsapp(agent=support_agent, access_token=..., verify_token=...),
        AGUI(agent=support_agent),
    ],
)

When user memory is enabled and each interface resolves the same person to the same user_id, stored memories are available across surfaces. Session history stays scoped to each surface's session_id, and interfaces pass surface context along with the run, such as the Slack channel name.

Conditional registration

Register optional interfaces only when their credentials are available. In this example, the uppercase names are values your application reads from its environment:

interfaces = []

if SLACK_TOKEN and SLACK_SIGNING_SECRET:
    interfaces.append(Slack(agent=agent, token=SLACK_TOKEN, signing_secret=SLACK_SIGNING_SECRET))

if TELEGRAM_TOKEN and TELEGRAM_WEBHOOK_SECRET_TOKEN:
    interfaces.append(Telegram(agent=agent, token=TELEGRAM_TOKEN))

agent_os = AgentOS(agents=[agent], db=db, interfaces=interfaces)

The Scout, Dash, and Coda apps use this pattern. The Slack interface loads when both environment variables are set, which keeps development runs working before optional channel credentials are configured.

Custom interfaces and one-off webhooks

Subclass BaseInterface, return your routes from get_router, and dispatch incoming messages to the agent. See BaseInterface for the full surface.

Add a route directly to the FastAPI app for an application-specific event. This illustrates dispatch only; a provider webhook also needs its request-signature verification before calling the agent:

app = agent_os.get_app()

@app.post("/webhooks/stripe")
async def handle_stripe(event: dict):
    response = await agent.arun(f"Process Stripe event: {event}", user_id="system")
    return {"ok": True, "response": response.content}
NeedPattern
Reusable surface shared across AgentOS applicationsSubclass BaseInterface
One application-specific event sourceAdd a FastAPI route