Skip to content

Set up calling

Configure calling under channels.agent-wechat.calls. Voice and video each default to disabled. The current daemon and plugin handle direct voice calls.

Connect the daemon

  1. Finish Quick setup and check wx calls status. The daemon must advertise directAudio: true; see Calling for build options.

  2. Give the channel token the calls scope alongside its existing messaging scopes:

    Terminal window
    wx tokens create openclaw-calling --accounts ACCOUNT_ID \
    --scopes read --scopes media --scopes send --scopes login \
    --scopes read-state --scopes calls

    Use the returned token in the channel’s existing native.token SecretRef. A token without calls cannot use the call endpoints.

Configure speech and access

Merge this example into your existing channel and agent configuration. Replace the example contact and owner IDs. Set OPENAI_API_KEY in the Gateway process’s environment.

{
"secrets": {
"providers": {
"voiceenv": {
"source": "env",
"allowlist": ["OPENAI_API_KEY"]
}
}
},
"agents": {
"entries": {
"main": {
"tools": {
"alsoAllow": ["wechat_call"]
}
}
}
},
"channels": {
"agent-wechat": {
"calls": {
"voice": {
"enabled": true,
"agentId": "main",
"inboundPolicy": "allowlist",
"inboundAllowFrom": ["allowed-contact-id"],
"outboundPolicy": "allowlist",
"outboundAllowTo": ["allowed-contact-id"],
"outboundToolAllowFrom": ["owner-id"],
"maxDurationSeconds": 3600,
"realtime": {
"provider": "openai",
"voice": "marin",
"instructions": "Keep spoken replies concise.",
"agentContext": { "enabled": true },
"providers": {
"openai": {
"apiKey": {
"source": "env",
"provider": "voiceenv",
"id": "OPENAI_API_KEY"
}
}
}
},
"toolPolicy": "none"
},
"video": {
"enabled": false
}
}
}
}
}

apiKey also accepts an OpenClaw file/exec/store SecretRef or a key string. When omitted, OpenClaw uses the selected agent’s OpenAI authentication or Gateway environment. A text-agent subscription alone does not necessarily grant realtime API access. The daemon token and OpenAI key are separate credentials.

wechat_call is optional: the example grants it to main for status, outbound calls and hangup. Grant it to any other agent that should place calls for you, such as the agent that answers a group; the call itself always runs as calls.voice.agentId. Automatic inbound answering does not require this tool.

Restart the Gateway after saving the configuration. An enabled, prepared voice service reports available when the daemon is free; provider or capability failure reports unavailable and leaves calls unanswered.

Models and behavior

All paths below are relative to calls.voice.

SettingBehavior / default
realtime.providerRequired; openai is the supported adapter.
realtime.model, realtime.voiceOptional speech model/voice overrides; otherwise provider defaults.
realtime.instructionsOptional conversation guidance, up to 4,000 characters.
realtime.agentContext.enabledDefaults to false. Set to true to include excerpts from the selected agent’s IDENTITY.md and SOUL.md.
agentIdRequired. Selects the voice persona, provider authentication and agent for permitted consultations.
toolPolicynone, safe-read-only, or owner. Opting in to session persistence defaults to safe-read-only.
allowConsultSessionPersistenceSet to true to allow consultation in OpenClaw sessions for calls.
sessionScopeper-contact (one session per contact, so the agent remembers earlier calls) or per-call. See Remember earlier calls.
consultation.summary, consultation.recentMessages, realtime.recentContextSummarize each answered call and share recent chat with the agent (on by default), and give the next call a recap (off by default). See Remember earlier calls.
realtime.consultPolicyauto lets the provider choose when to consult. substantive directs it to consult for facts and context. always also starts a consult from the caller’s current turn if the provider skips it.
realtime.consultThinkingLevel, realtime.consultFastModeOptional OpenClaw reasoning level and fast-mode override for consultations.
consultation.inboundSessionKeyOptional existing session of the selected agent that seeds a new call session for inbound calls.
consultation.timeoutMs30,000 by default; 1,000–120,000 ms.
maxDurationSeconds3,600 (one hour) by default; 30–3,600 seconds. The plugin hangs up when it is reached. The native daemon currently ends calls after 20 minutes.

The speech model handles conversation; the selected OpenClaw agent handles delegated questions and permitted tools. Incoming/outgoing policies default to disabled; allowlists accept exact IDs, without *. Tool callers must also be authorized owners in outboundToolAllowFrom. Messaging permissions do not authorize calls.

Set realtime.model to one of these OpenAI models. Omit it to use the provider’s default, gpt-realtime-2.1.

ModelConversationAgent consultationSign-in
gpt-realtime-2.1, gpt-realtime-2.1-mini, gpt-realtime-2Takes turns; stops when the caller interrupts.Through a tool.OpenAI API key.
gpt-live-1-codex (voice cove)Listens while it talks and handles interruptions itself. Introduces itself as ChatGPT: this route does not use the agent’s name or persona.Delegates to the agent. consultPolicy: "always" is not supported.The agent’s ChatGPT sign-in in OpenClaw (2026.10.10 or later), then the API key.
gpt-live-1 (voice marin)Listens while it talks and handles interruptions itself. Uses the agent’s name and persona.Same as gpt-live-1-codex.OpenAI API key.

The speech model receives the selected agent’s configured identity. When workspace context is enabled, the realtime provider also receives bounded excerpts of the two persona files. Keep those files suitable for this use.

Calls placed with wechat_call use the requesting session as context when consultation is enabled and that session belongs to calls.voice.agentId. Set consultation.inboundSessionKey to do the same for inbound calls. OpenClaw copies that session’s context into the call’s session when the call session is first created. Choose a session whose history is suitable for the callers.

With toolPolicy: "owner", a call participant whose WeChat ID exactly matches an agent-wechat:<WeChat ID> entry in commands.ownerAllowFrom can consult with the agent’s normal tool policy. An owner can use a bound session with the same WeChat peer and channel account. Other allowed participants get read-only consultation in a separate session. Add inbound callers to inboundAllowFrom separately.

Consultations run like the agent’s normal chat turns. They use its configured model, including CLI runtimes such as claude-cli, and its fallback models.