Gateway
OpenResponses API
OpenClaw의 Gateway는 OpenResponses 호환 POST /v1/responses 엔드포인트를 제공할 수 있습니다.
이 엔드포인트는 기본적으로 비활성화되어 있습니다. 먼저 구성에서 활성화하세요.
POST /v1/responses- Gateway와 동일한 포트(WS + HTTP 멀티플렉스):
http://<gateway-host>:<port>/v1/responses
내부적으로 요청은 일반 Gateway 에이전트 실행(openclaw agent와 동일한 코드 경로)으로 실행되므로 라우팅/권한/구성은 사용자의 Gateway와 일치합니다.
인증, 보안 및 라우팅
운영 동작은 OpenAI Chat Completions와 일치합니다.
- 일치하는 Gateway HTTP 인증 경로 사용:
- 공유 비밀 인증(
gateway.auth.mode="token"또는"password"):Authorization: Bearer <token-or-password> - 신뢰할 수 있는 프록시 인증(
gateway.auth.mode="trusted-proxy"): 구성된 신뢰할 수 있는 프록시 소스의 ID 인식 프록시 헤더. 동일 호스트 loopback 프록시는 명시적gateway.auth.trustedProxy.allowLoopback = true가 필요합니다. - 신뢰할 수 있는 프록시 로컬 직접 fallback:
Forwarded,X-Forwarded-*또는X-Real-IP헤더가 없는 동일 호스트 호출자는gateway.auth.password/OPENCLAW_GATEWAY_PASSWORD를 사용할 수 있습니다. - 프라이빗 인그레스 공개 인증(
gateway.auth.mode="none"): 인증 헤더 없음
- 공유 비밀 인증(
- 엔드포인트를 Gateway 인스턴스에 대한 전체 운영자 액세스로 취급
- 공유 비밀 인증 모드(
token및password)에서는 더 좁은 bearer 선언x-openclaw-scopes값을 무시하고 일반 전체 운영자 기본값을 복원 - 신뢰할 수 있는 ID 포함 HTTP 모드(예: 신뢰할 수 있는 프록시 인증 또는
gateway.auth.mode="none")에서는x-openclaw-scopes가 있으면 이를 준수하고, 없으면 일반 운영자 기본 scope 집합으로 fallback model: "openclaw",model: "openclaw/default",model: "openclaw/<agentId>"또는x-openclaw-agent-id로 에이전트 선택- 선택된 에이전트의 백엔드 모델을 override하려면
x-openclaw-model사용 - 명시적 세션 라우팅에는
x-openclaw-session-key사용 - 기본이 아닌 합성 인그레스 채널 컨텍스트를 원할 때는
x-openclaw-message-channel사용
인증 매트릭스:
gateway.auth.mode="token"또는"password"+Authorization: Bearer ...- 공유 Gateway 운영자 비밀의 소유를 증명
- 더 좁은
x-openclaw-scopes무시 - 전체 기본 운영자 scope 집합 복원:
operator.admin,operator.approvals,operator.pairing,operator.read,operator.talk.secrets,operator.write - 이 엔드포인트의 채팅 턴을 소유자 발신자 턴으로 취급
- 신뢰할 수 있는 ID 포함 HTTP 모드(예: 신뢰할 수 있는 프록시 인증 또는 프라이빗 인그레스의
gateway.auth.mode="none")- 헤더가 있으면
x-openclaw-scopes준수 - 헤더가 없으면 일반 운영자 기본 scope 집합으로 fallback
- 호출자가 명시적으로 scope를 좁히고
operator.admin을 생략할 때만 소유자 의미 체계를 잃음
- 헤더가 있으면
gateway.http.endpoints.responses.enabled로 이 엔드포인트를 활성화하거나 비활성화합니다.
동일한 호환성 표면에는 다음도 포함됩니다.
GET /v1/modelsGET /v1/models/{id}POST /v1/embeddingsPOST /v1/chat/completions
에이전트 대상 모델, openclaw/default, 임베딩 pass-through, 백엔드 모델 override가 어떻게 함께 작동하는지에 대한 표준 설명은 OpenAI Chat Completions 및 모델 목록 및 에이전트 라우팅을 참조하세요.
세션 동작
기본적으로 엔드포인트는 요청별 무상태입니다(각 호출마다 새 세션 키가 생성됨).
요청에 OpenResponses user 문자열이 포함되어 있으면 Gateway는 이 문자열에서 안정적인 세션 키를 파생하므로 반복 호출이 에이전트 세션을 공유할 수 있습니다.
요청 형태(지원됨)
요청은 항목 기반 입력이 있는 OpenResponses API를 따릅니다. 현재 지원 사항:
input: 문자열 또는 항목 객체 배열.instructions: 시스템 프롬프트에 병합됩니다.tools: 클라이언트 도구 정의(function 도구).tool_choice: 클라이언트 도구를 필터링하거나 요구하기 위한"auto","none","required"또는{ "type": "function", "name": "..." }.stream: SSE 스트리밍을 활성화합니다.max_output_tokens: 최선 노력 출력 제한(프로바이더 종속).temperature: 프로바이더에 전달되는 최선 노력 샘플링 온도입니다. 고정된 서버 측 샘플링을 사용하는 ChatGPT 기반 Codex Responses 백엔드에서는 무시됩니다.top_p: 프로바이더에 전달되는 최선 노력 nucleus 샘플링입니다.temperature와 동일한 Codex Responses 주의 사항이 적용됩니다.user: 안정적인 세션 라우팅.
허용되지만 현재 무시됨:
max_tool_callsreasoningmetadatastoretruncation
지원됨:
previous_response_id: 요청이 동일한 에이전트/사용자/요청된 세션 scope 내에 머무르면 OpenClaw는 이전 응답 세션을 재사용합니다.
항목(input)
message
역할: system, developer, user, assistant.
system및developer는 시스템 프롬프트에 추가됩니다.- 가장 최근의
user또는function_call_output항목이 "현재 메시지"가 됩니다. - 이전 사용자/assistant 메시지는 컨텍스트를 위한 기록으로 포함됩니다.
function_call_output(턴 기반 도구)
도구 결과를 모델로 다시 보냅니다.
{ "type": "function_call_output", "call_id": "call_123", "output": "{\"temperature\": \"72F\"}"}reasoning 및 item_reference
스키마 호환성을 위해 허용되지만 프롬프트를 구성할 때는 무시됩니다.
도구(클라이언트 측 function 도구)
tools: [{ type: "function", name, description?, parameters? }]로 도구를 제공합니다.
에이전트가 도구 호출을 결정하면 응답은 function_call 출력 항목을 반환합니다.
그런 다음 턴을 계속하려면 function_call_output이 포함된 후속 요청을 보냅니다.
tool_choice: "required" 및 function 고정 tool_choice의 경우, 엔드포인트는 노출된 클라이언트 function-tool 집합을 좁히고, 런타임에 응답 전에 클라이언트 도구를 호출하도록 지시하며, 일치하는 구조화된 클라이언트 도구 호출이 포함되지 않으면 턴을 거부합니다. 이 계약은 모든 내부 OpenClaw 에이전트 도구가 아니라 호출자가 제공한 HTTP tools 목록에 적용됩니다. 비스트리밍 요청은 api_error와 함께 502를 반환하고, 스트리밍 요청은 response.failed 이벤트를 내보냅니다. 이는 /v1/chat/completions 계약과 일치합니다.
이미지(input_image)
base64 또는 URL 소스를 지원합니다.
{ "type": "input_image", "source": { "type": "url", "url": "https://example.com/image.png" }}허용되는 MIME 유형(현재): image/jpeg, image/png, image/gif, image/webp, image/heic, image/heif.
최대 크기(현재): 10MB.
파일(input_file)
base64 또는 URL 소스를 지원합니다.
{ "type": "input_file", "source": { "type": "base64", "media_type": "text/plain", "data": "SGVsbG8gV29ybGQh", "filename": "hello.txt" }}허용되는 MIME 유형(현재): text/plain, text/markdown, text/html, text/csv,
application/json, application/pdf.
최대 크기(현재): 5MB.
현재 동작:
- 파일 콘텐츠는 사용자 메시지가 아니라 시스템 프롬프트에 디코딩되어 추가되므로 일시적으로 유지됩니다(세션 기록에 지속되지 않음).
- 디코딩된 파일 텍스트는 추가되기 전에 신뢰할 수 없는 외부 콘텐츠로 래핑되므로 파일 바이트는 신뢰할 수 있는 지시가 아니라 데이터로 취급됩니다.
- 삽입된 블록은
<<<EXTERNAL_UNTRUSTED_CONTENT id="...">>>/<<<END_EXTERNAL_UNTRUSTED_CONTENT id="...">>>같은 명시적 경계 마커를 사용하며Source: External메타데이터 줄을 포함합니다. - 이 파일 입력 경로는 프롬프트 예산을 보존하기 위해 긴
SECURITY NOTICE:배너를 의도적으로 생략합니다. 경계 마커와 메타데이터는 그대로 유지됩니다. - PDF는 먼저 텍스트로 파싱됩니다. 텍스트가 거의 없으면 첫 페이지들이 이미지로 래스터화되어 모델에 전달되고, 삽입된 파일 블록은
[PDF content rendered to images]플레이스홀더를 사용합니다.
PDF 파싱은 번들된 document-extract Plugin에서 제공하며, 이 Plugin은 텍스트 추출 및 페이지 렌더링에 clawpdf와 패키지된 PDFium WebAssembly 런타임을 사용합니다.
URL 가져오기 기본값:
files.allowUrl:trueimages.allowUrl:truemaxUrlParts:8(요청당 URL 기반input_file+input_image부분 총합)- 요청은 보호됩니다(DNS 확인, 프라이빗 IP 차단, 리디렉션 제한, timeout).
- 선택적 호스트 이름 allowlist는 입력 유형별로 지원됩니다(
files.urlAllowlist,images.urlAllowlist).- 정확한 호스트:
"cdn.example.com" - 와일드카드 하위 도메인:
"*.assets.example.com"(apex와 일치하지 않음) - 비어 있거나 생략된 allowlist는 호스트 이름 allowlist 제한이 없음을 의미합니다.
- 정확한 호스트:
- URL 기반 가져오기를 완전히 비활성화하려면
files.allowUrl: false및/또는images.allowUrl: false를 설정하세요.
파일 + 이미지 제한(구성)
기본값은 gateway.http.endpoints.responses 아래에서 조정할 수 있습니다.
{ gateway: { http: { endpoints: { responses: { enabled: true, maxBodyBytes: 20000000, maxUrlParts: 8, files: { allowUrl: true, urlAllowlist: ["cdn.example.com", "*.assets.example.com"], allowedMimes: [ "text/plain", "text/markdown", "text/html", "text/csv", "application/json", "application/pdf", ], maxBytes: 5242880, maxChars: 200000, maxRedirects: 3, timeoutMs: 10000, pdf: { maxPages: 4, maxPixels: 4000000, minTextChars: 200, }, }, images: { allowUrl: true, urlAllowlist: ["images.example.com"], allowedMimes: [ "image/jpeg", "image/png", "image/gif", "image/webp", "image/heic", "image/heif", ], maxBytes: 10485760, maxRedirects: 3, timeoutMs: 10000, }, }, }, }, },}생략 시 기본값:
maxBodyBytes: 20MBmaxUrlParts: 8files.maxBytes: 5MBfiles.maxChars: 200kfiles.maxRedirects: 3files.timeoutMs: 10sfiles.pdf.maxPages: 4files.pdf.maxPixels: 4,000,000files.pdf.minTextChars: 200images.maxBytes: 10MBimages.maxRedirects: 3images.timeoutMs: 10s- HEIC/HEIF
input_image소스는 시스템 변환기가 사용 가능할 때 허용되며 프로바이더 전달 전에 JPEG로 정규화됩니다. 지원되는 변환기는 macOSsips, ImageMagick, GraphicsMagick 또는 ffmpeg입니다.
보안 참고:
- URL allowlist는 가져오기 전과 리디렉션 홉에서 강제 적용됩니다.
- 호스트 이름을 allowlist에 추가해도 프라이빗/내부 IP 차단을 우회하지 않습니다.
- 인터넷에 노출된 gateway의 경우 앱 수준 보호 외에도 네트워크 egress 제어를 적용하세요. 보안을 참조하세요.
스트리밍(SSE)
Server-Sent Events(SSE)를 받으려면 stream: true를 설정하세요.
Content-Type: text/event-stream- 각 이벤트 줄은
event: <type>및data: <json>입니다. - 스트림은
data: [DONE]으로 종료됩니다.
현재 내보내는 이벤트 유형:
response.createdresponse.in_progressresponse.output_item.addedresponse.content_part.addedresponse.output_text.deltaresponse.output_text.doneresponse.content_part.doneresponse.output_item.doneresponse.completedresponse.failed(오류 시)
사용량
usage는 기본 프로바이더가 토큰 수를 보고할 때 채워집니다.
OpenClaw는 해당 카운터가 downstream 상태/세션 표면에 도달하기 전에
input_tokens / output_tokens 및 prompt_tokens / completion_tokens를 포함한 일반적인 OpenAI 스타일 alias를 정규화합니다.
오류
오류는 다음과 같은 JSON 객체를 사용합니다.
{ "error": { "message": "...", "type": "invalid_request_error" } }일반적인 경우:
401인증 누락/유효하지 않음400유효하지 않은 요청 본문405잘못된 메서드
예시
비스트리밍:
curl -sS http://127.0.0.1:18789/v1/responses \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -H 'x-openclaw-agent-id: main' \ -d '{ "model": "openclaw", "input": "hi" }'스트리밍:
curl -N http://127.0.0.1:18789/v1/responses \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -H 'x-openclaw-agent-id: main' \ -d '{ "model": "openclaw", "stream": true, "input": "hi" }'