Requests run as a normal Gateway agent run (same codepath as
openclaw agent), so routing, permissions, and config match your Gateway.
Enabling the endpoint
enabled: false (or omit it) to disable.
Security boundary (important)
Treat this endpoint as full operator access to the gateway instance:- A valid Gateway token/password for this endpoint is equivalent to an owner/operator credential, not a narrow per-user scope.
- Requests run through the same control-plane agent path as trusted operator actions, so if the target agent’s policy allows sensitive tools, this endpoint can use them.
- Keep it on loopback/tailnet/private ingress only. Do not expose it to the public internet.
See Operator scopes, Security, and Remote access.
Authentication
Uses the Gateway auth configuration (see Trusted proxy auth for that mode’s details):
Notes:
- Same-host callers that bypass the proxy on a
trusted-proxygateway can fall back togateway.auth.password/OPENCLAW_GATEWAY_PASSWORDdirectly. AnyForwarded,X-Forwarded-*, orX-Real-IPheader evidence keeps the request on the trusted-proxy path instead. - If
gateway.auth.rateLimitis configured and too many auth attempts fail, the endpoint returns429with aRetry-Afterheader.
When to use this endpoint
- Prefer this over adding a new built-in channel when your integration is just another operator/client surface for the same gateway.
- For native mobile clients that connect directly to a remote gateway, prefer WebChat or the Gateway Protocol with the paired-device bootstrap/device-token flow, so the device does not need a shared HTTP token/password.
- Build a channel plugin instead when integrating an external messaging network with its own users, rooms, webhook delivery, or outbound transport. See Building plugins.
Agent-first model contract
OpenClaw treats the OpenAImodel field as an agent target, not a raw provider model id.
Optional request headers:
/v1/models lists top-level agent targets (openclaw, openclaw/default, openclaw/<agentId>), not backend provider models and not sub-agents; sub-agents stay internal execution topology. If you omit x-openclaw-model, the selected agent runs with its normal configured model.
/v1/embeddings uses the same agent-target model ids. Send x-openclaw-model (from a shared-secret caller, or an identity-bearing caller with operator.admin) to pick a specific embedding model; otherwise the request uses the selected agent’s normal embedding setup.
Session behavior
By default the endpoint is stateless per request (a new session key is generated each call). If the request includes an OpenAIuser string, the Gateway derives a stable session key from it so repeated calls can share an agent session. For custom apps, reuse the same user value per conversation thread; avoid account-level identifiers unless you want multiple conversations/devices to share one OpenClaw session. Use x-openclaw-session-key only when you need explicit routing control across multiple clients/threads, with application-owned keys that avoid the reserved namespaces above.
Request limits (config)
Defaults can be tuned undergateway.http.endpoints.chatCompletions:
HEIC/HEIF
image_url sources are accepted and normalized to JPEG before provider delivery through the shared OpenClaw image processor (Rastermill), which falls back to a system converter (sips, ImageMagick, GraphicsMagick, or ffmpeg) for formats needing external codec support.
Security note: allowlisting a hostname does not bypass private/internal IP blocking. For internet-exposed gateways, apply network egress controls in addition to app-level guards. See Security.
Chat tool contract
/v1/chat/completions supports a function-tool subset compatible with common OpenAI Chat clients.
Supported request fields
All sampling and token-cap fields ride the same agent stream-param channel and are forwarded best-effort:
- Token cap: the wire field name is chosen by the provider transport:
max_completion_tokensfor OpenAI-family endpoints,max_tokensfor providers that only accept the legacy name (Mistral, Chutes). stopmaps to the transport’s stop field:stopfor Chat Completions backends,stop_sequencesfor Anthropic. The OpenAI Responses API has no stop parameter, sostopis not applied on Responses-backed models.- The ChatGPT-based Codex Responses backend uses fixed server-side sampling and strips
temperature/top_p(along withmax_output_tokens,metadata,prompt_cache_retention,service_tier) before the request reaches that backend.
Unsupported variants
Returns400 invalid_request_error for:
- non-array
tools, non-function tool entries, or missingtool.function.name tool_choicevariants such asallowed_toolsandcustomtool_choice.function.namevalues that do not match a provided tool
tool_choice: "required" and function-pinned tool_choice, the endpoint narrows the exposed client function-tool set, instructs the runtime to call a client tool before responding, and errors if the agent response has no matching structured client-tool call. This applies to the caller-supplied HTTP tools list, not every internal OpenClaw agent tool.
Non-streaming tool response shape
When the agent calls tools, the response uses:choices[0].finish_reason = "tool_calls"choices[0].message.tool_calls[]entries withid,type: "function",function.name,function.arguments(JSON string)- Assistant commentary before the tool call, in
choices[0].message.content(possibly empty)
Streaming tool response shape
Whenstream: true, tool calls arrive as incremental SSE chunks: an initial assistant role delta, optional assistant commentary deltas, one or more delta.tool_calls chunks carrying tool identity and argument fragments, then a final chunk with finish_reason: "tool_calls" and data: [DONE].
If stream_options.include_usage=true, a trailing usage chunk is emitted before [DONE].
Tool follow-up loop
After receivingtool_calls, execute the requested function(s) and send a follow-up request that includes the prior assistant tool-call message plus one or more role: "tool" messages with matching tool_call_id. This continues the same agent reasoning loop to produce the final answer.
Streaming (SSE)
Setstream: true to receive Server-Sent Events:
Content-Type: text/event-stream- Each event line is
data: <json> - Stream ends with
data: [DONE]
Open WebUI quick setup
- Base URL:
http://127.0.0.1:18789/v1 - Docker on macOS base URL:
http://host.docker.internal:18789/v1 - API key: your Gateway bearer token
- Model:
openclaw/default
GET /v1/models lists openclaw/default, and Open WebUI uses it as the chat model id. For a specific backend provider/model, set the agent’s normal default model, or send x-openclaw-model (shared-secret caller, or identity-bearing caller with operator.admin).
Quick smoke test:
openclaw/default, most Open WebUI setups can connect with the same base URL and token.
Examples
Stable session for one app conversation:user value on later calls for that conversation to continue the same agent session.
Non-streaming:
/v1/embeddings supports input as a string or array of strings.