Agent Bindings: Route Channel Traffic to the Right Agent
Learn how agent bindings route channel accounts and conversations to the correct OpenClaw agent. This page explains when to use bindings and how they work with existing channel rules.
Read this when
- Routing channel accounts to different agents
- Sending one conversation to a specialized agent
- Deciding whether the default agent is sufficient
When a message lands on a channel, OpenClaw must pick which agent will handle it. In the default case, this is straightforward: the agent designated as default: true receives everything. An agent binding changes that choice for a portion of your traffic. Each binding specifies an agentId and matches channel attributes like the account, peer, guild, team, or Discord roles, and the agent that matches owns the session that results.
Bindings only determine the agent. They don't create channel accounts and they don't grant permissions. The binding is only checked after the channel has already accepted the message through its usual pairing, allowlist, and account rules.
When to use a binding
If all conversations can share a single workspace, one model policy, and one session boundary, bindings aren't necessary. The default agent handles it. Use bindings when you need a consistent division, such as:
- a dedicated channel account for each agent
- a support inbox directed to a support workspace
- a specific direct message or group assigned to a specialist
- a guild, team, or Discord role handled differently from the rest of an account
Set up the channel account first, then attach the binding. A binding that points to an account the channel never accepts will have no effect.
Route an account to an agent
This example keeps main as the fallback and sends the Discord account named support to its own agent and workspace:
{
agents: {
entries: {
main: {
default: true,
workspace: "~/.openclaw/workspace",
},
support: {
workspace: "~/.openclaw/workspace-support",
},
},
},
bindings: [
{
agentId: "support",
comment: "Route the support bot account to the support agent",
match: {
channel: "discord",
accountId: "support",
},
},
],
}
Messages arriving on the support account now go to agentId: "support". All other Discord accounts and channels continue using main unless another binding matches.
Routing configuration is loaded at startup, so restart the Gateway, then check the roster and channel accounts:
openclaw agents list --bindings
openclaw channels status --probe
Match a specific conversation
Add match.peer when only one direct message, group, or channel should reach the specialized agent:
{
bindings: [
{
agentId: "support",
match: {
channel: "discord",
accountId: "default",
peer: {
kind: "channel",
id: "123456789012345678",
},
},
},
],
}
peer.kind accepts direct, group, or channel. Use the channel's canonical peer ID rather than a display name.
Match fields and precedence
Every binding requires agentId and match.channel. The optional route-match fields:
accountId: one configured account. Leaving it out matches only the channel's default account;"*"acts as an explicit channel-wide fallback.peer: a specific or wildcard direct, group, or channel peerguildIdandteamId: channel-specific group-space constraintsroles: Discord role IDs, evaluated alongside the guild constraintsession.dmScope: an optional session-scoping override for matched direct messages
Precedence follows specificity: concrete conversation and group-space matches take priority over account and channel fallbacks. Within the same tier, the first binding in config order wins. Put narrow rules before broad ones when they share a tier.
Top-level bindings also accepts type: "acp" entries for persistent ACP conversations. Those require a concrete match.peer.id and follow the ACP conversation identity contract instead of ordinary route precedence. See ACP agents if that's what you need.
Common mistakes
Omitting accountId to mean every account
An omitted accountId matches only the channel's default account. For a channel-wide fallback, state it explicitly with accountId: "*".
Binding to an unknown agent
The agentId must exist under agents.entries, and exactly one entry should be marked default: true. A binding that references a missing agent misroutes silently.
Treating bindings as access control
Bindings select an agent for messages that were already admitted. Pairing, dmPolicy, group policy, and allowlists are separate controls. Configure them independently.