--- summary: "Expose an OpenAI-compatible /v1/chat/completions HTTP endpoint from the Gateway" read_when: - Integrating tools that expect OpenAI Chat Completions title: "OpenAI Chat Completions" --- # OpenAI Chat Completions (HTTP) OpenClaw’s Gateway can serve a small OpenAI-compatible Chat Completions endpoint. This endpoint is **disabled by default**. Enable it in config first. - `POST /v1/chat/completions` - Same port as the Gateway (WS + HTTP multiplex): `http://:/v1/chat/completions` Under the hood, requests are executed as a normal Gateway agent run (same codepath as `openclaw agent`), so routing/permissions/config match your Gateway. ## Authentication Uses the Gateway auth configuration. Send a bearer token: - `Authorization: Bearer ` Notes: - When `gateway.auth.mode="token"`, use `gateway.auth.token` (or `OPENCLAW_GATEWAY_TOKEN`). - When `gateway.auth.mode="password"`, use `gateway.auth.password` (or `OPENCLAW_GATEWAY_PASSWORD`). - If `gateway.auth.rateLimit` is configured and too many auth failures occur, the endpoint returns `429` with `Retry-After`. ## Security boundary (important) Treat this endpoint as a **full operator-access** surface for the gateway instance. - HTTP bearer auth here is not a narrow per-user scope model. - A valid Gateway token/password for this endpoint should be treated like an owner/operator credential. - Requests run through the same control-plane agent path as trusted operator actions. - There is no separate non-owner/per-user tool boundary on this endpoint; once a caller passes Gateway auth here, OpenClaw treats that caller as a trusted operator for this gateway. - If the target agent policy allows sensitive tools, this endpoint can use them. - Keep this endpoint on loopback/tailnet/private ingress only; do not expose it directly to the public internet. See [Security](/gateway/security) and [Remote access](/gateway/remote). ## Choosing an agent No custom headers required: encode the agent id in the OpenAI `model` field: - `model: "openclaw:"` (example: `"openclaw:main"`, `"openclaw:beta"`) - `model: "agent:"` (alias) Or target a specific OpenClaw agent by header: - `x-openclaw-agent-id: ` (default: `main`) Advanced: - `x-openclaw-session-key: ` to fully control session routing. ## Enabling the endpoint Set `gateway.http.endpoints.chatCompletions.enabled` to `true`: ```json5 { gateway: { http: { endpoints: { chatCompletions: { enabled: true }, }, }, }, } ``` ## Disabling the endpoint Set `gateway.http.endpoints.chatCompletions.enabled` to `false`: ```json5 { gateway: { http: { endpoints: { chatCompletions: { enabled: false }, }, }, }, } ``` ## Session behavior By default the endpoint is **stateless per request** (a new session key is generated each call). If the request includes an OpenAI `user` string, the Gateway derives a stable session key from it, so repeated calls can share an agent session. ## Streaming (SSE) Set `stream: true` to receive Server-Sent Events (SSE): - `Content-Type: text/event-stream` - Each event line is `data: ` - Stream ends with `data: [DONE]` ## Examples Non-streaming: ```bash curl -sS http://127.0.0.1:18789/v1/chat/completions \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -H 'x-openclaw-agent-id: main' \ -d '{ "model": "openclaw", "messages": [{"role":"user","content":"hi"}] }' ``` Streaming: ```bash curl -N http://127.0.0.1:18789/v1/chat/completions \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -H 'x-openclaw-agent-id: main' \ -d '{ "model": "openclaw", "stream": true, "messages": [{"role":"user","content":"hi"}] }' ```